From 0aab67c47d3a0cc6855cb97c5f95e04e0a9de561 Mon Sep 17 00:00:00 2001 From: Anubisss Date: Tue, 7 Apr 2009 00:23:37 +0200 Subject: *Fix CRLF in Unit.h and Level3.cpp files. --HG-- branch : trunk --- src/game/Level3.cpp | 15184 +++++++++++++++++++++++++------------------------- src/game/Unit.h | 3292 +++++------ 2 files changed, 9238 insertions(+), 9238 deletions(-) (limited to 'src') diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 13561540c02..10b0cd198a0 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -1,7592 +1,7592 @@ -/* -* Copyright (C) 2005-2009 MaNGOS -* -* Copyright (C) 2008-2009 Trinity -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "Database/DatabaseEnv.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "World.h" -#include "ObjectMgr.h" -#include "AuctionHouseMgr.h" -#include "AccountMgr.h" -#include "PlayerDump.h" -#include "SpellMgr.h" -#include "Player.h" -#include "Opcodes.h" -#include "GameObject.h" -#include "Chat.h" -#include "Log.h" -#include "Guild.h" -#include "ObjectAccessor.h" -#include "MapManager.h" -#include "ScriptCalls.h" -#include "Language.h" -#include "GridNotifiersImpl.h" -#include "CellImpl.h" -#include "Weather.h" -#include "PointMovementGenerator.h" -#include "TargetedMovementGenerator.h" -#include "SkillDiscovery.h" -#include "SkillExtraItems.h" -#include "SystemConfig.h" -#include "Config/ConfigEnv.h" -#include "Util.h" -#include "ItemEnchantmentMgr.h" -#include "BattleGroundMgr.h" -#include "InstanceSaveMgr.h" -#include "InstanceData.h" -#include "AuctionHouseBot.h" - -bool ChatHandler::HandleAHBotOptionsCommand(const char* args) -{ - uint32 ahMapID = 0; - char * opt = strtok((char*)args, " "); - char * ahMapIdStr = strtok(NULL, " "); - if (ahMapIdStr) - { - ahMapID = (uint32) strtoul(ahMapIdStr, NULL, 0); - } - if (!opt) - { - PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter"); - PSendSysMessage("Try ahbotoptions help to see a list of options."); - return false; - } - int l = strlen(opt); - - if (strncmp(opt,"help",l) == 0) - { - PSendSysMessage("AHBot commands:"); - PSendSysMessage("ahexpire"); - PSendSysMessage("minitems"); - PSendSysMessage("maxitems"); - PSendSysMessage("mintime"); - PSendSysMessage("maxtime"); - PSendSysMessage("percentages"); - PSendSysMessage("minprice"); - PSendSysMessage("maxprice"); - PSendSysMessage("minbidprice"); - PSendSysMessage("maxbidprice"); - PSendSysMessage("maxstack"); - PSendSysMessage("buyerprice"); - PSendSysMessage("bidinterval"); - PSendSysMessage("bidsperinterval"); - return true; - } - else if (strncmp(opt,"ahexpire",l) == 0) - { - if (!ahMapIdStr) - { - PSendSysMessage("Syntax is: ahbotoptions ahexpire $ahMapID (2, 6 or 7)"); - return false; - } - AuctionHouseBotCommands(0, ahMapID, NULL, NULL); - } - else if (strncmp(opt,"minitems",l) == 0) - { - char * param1 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1)) - { - PSendSysMessage("Syntax is: ahbotoptions minitems $ahMapID (2, 6 or 7) $minItems"); - return false; - } - AuctionHouseBotCommands(1, ahMapID, NULL, param1); - } - else if (strncmp(opt,"maxitems",l) == 0) - { - char * param1 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1)) - { - PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems"); - return false; - } - AuctionHouseBotCommands(2, ahMapID, NULL, param1); - } - else if (strncmp(opt,"mintime",l) == 0) - { - char * param1 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1)) - { - PSendSysMessage("Syntax is: ahbotoptions mintime $ahMapID (2, 6 or 7) $mintime"); - return false; - } - AuctionHouseBotCommands(3, ahMapID, NULL, param1); - } - else if (strncmp(opt,"maxtime",l) == 0) - { - char * param1 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1)) - { - PSendSysMessage("Syntax is: ahbotoptions maxtime $ahMapID (2, 6 or 7) $maxtime"); - return false; - } - AuctionHouseBotCommands(4, ahMapID, NULL, param1); - } - else if (strncmp(opt,"percentages",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - char * param3 = strtok(NULL, " "); - char * param4 = strtok(NULL, " "); - char * param5 = strtok(NULL, " "); - char * param6 = strtok(NULL, " "); - char * param7 = strtok(NULL, " "); - char * param8 = strtok(NULL, " "); - char * param9 = strtok(NULL, " "); - char * param10 = strtok(NULL, " "); - char * param11 = strtok(NULL, " "); - char * param12 = strtok(NULL, " "); - char * param13 = strtok(NULL, " "); - char * param14 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param14)) - { - PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14"); - PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); - PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); - PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); - PSendSysMessage("The total must add up to 100%"); - return false; - } - uint32 greytg = (uint32) strtoul(param1, NULL, 0); - uint32 whitetg = (uint32) strtoul(param2, NULL, 0); - uint32 greentg = (uint32) strtoul(param3, NULL, 0); - uint32 bluetg = (uint32) strtoul(param3, NULL, 0); - uint32 purpletg = (uint32) strtoul(param5, NULL, 0); - uint32 orangetg = (uint32) strtoul(param6, NULL, 0); - uint32 yellowtg = (uint32) strtoul(param7, NULL, 0); - uint32 greyi = (uint32) strtoul(param8, NULL, 0); - uint32 whitei = (uint32) strtoul(param9, NULL, 0); - uint32 greeni = (uint32) strtoul(param10, NULL, 0); - uint32 bluei = (uint32) strtoul(param11, NULL, 0); - uint32 purplei = (uint32) strtoul(param12, NULL, 0); - uint32 orangei = (uint32) strtoul(param13, NULL, 0); - uint32 yellowi = (uint32) strtoul(param14, NULL, 0); - uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi; - if ((totalPercent == 0) || (totalPercent != 100)) - { - PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14"); - PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); - PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); - PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); - PSendSysMessage("The total must add up to 100%"); - return false; - } - char param[100]; - param[0] = '\0'; - strcat(param, param1); - strcat(param, " "); - strcat(param, param2); - strcat(param, " "); - strcat(param, param3); - strcat(param, " "); - strcat(param, param4); - strcat(param, " "); - strcat(param, param5); - strcat(param, " "); - strcat(param, param6); - strcat(param, " "); - strcat(param, param7); - strcat(param, " "); - strcat(param, param8); - strcat(param, " "); - strcat(param, param9); - strcat(param, " "); - strcat(param, param10); - strcat(param, " "); - strcat(param, param11); - strcat(param, " "); - strcat(param, param12); - strcat(param, " "); - strcat(param, param13); - strcat(param, " "); - strcat(param, param14); - AuctionHouseBotCommands(5, ahMapID, NULL, param); - } - else if (strncmp(opt,"minprice",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1) || (!param2)) - { - PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - if (strncmp(param1,"grey",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_GREY, param2); - } - else if (strncmp(param1,"white",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_WHITE, param2); - } - else if (strncmp(param1,"green",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_GREEN, param2); - } - else if (strncmp(param1,"blue",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_BLUE, param2); - } - else if (strncmp(param1,"purple",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_PURPLE, param2); - } - else if (strncmp(param1,"orange",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_ORANGE, param2); - } - else if (strncmp(param1,"yellow",l) == 0) - { - AuctionHouseBotCommands(6, ahMapID, AHB_YELLOW, param2); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - } - else if (strncmp(opt,"maxprice",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1) || (!param2)) - { - PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - if (strncmp(param1,"grey",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_GREY, param2); - } - else if (strncmp(param1,"white",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_WHITE, param2); - } - else if (strncmp(param1,"green",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_GREEN, param2); - } - else if (strncmp(param1,"blue",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_BLUE, param2); - } - else if (strncmp(param1,"purple",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_PURPLE, param2); - } - else if (strncmp(param1,"orange",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_ORANGE, param2); - } - else if (strncmp(param1,"yellow",l) == 0) - { - AuctionHouseBotCommands(7, ahMapID, AHB_YELLOW, param2); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - } - else if (strncmp(opt,"minbidprice",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1) || (!param2)) - { - PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - uint32 minBidPrice = (uint32) strtoul(param2, NULL, 0); - if ((minBidPrice < 1) || (minBidPrice > 100)) - { - PSendSysMessage("The min bid price multiplier must be between 1 and 100"); - return false; - } - if (strncmp(param1,"grey",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_GREY, param2); - } - else if (strncmp(param1,"white",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_WHITE, param2); - } - else if (strncmp(param1,"green",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_GREEN, param2); - } - else if (strncmp(param1,"blue",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_BLUE, param2); - } - else if (strncmp(param1,"purple",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_PURPLE, param2); - } - else if (strncmp(param1,"orange",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_ORANGE, param2); - } - else if (strncmp(param1,"yellow",l) == 0) - { - AuctionHouseBotCommands(8, ahMapID, AHB_YELLOW, param2); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - } - else if (strncmp(opt,"maxbidprice",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1) || (!param2)) - { - PSendSysMessage("Syntax is: ahbotoptions maxbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - uint32 maxBidPrice = (uint32) strtoul(param2, NULL, 0); - if ((maxBidPrice < 1) || (maxBidPrice > 100)) - { - PSendSysMessage("The max bid price multiplier must be between 1 and 100"); - return false; - } - if (strncmp(param1,"grey",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_GREY, param2); - } - else if (strncmp(param1,"white",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_WHITE, param2); - } - else if (strncmp(param1,"green",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_GREEN, param2); - } - else if (strncmp(param1,"blue",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_BLUE, param2); - } - else if (strncmp(param1,"purple",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_PURPLE, param2); - } - else if (strncmp(param1,"orange",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_ORANGE, param2); - } - else if (strncmp(param1,"yellow",l) == 0) - { - AuctionHouseBotCommands(9, ahMapID, AHB_YELLOW, param2); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions max bidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); - return false; - } - } - else if (strncmp(opt,"maxstack",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1) || (!param2)) - { - PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); - return false; - } - uint32 maxStack = (uint32) strtoul(param2, NULL, 0); - if (maxStack < 0) - { - PSendSysMessage("maxstack can't be a negative number."); - return false; - } - if (strncmp(param1,"grey",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_GREY, param2); - } - else if (strncmp(param1,"white",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_WHITE, param2); - } - else if (strncmp(param1,"green",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_GREEN, param2); - } - else if (strncmp(param1,"blue",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_BLUE, param2); - } - else if (strncmp(param1,"purple",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_PURPLE, param2); - } - else if (strncmp(param1,"orange",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_ORANGE, param2); - } - else if (strncmp(param1,"yellow",l) == 0) - { - AuctionHouseBotCommands(10, ahMapID, AHB_YELLOW, param2); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); - return false; - } - } - else if (strncmp(opt,"buyerprice",l) == 0) - { - char * param1 = strtok(NULL, " "); - char * param2 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1) || (!param2)) - { - PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); - return false; - } - if (strncmp(param1,"grey",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_GREY, param2); - } - else if (strncmp(param1,"white",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_WHITE, param2); - } - else if (strncmp(param1,"green",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_GREEN, param2); - } - else if (strncmp(param1,"blue",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_BLUE, param2); - } - else if (strncmp(param1,"purple",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_PURPLE, param2); - } - else if (strncmp(param1,"orange",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_ORANGE, param2); - } - else if (strncmp(param1,"yellow",l) == 0) - { - AuctionHouseBotCommands(11, ahMapID, AHB_YELLOW, param2); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); - return false; - } - } - else if (strncmp(opt,"bidinterval",l) == 0) - { - char * param1 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1)) - { - PSendSysMessage("Syntax is: ahbotoptions bidinterval $ahMapID (2, 6 or 7) $interval(in minutes)"); - return false; - } - AuctionHouseBotCommands(12, ahMapID, NULL, param1); - } - else if (strncmp(opt,"bidsperinterval",l) == 0) - { - char * param1 = strtok(NULL, " "); - if ((!ahMapIdStr) || (!param1)) - { - PSendSysMessage("Syntax is: ahbotoptions bidsperinterval $ahMapID (2, 6 or 7) $bids"); - return false; - } - AuctionHouseBotCommands(13, ahMapID, NULL, param1); - } - else - { - PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter"); - PSendSysMessage("Try ahbotoptions help to see a list of options."); - return false; - } - return true; -} - -//reload commands -bool ChatHandler::HandleReloadAllCommand(const char*) -{ - HandleReloadSkillFishingBaseLevelCommand(""); - - HandleReloadAllAreaCommand(""); - HandleReloadAllLootCommand(""); - HandleReloadAllNpcCommand(""); - HandleReloadAllQuestCommand(""); - HandleReloadAllSpellCommand(""); - HandleReloadAllItemCommand(""); - HandleReloadAllLocalesCommand(""); - - HandleReloadCommandCommand(""); - HandleReloadReservedNameCommand(""); - HandleReloadTrinityStringCommand(""); - HandleReloadGameTeleCommand(""); - return true; -} - -bool ChatHandler::HandleReloadAllAreaCommand(const char*) -{ - //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand - HandleReloadAreaTriggerTeleportCommand(""); - HandleReloadAreaTriggerTavernCommand(""); - HandleReloadGameGraveyardZoneCommand(""); - return true; -} - -bool ChatHandler::HandleReloadAllLootCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables..." ); - LoadLootTables(); - SendGlobalGMSysMessage("DB tables `*_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/) -{ - HandleReloadNpcGossipCommand("a"); - HandleReloadNpcOptionCommand("a"); - HandleReloadNpcTrainerCommand("a"); - HandleReloadNpcVendorCommand("a"); - HandleReloadPointsOfInterestCommand("a"); - return true; -} - -bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/) -{ - HandleReloadQuestAreaTriggersCommand("a"); - HandleReloadQuestTemplateCommand("a"); - - sLog.outString( "Re-Loading Quests Relations..." ); - objmgr.LoadQuestRelations(); - SendGlobalGMSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadAllScriptsCommand(const char*) -{ - if(sWorld.IsScriptScheduled()) - { - PSendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - sLog.outString( "Re-Loading Scripts..." ); - HandleReloadGameObjectScriptsCommand("a"); - HandleReloadEventScriptsCommand("a"); - HandleReloadQuestEndScriptsCommand("a"); - HandleReloadQuestStartScriptsCommand("a"); - HandleReloadSpellScriptsCommand("a"); - SendGlobalGMSysMessage("DB tables `*_scripts` reloaded."); - HandleReloadDbScriptStringCommand("a"); - HandleReloadWpScriptsCommand("a"); - return true; -} - -bool ChatHandler::HandleReloadAllSpellCommand(const char*) -{ - HandleReloadSkillDiscoveryTemplateCommand("a"); - HandleReloadSkillExtraItemTemplateCommand("a"); - HandleReloadSpellAffectCommand("a"); - HandleReloadSpellRequiredCommand("a"); - HandleReloadSpellAreaCommand("a"); - HandleReloadSpellElixirCommand("a"); - HandleReloadSpellLearnSpellCommand("a"); - HandleReloadSpellLinkedSpellCommand("a"); - HandleReloadSpellProcEventCommand("a"); - HandleReloadSpellBonusesCommand("a"); - HandleReloadSpellScriptTargetCommand("a"); - HandleReloadSpellTargetPositionCommand("a"); - HandleReloadSpellThreatsCommand("a"); - HandleReloadSpellPetAurasCommand("a"); - HandleReloadSpellDisabledCommand("a"); - return true; -} - -bool ChatHandler::HandleReloadAllItemCommand(const char*) -{ - HandleReloadPageTextsCommand("a"); - HandleReloadItemEnchantementsCommand("a"); - return true; -} - -bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/) -{ - HandleReloadLocalesCreatureCommand("a"); - HandleReloadLocalesGameobjectCommand("a"); - HandleReloadLocalesItemCommand("a"); - HandleReloadLocalesNpcTextCommand("a"); - HandleReloadLocalesPageTextCommand("a"); - HandleReloadLocalesPointsOfInterestCommand("a"); - HandleReloadLocalesQuestCommand("a"); - return true; -} - -bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/) -{ - sLog.outString( "Re-Loading config settings..." ); - sWorld.LoadConfigSettings(true); - SendGlobalGMSysMessage("World config settings reloaded."); - return true; -} - -bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*) -{ - sLog.outString( "Re-Loading Tavern Area Triggers..." ); - objmgr.LoadTavernAreaTriggers(); - SendGlobalGMSysMessage("DB table `areatrigger_tavern` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*) -{ - sLog.outString( "Re-Loading AreaTrigger teleport definitions..." ); - objmgr.LoadAreaTriggerTeleports(); - SendGlobalGMSysMessage("DB table `areatrigger_teleport` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadAccessRequirementCommand(const char*) -{ - sLog.outString( "Re-Loading Access Requirement definitions..." ); - objmgr.LoadAccessRequirements(); - SendGlobalGMSysMessage("DB table `access_requirement` reloaded."); - return true; - } - -bool ChatHandler::HandleReloadCommandCommand(const char*) -{ - load_command_table = true; - SendGlobalGMSysMessage("DB table `command` will be reloaded at next chat command use."); - return true; -} - -bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*) -{ - sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" ); - objmgr.LoadCreatureQuestRelations(); - SendGlobalGMSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*) -{ - sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" ); - objmgr.LoadCreatureInvolvedRelations(); - SendGlobalGMSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*) -{ - sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" ); - objmgr.LoadGameobjectQuestRelations(); - SendGlobalGMSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*) -{ - sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" ); - objmgr.LoadGameobjectInvolvedRelations(); - SendGlobalGMSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*) -{ - sLog.outString( "Re-Loading Quest Area Triggers..." ); - objmgr.LoadQuestAreaTriggers(); - SendGlobalGMSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadQuestTemplateCommand(const char*) -{ - sLog.outString( "Re-Loading Quest Templates..." ); - objmgr.LoadQuests(); - SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded."); - - /// dependent also from `gameobject` but this table not reloaded anyway - sLog.outString( "Re-Loading GameObjects for quests..." ); - objmgr.LoadGameObjectForQuests(); - SendGlobalGMSysMessage("Data GameObjects for quests reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" ); - LoadLootTemplates_Creature(); - LootTemplates_Creature.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `creature_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" ); - LoadLootTemplates_Disenchant(); - LootTemplates_Disenchant.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `disenchant_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" ); - LoadLootTemplates_Fishing(); - LootTemplates_Fishing.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `fishing_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" ); - LoadLootTemplates_Gameobject(); - LootTemplates_Gameobject.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `gameobject_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" ); - LoadLootTemplates_Item(); - LootTemplates_Item.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `item_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" ); - LoadLootTemplates_Milling(); - LootTemplates_Milling.CheckLootRefs(); - SendGlobalSysMessage("DB table `milling_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" ); - LoadLootTemplates_Pickpocketing(); - LootTemplates_Pickpocketing.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `pickpocketing_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" ); - LoadLootTemplates_Prospecting(); - LootTemplates_Prospecting.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `prospecting_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" ); - LoadLootTemplates_QuestMail(); - LootTemplates_QuestMail.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `quest_mail_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" ); - LoadLootTemplates_Reference(); - SendGlobalGMSysMessage("DB table `reference_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" ); - LoadLootTemplates_Skinning(); - LootTemplates_Skinning.CheckLootRefs(); - SendGlobalGMSysMessage("DB table `skinning_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" ); - LoadLootTemplates_Spell(); - LootTemplates_Spell.CheckLootRefs(); - SendGlobalSysMessage("DB table `spell_loot_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadTrinityStringCommand(const char*) -{ - sLog.outString( "Re-Loading trinity_string Table!" ); - objmgr.LoadTrinityStrings(); - SendGlobalGMSysMessage("DB table `trinity_string` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadNpcOptionCommand(const char*) -{ - sLog.outString( "Re-Loading `npc_option` Table!" ); - objmgr.LoadNpcOptions(); - SendGlobalGMSysMessage("DB table `npc_option` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadNpcGossipCommand(const char*) -{ - sLog.outString( "Re-Loading `npc_gossip` Table!" ); - objmgr.LoadNpcTextId(); - SendGlobalGMSysMessage("DB table `npc_gossip` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadNpcTrainerCommand(const char*) -{ - sLog.outString( "Re-Loading `npc_trainer` Table!" ); - objmgr.LoadTrainerSpell(); - SendGlobalGMSysMessage("DB table `npc_trainer` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadNpcVendorCommand(const char*) -{ - sLog.outString( "Re-Loading `npc_vendor` Table!" ); - objmgr.LoadVendors(); - SendGlobalGMSysMessage("DB table `npc_vendor` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*) -{ - sLog.outString( "Re-Loading `points_of_interest` Table!" ); - objmgr.LoadPointsOfInterest(); - SendGlobalSysMessage("DB table `points_of_interest` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadReservedNameCommand(const char*) -{ - sLog.outString( "Loading ReservedNames... (`reserved_name`)" ); - objmgr.LoadReservedPlayersNames(); - SendGlobalGMSysMessage("DB table `reserved_name` (player reserved names) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/) -{ - sLog.outString( "Re-Loading Skill Discovery Table..." ); - LoadSkillDiscoveryTable(); - SendGlobalGMSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/) -{ - sLog.outString( "Re-Loading Skill Extra Item Table..." ); - LoadSkillExtraItemTable(); - SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/) -{ - sLog.outString( "Re-Loading Skill Fishing base level requirements..." ); - objmgr.LoadFishingBaseSkillLevel(); - SendGlobalGMSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellAffectCommand(const char*) -{ - sLog.outString( "Re-Loading SpellAffect definitions..." ); - spellmgr.LoadSpellAffects(); - SendGlobalGMSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellAreaCommand(const char*) -{ - sLog.outString( "Re-Loading SpellArea Data..." ); - spellmgr.LoadSpellAreas(); - SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellRequiredCommand(const char*) -{ - sLog.outString( "Re-Loading Spell Required Data... " ); - spellmgr.LoadSpellRequired(); - SendGlobalGMSysMessage("DB table `spell_required` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellElixirCommand(const char*) -{ - sLog.outString( "Re-Loading Spell Elixir types..." ); - spellmgr.LoadSpellElixirs(); - SendGlobalGMSysMessage("DB table `spell_elixir` (spell elixir types) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*) -{ - sLog.outString( "Re-Loading Spell Learn Spells..." ); - spellmgr.LoadSpellLearnSpells(); - SendGlobalGMSysMessage("DB table `spell_learn_spell` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellLinkedSpellCommand(const char*) -{ - sLog.outString( "Re-Loading Spell Linked Spells..." ); - spellmgr.LoadSpellLinked(); - SendGlobalGMSysMessage("DB table `spell_linked_spell` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellProcEventCommand(const char*) -{ - sLog.outString( "Re-Loading Spell Proc Event conditions..." ); - spellmgr.LoadSpellProcEvents(); - SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellBonusesCommand(const char*) -{ - sLog.outString( "Re-Loading Spell Bonus Data..." ); - spellmgr.LoadSpellBonusess(); - SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*) -{ - sLog.outString( "Re-Loading SpellsScriptTarget..." ); - spellmgr.LoadSpellScriptTarget(); - SendGlobalGMSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*) -{ - sLog.outString( "Re-Loading Spell target coordinates..." ); - spellmgr.LoadSpellTargetPositions(); - SendGlobalGMSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellThreatsCommand(const char*) -{ - sLog.outString( "Re-Loading Aggro Spells Definitions..."); - spellmgr.LoadSpellThreats(); - SendGlobalGMSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded."); - return true; -} - -bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*) -{ - sLog.outString( "Re-Loading Spell pet auras..."); - spellmgr.LoadSpellPetAuras(); - SendGlobalGMSysMessage("DB table `spell_pet_auras` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadPageTextsCommand(const char*) -{ - sLog.outString( "Re-Loading Page Texts..." ); - objmgr.LoadPageTexts(); - SendGlobalGMSysMessage("DB table `page_texts` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*) -{ - sLog.outString( "Re-Loading Item Random Enchantments Table..." ); - LoadRandomEnchantmentsTable(); - SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg) -{ - if(sWorld.IsScriptScheduled()) - { - SendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - if(*arg!='a') - sLog.outString( "Re-Loading Scripts from `gameobject_scripts`..."); - - objmgr.LoadGameObjectScripts(); - - if(*arg!='a') - SendGlobalGMSysMessage("DB table `gameobject_scripts` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg) -{ - if(sWorld.IsScriptScheduled()) - { - SendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - if(*arg!='a') - sLog.outString( "Re-Loading Scripts from `event_scripts`..."); - - objmgr.LoadEventScripts(); - - if(*arg!='a') - SendGlobalGMSysMessage("DB table `event_scripts` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadWpScriptsCommand(const char* arg) -{ - if(sWorld.IsScriptScheduled()) - { - SendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - if(*arg!='a') - sLog.outString( "Re-Loading Scripts from `waypoint_scripts`..."); - - objmgr.LoadWaypointScripts(); - - if(*arg!='a') - SendGlobalGMSysMessage("DB table `waypoint_scripts` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg) -{ - if(sWorld.IsScriptScheduled()) - { - SendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - if(*arg!='a') - sLog.outString( "Re-Loading Scripts from `quest_end_scripts`..."); - - objmgr.LoadQuestEndScripts(); - - if(*arg!='a') - SendGlobalGMSysMessage("DB table `quest_end_scripts` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg) -{ - if(sWorld.IsScriptScheduled()) - { - SendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - if(*arg!='a') - sLog.outString( "Re-Loading Scripts from `quest_start_scripts`..."); - - objmgr.LoadQuestStartScripts(); - - if(*arg!='a') - SendGlobalGMSysMessage("DB table `quest_start_scripts` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg) -{ - if(sWorld.IsScriptScheduled()) - { - SendSysMessage("DB scripts used currently, please attempt reload later."); - SetSentErrorMessage(true); - return false; - } - - if(*arg!='a') - sLog.outString( "Re-Loading Scripts from `spell_scripts`..."); - - objmgr.LoadSpellScripts(); - - if(*arg!='a') - SendGlobalGMSysMessage("DB table `spell_scripts` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg) -{ - sLog.outString( "Re-Loading Script strings from `db_script_string`..."); - objmgr.LoadDbScriptStrings(); - SendGlobalGMSysMessage("DB table `db_script_string` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Graveyard-zone links..."); - - objmgr.LoadGraveyardZones(); - - SendGlobalGMSysMessage("DB table `game_graveyard_zone` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Game Tele coordinates..."); - - objmgr.LoadGameTele(); - - SendGlobalGMSysMessage("DB table `game_tele` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading spell disabled table..."); - - objmgr.LoadSpellDisabledEntrys(); - - SendGlobalGMSysMessage("DB table `spell_disabled` reloaded."); - - return true; -} - -bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales Creature ..."); - objmgr.LoadCreatureLocales(); - SendGlobalGMSysMessage("DB table `locales_creature` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales Gameobject ... "); - objmgr.LoadGameObjectLocales(); - SendGlobalGMSysMessage("DB table `locales_gameobject` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales Item ... "); - objmgr.LoadItemLocales(); - SendGlobalGMSysMessage("DB table `locales_item` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales NPC Text ... "); - objmgr.LoadNpcTextLocales(); - SendGlobalGMSysMessage("DB table `locales_npc_text` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales Page Text ... "); - objmgr.LoadPageTextLocales(); - SendGlobalGMSysMessage("DB table `locales_page_text` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales Points Of Interest ... "); - objmgr.LoadPointOfInterestLocales(); - SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded."); - return true; -} - -bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/) -{ - sLog.outString( "Re-Loading Locales Quest ... "); - objmgr.LoadQuestLocales(); - SendGlobalGMSysMessage("DB table `locales_quest` reloaded."); - return true; -} - -bool ChatHandler::HandleLoadScriptsCommand(const char* args) -{ - if(!LoadScriptingModule(args)) return true; - - sWorld.SendGMText(LANG_SCRIPTS_RELOADED); - return true; -} - -bool ChatHandler::HandleReloadAuctionsCommand(const char* args) -{ - ///- Reload dynamic data tables from the database - sLog.outString( "Re-Loading Auctions..." ); - auctionmgr.LoadAuctionItems(); - auctionmgr.LoadAuctions(); - SendGlobalGMSysMessage("Auctions reloaded."); - return true; -} - -bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args) -{ - if(!*args) - return false; - - std::string targetAccountName; - uint32 targetAccountId = 0; - uint32 targetSecurity = 0; - uint32 gm = 0; - char* arg1 = strtok((char*)args, " "); - char* arg2 = strtok(NULL, " "); - - if(getSelectedPlayer() && arg1 && !arg2) - { - targetAccountId = getSelectedPlayer()->GetSession()->GetAccountId(); - accmgr.GetName(targetAccountId, targetAccountName); - Player* targetPlayer = getSelectedPlayer(); - gm = atoi(arg1); - - // Check for invalid specified GM level. - if ( (gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR) ) - { - SendSysMessage(LANG_BAD_VALUE); - SetSentErrorMessage(true); - return false; - } - - // Check if targets GM level and specified GM level is not higher than current gm level - targetSecurity = targetPlayer->GetSession()->GetSecurity(); - if(targetSecurity >= m_session->GetSecurity() || gm >= m_session->GetSecurity() ) - { - SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); - SetSentErrorMessage(true); - return false; - } - - // Decide which string to show - if(m_session->GetPlayer()!=targetPlayer) - { - PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); - }else{ - PSendSysMessage(LANG_YOURS_SECURITY_CHANGED, m_session->GetPlayer()->GetName(), gm); - } - - LoginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId); - return true; - }else - { - // Check for second parameter - if(!arg2) - return false; - - // Check for account - targetAccountName = arg1; - if(!AccountMgr::normilizeString(targetAccountName)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str()); - SetSentErrorMessage(true); - return false; - } - - // Check for invalid specified GM level. - gm = atoi(arg2); - if ( (gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR) ) - { - SendSysMessage(LANG_BAD_VALUE); - SetSentErrorMessage(true); - return false; - } - - targetAccountId = accmgr.GetId(arg1); - /// m_session==NULL only for console - uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE; - - /// can set security level only for target with less security and to less security that we have - /// This is also reject self apply in fact - targetSecurity = accmgr.GetSecurity(targetAccountId); - if(targetSecurity >= plSecurity || gm >= plSecurity ) - { - SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); - SetSentErrorMessage(true); - return false; - } - - PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); - LoginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId); - return true; - } -} - -/// Set password for account -bool ChatHandler::HandleAccountSetPasswordCommand(const char* args) -{ - if(!*args) - return false; - - ///- Get the command line arguments - char *szAccount = strtok ((char*)args," "); - char *szPassword1 = strtok (NULL," "); - char *szPassword2 = strtok (NULL," "); - - if (!szAccount||!szPassword1 || !szPassword2) - return false; - - std::string account_name = szAccount; - if(!AccountMgr::normilizeString(account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - uint32 targetAccountId = accmgr.GetId(account_name); - if (!targetAccountId) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - /// can set password only for target with less security - /// This is also reject self apply in fact - if(HasLowerSecurityAccount (NULL,targetAccountId,true)) - return false; - - if (strcmp(szPassword1,szPassword2)) - { - SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH); - SetSentErrorMessage (true); - return false; - } - - AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1); - - switch(result) - { - case AOR_OK: - SendSysMessage(LANG_COMMAND_PASSWORD); - break; - case AOR_NAME_NOT_EXIST: - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - case AOR_PASS_TOO_LONG: - SendSysMessage(LANG_PASSWORD_TOO_LONG); - SetSentErrorMessage(true); - return false; - default: - SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/) -{ - Player* SelectedPlayer = getSelectedPlayer(); - if(!SelectedPlayer) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - // each skills that have max skill value dependent from level seted to current level max skill value - SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); - return true; -} - -bool ChatHandler::HandleSetSkillCommand(const char* args) -{ - // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r - char* skill_p = extractKeyFromLink((char*)args,"Hskill"); - if(!skill_p) - return false; - - char *level_p = strtok (NULL, " "); - - if( !level_p) - return false; - - char *max_p = strtok (NULL, " "); - - int32 skill = atoi(skill_p); - if (skill <= 0) - { - PSendSysMessage(LANG_INVALID_SKILL_ID, skill); - SetSentErrorMessage(true); - return false; - } - - int32 level = atol (level_p); - - Player * target = getSelectedPlayer(); - if(!target) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill); - if(!sl) - { - PSendSysMessage(LANG_INVALID_SKILL_ID, skill); - SetSentErrorMessage(true); - return false; - } - - std::string tNameLink = GetNameLink(target); - - if(!target->GetSkillValue(skill)) - { - PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]); - SetSentErrorMessage(true); - return false; - } - - int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill); - - if( level <= 0 || level > max || max <= 0 ) - return false; - - target->SetSkill(skill, level, max); - PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max); - - return true; -} - -bool ChatHandler::HandleUnLearnCommand(const char* args) -{ - if (!*args) - return false; - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r - uint32 spell_id = extractSpellIdFromLink((char*)args); - if(!spell_id) - return false; - - char const* allStr = strtok(NULL," "); - bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; - - Player* target = getSelectedPlayer(); - if(!target) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if(allRanks) - spell_id = spellmgr.GetFirstSpellInChain (spell_id); - - if (target->HasSpell(spell_id)) - target->removeSpell(spell_id,false,!allRanks); - else - SendSysMessage(LANG_FORGET_SPELL); - - return true; -} - -bool ChatHandler::HandleCooldownCommand(const char* args) -{ - Player* target = getSelectedPlayer(); - if(!target) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - std::string tNameLink = GetNameLink(target); - - if (!*args) - { - target->RemoveAllSpellCooldown(); - PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str()); - } - else - { - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell_id = extractSpellIdFromLink((char*)args); - if(!spell_id) - return false; - - if(!sSpellStore.LookupEntry(spell_id)) - { - PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); - SetSentErrorMessage(true); - return false; - } - - WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) ); - data << uint32(spell_id); - data << uint64(target->GetGUID()); - target->GetSession()->SendPacket(&data); - target->RemoveSpellCooldown(spell_id); - PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); - } - return true; -} - -bool ChatHandler::HandleLearnAllCommand(const char* /*args*/) -{ - static const char *allSpellList[] = - { - "3365", - "6233", - "6247", - "6246", - "6477", - "6478", - "22810", - "8386", - "21651", - "21652", - "522", - "7266", - "8597", - "2479", - "22027", - "6603", - "5019", - "133", - "168", - "227", - "5009", - "9078", - "668", - "203", - "20599", - "20600", - "81", - "20597", - "20598", - "20864", - "1459", - "5504", - "587", - "5143", - "118", - "5505", - "597", - "604", - "1449", - "1460", - "2855", - "1008", - "475", - "5506", - "1463", - "12824", - "8437", - "990", - "5145", - "8450", - "1461", - "759", - "8494", - "8455", - "8438", - "6127", - "8416", - "6129", - "8451", - "8495", - "8439", - "3552", - "8417", - "10138", - "12825", - "10169", - "10156", - "10144", - "10191", - "10201", - "10211", - "10053", - "10173", - "10139", - "10145", - "10192", - "10170", - "10202", - "10054", - "10174", - "10193", - "12826", - "2136", - "143", - "145", - "2137", - "2120", - "3140", - "543", - "2138", - "2948", - "8400", - "2121", - "8444", - "8412", - "8457", - "8401", - "8422", - "8445", - "8402", - "8413", - "8458", - "8423", - "8446", - "10148", - "10197", - "10205", - "10149", - "10215", - "10223", - "10206", - "10199", - "10150", - "10216", - "10207", - "10225", - "10151", - "116", - "205", - "7300", - "122", - "837", - "10", - "7301", - "7322", - "6143", - "120", - "865", - "8406", - "6141", - "7302", - "8461", - "8407", - "8492", - "8427", - "8408", - "6131", - "7320", - "10159", - "8462", - "10185", - "10179", - "10160", - "10180", - "10219", - "10186", - "10177", - "10230", - "10181", - "10161", - "10187", - "10220", - "2018", - "2663", - "12260", - "2660", - "3115", - "3326", - "2665", - "3116", - "2738", - "3293", - "2661", - "3319", - "2662", - "9983", - "8880", - "2737", - "2739", - "7408", - "3320", - "2666", - "3323", - "3324", - "3294", - "22723", - "23219", - "23220", - "23221", - "23228", - "23338", - "10788", - "10790", - "5611", - "5016", - "5609", - "2060", - "10963", - "10964", - "10965", - "22593", - "22594", - "596", - "996", - "499", - "768", - "17002", - "1448", - "1082", - "16979", - "1079", - "5215", - "20484", - "5221", - "15590", - "17007", - "6795", - "6807", - "5487", - "1446", - "1066", - "5421", - "3139", - "779", - "6811", - "6808", - "1445", - "5216", - "1737", - "5222", - "5217", - "1432", - "6812", - "9492", - "5210", - "3030", - "1441", - "783", - "6801", - "20739", - "8944", - "9491", - "22569", - "5226", - "6786", - "1433", - "8973", - "1828", - "9495", - "9006", - "6794", - "8993", - "5203", - "16914", - "6784", - "9635", - "22830", - "20722", - "9748", - "6790", - "9753", - "9493", - "9752", - "9831", - "9825", - "9822", - "5204", - "5401", - "22831", - "6793", - "9845", - "17401", - "9882", - "9868", - "20749", - "9893", - "9899", - "9895", - "9832", - "9902", - "9909", - "22832", - "9828", - "9851", - "9883", - "9869", - "17406", - "17402", - "9914", - "20750", - "9897", - "9848", - "3127", - "107", - "204", - "9116", - "2457", - "78", - "18848", - "331", - "403", - "2098", - "1752", - "11278", - "11288", - "11284", - "6461", - "2344", - "2345", - "6463", - "2346", - "2352", - "775", - "1434", - "1612", - "71", - "2468", - "2458", - "2467", - "7164", - "7178", - "7367", - "7376", - "7381", - "21156", - "5209", - "3029", - "5201", - "9849", - "9850", - "20719", - "22568", - "22827", - "22828", - "22829", - "6809", - "8972", - "9005", - "9823", - "9827", - "6783", - "9913", - "6785", - "6787", - "9866", - "9867", - "9894", - "9896", - "6800", - "8992", - "9829", - "9830", - "780", - "769", - "6749", - "6750", - "9755", - "9754", - "9908", - "20745", - "20742", - "20747", - "20748", - "9746", - "9745", - "9880", - "9881", - "5391", - "842", - "3025", - "3031", - "3287", - "3329", - "1945", - "3559", - "4933", - "4934", - "4935", - "4936", - "5142", - "5390", - "5392", - "5404", - "5420", - "6405", - "7293", - "7965", - "8041", - "8153", - "9033", - "9034", - //"9036", problems with ghost state - "16421", - "21653", - "22660", - "5225", - "9846", - "2426", - "5916", - "6634", - //"6718", phasing stealth, annoying for learn all case. - "6719", - "8822", - "9591", - "9590", - "10032", - "17746", - "17747", - "8203", - "11392", - "12495", - "16380", - "23452", - "4079", - "4996", - "4997", - "4998", - "4999", - "5000", - "6348", - "6349", - "6481", - "6482", - "6483", - "6484", - "11362", - "11410", - "11409", - "12510", - "12509", - "12885", - "13142", - "21463", - "23460", - "11421", - "11416", - "11418", - "1851", - "10059", - "11423", - "11417", - "11422", - "11419", - "11424", - "11420", - "27", - "31", - "33", - "34", - "35", - "15125", - "21127", - "22950", - "1180", - "201", - "12593", - "12842", - "16770", - "6057", - "12051", - "18468", - "12606", - "12605", - "18466", - "12502", - "12043", - "15060", - "12042", - "12341", - "12848", - "12344", - "12353", - "18460", - "11366", - "12350", - "12352", - "13043", - "11368", - "11113", - "12400", - "11129", - "16766", - "12573", - "15053", - "12580", - "12475", - "12472", - "12953", - "12488", - "11189", - "12985", - "12519", - "16758", - "11958", - "12490", - "11426", - "3565", - "3562", - "18960", - "3567", - "3561", - "3566", - "3563", - "1953", - "2139", - "12505", - "13018", - "12522", - "12523", - "5146", - "5144", - "5148", - "8419", - "8418", - "10213", - "10212", - "10157", - "12524", - "13019", - "12525", - "13020", - "12526", - "13021", - "18809", - "13031", - "13032", - "13033", - "4036", - "3920", - "3919", - "3918", - "7430", - "3922", - "3923", - "7411", - "7418", - "7421", - "13262", - "7412", - "7415", - "7413", - "7416", - "13920", - "13921", - "7745", - "7779", - "7428", - "7457", - "7857", - "7748", - "7426", - "13421", - "7454", - "13378", - "7788", - "14807", - "14293", - "7795", - "6296", - "20608", - "755", - "444", - "427", - "428", - "442", - "447", - "3578", - "3581", - "19027", - "3580", - "665", - "3579", - "3577", - "6755", - "3576", - "2575", - "2577", - "2578", - "2579", - "2580", - "2656", - "2657", - "2576", - "3564", - "10248", - "8388", - "2659", - "14891", - "3308", - "3307", - "10097", - "2658", - "3569", - "16153", - "3304", - "10098", - "4037", - "3929", - "3931", - "3926", - "3924", - "3930", - "3977", - "3925", - "136", - "228", - "5487", - "43", - "202", - "0" - }; - - int loop = 0; - while(strcmp(allSpellList[loop], "0")) - { - uint32 spell = atol((char*)allSpellList[loop++]); - - if (m_session->GetPlayer()->HasSpell(spell)) - continue; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); - continue; - } - - m_session->GetPlayer()->learnSpell(spell,false); - } - - SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS); - - return true; -} - -bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/) -{ - static const char *gmSpellList[] = - { - "24347", // Become A Fish, No Breath Bar - "35132", // Visual Boom - "38488", // Attack 4000-8000 AOE - "38795", // Attack 2000 AOE + Slow Down 90% - "15712", // Attack 200 - "1852", // GM Spell Silence - "31899", // Kill - "31924", // Kill - "29878", // Kill My Self - "26644", // More Kill - - "28550", //Invisible 24 - "23452", //Invisible + Target - "0" - }; - - uint16 gmSpellIter = 0; - while( strcmp(gmSpellList[gmSpellIter], "0") ) - { - uint32 spell = atol((char*)gmSpellList[gmSpellIter++]); - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); - continue; - } - - m_session->GetPlayer()->learnSpell(spell,false); - } - - SendSysMessage(LANG_LEARNING_GM_SKILLS); - return true; -} - -bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/) -{ - HandleLearnAllMySpellsCommand(""); - HandleLearnAllMyTalentsCommand(""); - return true; -} - -bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/) -{ - ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass()); - if(!clsEntry) - return true; - uint32 family = clsEntry->spellfamily; - - for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++) - { - SpellEntry const *spellInfo = sSpellStore.LookupEntry(i); - if(!spellInfo) - continue; - - // skip server-side/triggered spells - if(spellInfo->spellLevel==0) - continue; - - // skip wrong class/race skills - if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id)) - continue; - - // skip other spell families - if( spellInfo->SpellFamilyName != family) - continue; - - // skip spells with first rank learned as talent (and all talents then also) - uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id); - if(GetTalentSpellCost(first_rank) > 0 ) - continue; - - // skip broken spells - if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) - continue; - - m_session->GetPlayer()->learnSpell(i,false); - } - - SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); - return true; -} - -bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/) -{ - Player* player = m_session->GetPlayer(); - uint32 classMask = player->getClassMask(); - - for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) - { - TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); - if(!talentInfo) - continue; - - TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); - if(!talentTabInfo) - continue; - - if( (classMask & talentTabInfo->ClassMask) == 0 ) - continue; - - // search highest talent rank - uint32 spellid = 0; - - for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank) - { - if(talentInfo->RankID[rank]!=0) - { - spellid = talentInfo->RankID[rank]; - break; - } - } - - if(!spellid) // ??? none spells in talent - continue; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) - continue; - - // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) - player->learnSpellHighRank(spellid); - } - - SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); - return true; -} - -bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/) -{ - Player* player = m_session->GetPlayer(); - - Pet* pet = player->GetPet(); - if(!pet) - { - SendSysMessage(LANG_NO_PET_FOUND); - SetSentErrorMessage(true); - return false; - } - - CreatureInfo const *ci = pet->GetCreatureInfo(); - if(!ci) - { - SendSysMessage(LANG_WRONG_PET_TYPE); - SetSentErrorMessage(true); - return false; - } - - CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); - if(!pet_family) - { - SendSysMessage(LANG_WRONG_PET_TYPE); - SetSentErrorMessage(true); - return false; - } - - if(pet_family->petTalentType < 0) // not hunter pet - { - SendSysMessage(LANG_WRONG_PET_TYPE); - SetSentErrorMessage(true); - return false; - } - - for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) - { - TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); - if(!talentInfo) - continue; - - TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); - if(!talentTabInfo) - continue; - - // prevent learn talent for different family (cheating) - if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0) - continue; - - // search highest talent rank - uint32 spellid = 0; - - for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank) - { - if(talentInfo->RankID[rank]!=0) - { - spellid = talentInfo->RankID[rank]; - break; - } - } - - if(!spellid) // ??? none spells in talent - continue; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) - continue; - - // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) - pet->learnSpellHighRank(spellid); - } - - SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); - return true; -} - -bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/) -{ - // skipping UNIVERSAL language (0) - for(int i = 1; i < LANGUAGES_COUNT; ++i) - m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false); - - SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); - return true; -} - -bool ChatHandler::HandleLearnAllDefaultCommand(const char* args) -{ - Player *player = NULL; - if (*args) - { - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(name.c_str()); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - player->learnDefaultSpells(); - player->learnQuestRewardedSpells(); - - PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(player).c_str()); - return true; -} - -bool ChatHandler::HandleLearnCommand(const char* args) -{ - Player* targetPlayer = getSelectedPlayer(); - - if(!targetPlayer) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if(!spell || !sSpellStore.LookupEntry(spell)) - return false; - - char const* allStr = strtok(NULL," "); - bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); - SetSentErrorMessage(true); - return false; - } - - if (!allRanks && targetPlayer->HasSpell(spell)) - { - if(targetPlayer == m_session->GetPlayer()) - SendSysMessage(LANG_YOU_KNOWN_SPELL); - else - PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str()); - SetSentErrorMessage(true); - return false; - } - - if(allRanks) - targetPlayer->learnSpellHighRank(spell); - else - targetPlayer->learnSpell(spell,false); - - return true; -} - -bool ChatHandler::HandleAddItemCommand(const char* args) -{ - if (!*args) - return false; - - uint32 itemId = 0; - - if(args[0]=='[') // [name] manual form - { - char* citemName = citemName = strtok((char*)args, "]"); - - if(citemName && citemName[0]) - { - std::string itemName = citemName+1; - WorldDatabase.escape_string(itemName); - QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str()); - if (!result) - { - PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1); - SetSentErrorMessage(true); - return false; - } - itemId = result->Fetch()->GetUInt16(); - delete result; - } - else - return false; - } - else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r - { - char* cId = extractKeyFromLink((char*)args,"Hitem"); - if(!cId) - return false; - itemId = atol(cId); - } - - char* ccount = strtok(NULL, " "); - - int32 count = 1; - - if (ccount) - count = strtol(ccount, NULL, 10); - - if (count == 0) - count = 1; - - Player* pl = m_session->GetPlayer(); - Player* plTarget = getSelectedPlayer(); - if(!plTarget) - plTarget = pl; - - sLog.outDetail(GetTrinityString(LANG_ADDITEM), itemId, count); - - ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId); - if(!pProto) - { - PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); - SetSentErrorMessage(true); - return false; - } - - //Subtract - if (count < 0) - { - plTarget->DestroyItemCount(itemId, -count, true, false); - PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str()); - return true; - } - - //Adding items - uint32 noSpaceForCount = 0; - - // check space and find places - ItemPosCountVec dest; - uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount ); - if( msg != EQUIP_ERR_OK ) // convert to possible store amount - count -= noSpaceForCount; - - if( count == 0 || dest.empty()) // can't add any - { - PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount ); - SetSentErrorMessage(true); - return false; - } - - Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); - - // remove binding (let GM give it to another player later) - if(pl==plTarget) - for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) - if(Item* item1 = pl->GetItemByPos(itr->pos)) - item1->SetBinding( false ); - - if(count > 0 && item) - { - pl->SendNewItem(item,count,false,true); - if(pl!=plTarget) - plTarget->SendNewItem(item,count,true,false); - } - - if(noSpaceForCount > 0) - PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); - - return true; -} - -bool ChatHandler::HandleAddItemSetCommand(const char* args) -{ - if (!*args) - return false; - - char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r - if (!cId) - return false; - - uint32 itemsetId = atol(cId); - - // prevent generation all items with itemset field value '0' - if (itemsetId == 0) - { - PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); - SetSentErrorMessage(true); - return false; - } - - Player* pl = m_session->GetPlayer(); - Player* plTarget = getSelectedPlayer(); - if(!plTarget) - plTarget = pl; - - sLog.outDetail(GetTrinityString(LANG_ADDITEMSET), itemsetId); - - bool found = false; - for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) - { - ItemPrototype const *pProto = sItemStorage.LookupEntry(id); - if (!pProto) - continue; - - if (pProto->ItemSet == itemsetId) - { - found = true; - ItemPosCountVec dest; - uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 ); - if (msg == EQUIP_ERR_OK) - { - Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true); - - // remove binding (let GM give it to another player later) - if (pl==plTarget) - item->SetBinding( false ); - - pl->SendNewItem(item,1,false,true); - if (pl!=plTarget) - plTarget->SendNewItem(item,1,true,false); - } - else - { - pl->SendEquipError( msg, NULL, NULL ); - PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1); - } - } - } - - if (!found) - { - PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); - - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleListItemCommand(const char* args) -{ - if(!*args) - return false; - - char* cId = extractKeyFromLink((char*)args,"Hitem"); - if(!cId) - return false; - - uint32 item_id = atol(cId); - if(!item_id) - { - PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); - SetSentErrorMessage(true); - return false; - } - - ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id); - if(!itemProto) - { - PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); - SetSentErrorMessage(true); - return false; - } - - char* c_count = strtok(NULL, " "); - int count = c_count ? atol(c_count) : 10; - - if(count < 0) - return false; - - QueryResult *result; - - // inventory case - uint32 inv_count = 0; - result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id); - if(result) - { - inv_count = (*result)[0].GetUInt32(); - delete result; - } - - result=CharacterDatabase.PQuery( - // 0 1 2 3 4 5 - "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name " - "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters " - "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ", - item_id,uint32(count)); - - if(result) - { - do - { - Field *fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 item_bag = fields[1].GetUInt32(); - uint32 item_slot = fields[2].GetUInt32(); - uint32 owner_guid = fields[3].GetUInt32(); - uint32 owner_acc = fields[4].GetUInt32(); - std::string owner_name = fields[5].GetCppString(); - - char const* item_pos = 0; - if(Player::IsEquipmentPos(item_bag,item_slot)) - item_pos = "[equipped]"; - else if(Player::IsInventoryPos(item_bag,item_slot)) - item_pos = "[in inventory]"; - else if(Player::IsBankPos(item_bag,item_slot)) - item_pos = "[in bank]"; - else - item_pos = ""; - - PSendSysMessage(LANG_ITEMLIST_SLOT, - item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos); - } while (result->NextRow()); - - int64 res_count = result->GetRowCount(); - - delete result; - - if(count > res_count) - count-=res_count; - else if(count) - count = 0; - } - - // mail case - uint32 mail_count = 0; - result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id); - if(result) - { - mail_count = (*result)[0].GetUInt32(); - delete result; - } - - if(count > 0) - { - result=CharacterDatabase.PQuery( - // 0 1 2 3 4 5 6 - "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name " - "FROM mail,mail_items,characters as char_s,characters as char_r " - "WHERE mail_items.item_template='%u' AND char_s.guid = mail.sender AND char_r.guid = mail.receiver AND mail.id=mail_items.mail_id LIMIT %u", - item_id,uint32(count)); - } - else - result = NULL; - - if(result) - { - do - { - Field *fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 item_s = fields[1].GetUInt32(); - uint32 item_r = fields[2].GetUInt32(); - uint32 item_s_acc = fields[3].GetUInt32(); - std::string item_s_name = fields[4].GetCppString(); - uint32 item_r_acc = fields[5].GetUInt32(); - std::string item_r_name = fields[6].GetCppString(); - - char const* item_pos = "[in mail]"; - - PSendSysMessage(LANG_ITEMLIST_MAIL, - item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos); - } while (result->NextRow()); - - int64 res_count = result->GetRowCount(); - - delete result; - - if(count > res_count) - count-=res_count; - else if(count) - count = 0; - } - - // auction case - uint32 auc_count = 0; - result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id); - if(result) - { - auc_count = (*result)[0].GetUInt32(); - delete result; - } - - if(count > 0) - { - result=CharacterDatabase.PQuery( - // 0 1 2 3 - "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name " - "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u", - item_id,uint32(count)); - } - else - result = NULL; - - if(result) - { - do - { - Field *fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 owner = fields[1].GetUInt32(); - uint32 owner_acc = fields[2].GetUInt32(); - std::string owner_name = fields[3].GetCppString(); - - char const* item_pos = "[in auction]"; - - PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos); - } while (result->NextRow()); - - delete result; - } - - // guild bank case - uint32 guild_count = 0; - result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id); - if(result) - { - guild_count = (*result)[0].GetUInt32(); - delete result; - } - - result=CharacterDatabase.PQuery( - // 0 1 2 - "SELECT gi.item_guid, gi.guildid, guild.name " - "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ", - item_id,uint32(count)); - - if(result) - { - do - { - Field *fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 guild_guid = fields[1].GetUInt32(); - std::string guild_name = fields[2].GetCppString(); - - char const* item_pos = "[in guild bank]"; - - PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos); - } while (result->NextRow()); - - int64 res_count = result->GetRowCount(); - - delete result; - - if(count > res_count) - count-=res_count; - else if(count) - count = 0; - } - - if(inv_count+mail_count+auc_count+guild_count == 0) - { - SendSysMessage(LANG_COMMAND_NOITEMFOUND); - SetSentErrorMessage(true); - return false; - } - - PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count); - - return true; -} - -bool ChatHandler::HandleListObjectCommand(const char* args) -{ - if(!*args) - return false; - - // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry"); - if(!cId) - return false; - - uint32 go_id = atol(cId); - if(!go_id) - { - PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); - SetSentErrorMessage(true); - return false; - } - - GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id); - if(!gInfo) - { - PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); - SetSentErrorMessage(true); - return false; - } - - char* c_count = strtok(NULL, " "); - int count = c_count ? atol(c_count) : 10; - - if(count < 0) - return false; - - QueryResult *result; - - uint32 obj_count = 0; - result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id); - if(result) - { - obj_count = (*result)[0].GetUInt32(); - delete result; - } - - if(m_session) - { - Player* pl = m_session->GetPlayer(); - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", - pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count)); - } - else - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u", - go_id,uint32(count)); - - if (result) - { - do - { - Field *fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - float x = fields[1].GetFloat(); - float y = fields[2].GetFloat(); - float z = fields[3].GetFloat(); - int mapid = fields[4].GetUInt16(); - - if (m_session) - PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid); - else - PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid); - } while (result->NextRow()); - - delete result; - } - - PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count); - return true; -} - -bool ChatHandler::HandleGameObjectStateCommand(const char* args) -{ - // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args, "Hgameobject"); - if(!cId) - return false; - - uint32 lowguid = atoi(cId); - if(!lowguid) - return false; - - GameObject* gobj = NULL; - - if(GameObjectData const* goData = objmgr.GetGOData(lowguid)) - gobj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid, goData->id); - - if(!gobj) - { - PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); - SetSentErrorMessage(true); - return false; - } - - char* cstate = strtok(NULL, " "); - if(!cstate) - return false; - - int32 state = atoi(cstate); - if(state < 0) - gobj->SendObjectDeSpawnAnim(gobj->GetGUID()); - else - gobj->SetGoState(state); - - return true; -} - -bool ChatHandler::HandleListCreatureCommand(const char* args) -{ - if(!*args) - return false; - - // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args,"Hcreature_entry"); - if(!cId) - return false; - - uint32 cr_id = atol(cId); - if(!cr_id) - { - PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); - SetSentErrorMessage(true); - return false; - } - - CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id); - if(!cInfo) - { - PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); - SetSentErrorMessage(true); - return false; - } - - char* c_count = strtok(NULL, " "); - int count = c_count ? atol(c_count) : 10; - - if(count < 0) - return false; - - QueryResult *result; - - uint32 cr_count = 0; - result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id); - if(result) - { - cr_count = (*result)[0].GetUInt32(); - delete result; - } - - if(m_session) - { - Player* pl = m_session->GetPlayer(); - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", - pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count)); - } - else - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", - cr_id,uint32(count)); - - if (result) - { - do - { - Field *fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - float x = fields[1].GetFloat(); - float y = fields[2].GetFloat(); - float z = fields[3].GetFloat(); - int mapid = fields[4].GetUInt16(); - - if (m_session) - PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid); - else - PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid); - } while (result->NextRow()); - - delete result; - } - - PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count); - return true; -} - -bool ChatHandler::HandleLookupItemCommand(const char* args) -{ - if(!*args) - return false; - - std::string namepart = args; - std::wstring wnamepart; - - // converting string that we try to find to lower case - if(!Utf8toWStr(namepart,wnamepart)) - return false; - - wstrToLower(wnamepart); - - uint32 counter = 0; - - // Search in `item_template` - for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) - { - ItemPrototype const *pProto = sItemStorage.LookupEntry(id); - if(!pProto) - continue; - - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); - if ( loc_idx >= 0 ) - { - ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); - if (il) - { - if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) - { - std::string name = il->Name[loc_idx]; - - if (Utf8FitTo(name, wnamepart)) - { - if (m_session) - PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str()); - else - PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str()); - ++counter; - continue; - } - } - } - } - - std::string name = pProto->Name1; - if(name.empty()) - continue; - - if (Utf8FitTo(name, wnamepart)) - { - if (m_session) - PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str()); - else - PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str()); - ++counter; - } - } - - if (counter==0) - SendSysMessage(LANG_COMMAND_NOITEMFOUND); - - return true; -} - -bool ChatHandler::HandleLookupItemSetCommand(const char* args) -{ - if(!*args) - return false; - - std::string namepart = args; - std::wstring wnamepart; - - if(!Utf8toWStr(namepart,wnamepart)) - return false; - - // converting string that we try to find to lower case - wstrToLower( wnamepart ); - - uint32 counter = 0; // Counter for figure out that we found smth. - - // Search in ItemSet.dbc - for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++) - { - ItemSetEntry const *set = sItemSetStore.LookupEntry(id); - if(set) - { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); - std::string name = set->name[loc]; - if(name.empty()) - continue; - - if (!Utf8FitTo(name, wnamepart)) - { - loc = 0; - for(; loc < MAX_LOCALE; ++loc) - { - if(m_session && loc==m_session->GetSessionDbcLocale()) - continue; - - name = set->name[loc]; - if(name.empty()) - continue; - - if (Utf8FitTo(name, wnamepart)) - break; - } - } - - if(loc < MAX_LOCALE) - { - // send item set in "id - [namedlink locale]" format - if (m_session) - PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]); - else - PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]); - ++counter; - } - } - } - if (counter == 0) // if counter == 0 then we found nth - SendSysMessage(LANG_COMMAND_NOITEMSETFOUND); - return true; -} - -bool ChatHandler::HandleLookupSkillCommand(const char* args) -{ - if(!*args) - return false; - - // can be NULL in console call - Player* target = getSelectedPlayer(); - - std::string namepart = args; - std::wstring wnamepart; - - if(!Utf8toWStr(namepart,wnamepart)) - return false; - - // converting string that we try to find to lower case - wstrToLower( wnamepart ); - - uint32 counter = 0; // Counter for figure out that we found smth. - - // Search in SkillLine.dbc - for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++) - { - SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id); - if(skillInfo) - { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); - std::string name = skillInfo->name[loc]; - if(name.empty()) - continue; - - if (!Utf8FitTo(name, wnamepart)) - { - loc = 0; - for(; loc < MAX_LOCALE; ++loc) - { - if(m_session && loc==m_session->GetSessionDbcLocale()) - continue; - - name = skillInfo->name[loc]; - if(name.empty()) - continue; - - if (Utf8FitTo(name, wnamepart)) - break; - } - } - - if(loc < MAX_LOCALE) - { - char valStr[50] = ""; - char const* knownStr = ""; - if(target && target->HasSkill(id)) - { - knownStr = GetTrinityString(LANG_KNOWN); - uint32 curValue = target->GetPureSkillValue(id); - uint32 maxValue = target->GetPureMaxSkillValue(id); - uint32 permValue = target->GetSkillPermBonusValue(id); - uint32 tempValue = target->GetSkillTempBonusValue(id); - - char const* valFormat = GetTrinityString(LANG_SKILL_VALUES); - snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue); - } - - // send skill in "id - [namedlink locale]" format - if (m_session) - PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr); - else - PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr); - - ++counter; - } - } - } - if (counter == 0) // if counter == 0 then we found nth - SendSysMessage(LANG_COMMAND_NOSKILLFOUND); - return true; -} - -bool ChatHandler::HandleLookupSpellCommand(const char* args) -{ - if(!*args) - return false; - - // can be NULL at console call - Player* target = getSelectedPlayer(); - - std::string namepart = args; - std::wstring wnamepart; - - if(!Utf8toWStr(namepart,wnamepart)) - return false; - - // converting string that we try to find to lower case - wstrToLower( wnamepart ); - - uint32 counter = 0; // Counter for figure out that we found smth. - - // Search in Spell.dbc - for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++) - { - SpellEntry const *spellInfo = sSpellStore.LookupEntry(id); - if(spellInfo) - { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); - std::string name = spellInfo->SpellName[loc]; - if(name.empty()) - continue; - - if (!Utf8FitTo(name, wnamepart)) - { - loc = 0; - for(; loc < MAX_LOCALE; ++loc) - { - if(m_session && loc==m_session->GetSessionDbcLocale()) - continue; - - name = spellInfo->SpellName[loc]; - if(name.empty()) - continue; - - if (Utf8FitTo(name, wnamepart)) - break; - } - } - - if(loc < MAX_LOCALE) - { - bool known = target && target->HasSpell(id); - bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL); - - uint32 talentCost = GetTalentSpellCost(id); - - bool talent = (talentCost > 0); - bool passive = IsPassiveSpell(id); - bool active = target && target->HasAura(id); - - // unit32 used to prevent interpreting uint8 as char at output - // find rank of learned spell for learning spell, or talent rank - uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id); - - // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format - std::ostringstream ss; - if (m_session) - ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; - else - ss << id << " - " << name; - - // include rank in link name - if(rank) - ss << GetTrinityString(LANG_SPELL_RANK) << rank; - - if (m_session) - ss << " " << localeNames[loc] << "]|h|r"; - else - ss << " " << localeNames[loc]; - - if(talent) - ss << GetTrinityString(LANG_TALENT); - if(passive) - ss << GetTrinityString(LANG_PASSIVE); - if(learn) - ss << GetTrinityString(LANG_LEARN); - if(known) - ss << GetTrinityString(LANG_KNOWN); - if(active) - ss << GetTrinityString(LANG_ACTIVE); - - SendSysMessage(ss.str().c_str()); - - ++counter; - } - } - } - if (counter == 0) // if counter == 0 then we found nth - SendSysMessage(LANG_COMMAND_NOSPELLFOUND); - return true; -} - -bool ChatHandler::HandleLookupQuestCommand(const char* args) -{ - if(!*args) - return false; - - // can be NULL at console call - Player* target = getSelectedPlayer(); - - std::string namepart = args; - std::wstring wnamepart; - - // converting string that we try to find to lower case - if(!Utf8toWStr(namepart,wnamepart)) - return false; - - wstrToLower(wnamepart); - - uint32 counter = 0 ; - - ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates(); - for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter) - { - Quest * qinfo = iter->second; - - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); - if ( loc_idx >= 0 ) - { - QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId()); - if (il) - { - if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty()) - { - std::string title = il->Title[loc_idx]; - - if (Utf8FitTo(title, wnamepart)) - { - char const* statusStr = ""; - - if(target) - { - QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); - - if(status == QUEST_STATUS_COMPLETE) - { - if(target->GetQuestRewardStatus(qinfo->GetQuestId())) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); - else - statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); - } - else if(status == QUEST_STATUS_INCOMPLETE) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); - } - - if (m_session) - PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr); - else - PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr); - ++counter; - continue; - } - } - } - } - - std::string title = qinfo->GetTitle(); - if(title.empty()) - continue; - - if (Utf8FitTo(title, wnamepart)) - { - char const* statusStr = ""; - - if(target) - { - QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); - - if(status == QUEST_STATUS_COMPLETE) - { - if(target->GetQuestRewardStatus(qinfo->GetQuestId())) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); - else - statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); - } - else if(status == QUEST_STATUS_INCOMPLETE) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); - } - - if (m_session) - PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr); - else - PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr); - - ++counter; - } - } - - if (counter==0) - SendSysMessage(LANG_COMMAND_NOQUESTFOUND); - - return true; -} - -bool ChatHandler::HandleLookupCreatureCommand(const char* args) -{ - if (!*args) - return false; - - std::string namepart = args; - std::wstring wnamepart; - - // converting string that we try to find to lower case - if (!Utf8toWStr (namepart,wnamepart)) - return false; - - wstrToLower (wnamepart); - - uint32 counter = 0; - - for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id) - { - CreatureInfo const* cInfo = sCreatureStorage.LookupEntry (id); - if(!cInfo) - continue; - - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); - if (loc_idx >= 0) - { - CreatureLocale const *cl = objmgr.GetCreatureLocale (id); - if (cl) - { - if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ()) - { - std::string name = cl->Name[loc_idx]; - - if (Utf8FitTo (name, wnamepart)) - { - if (m_session) - PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ()); - else - PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ()); - ++counter; - continue; - } - } - } - } - - std::string name = cInfo->Name; - if (name.empty ()) - continue; - - if (Utf8FitTo(name, wnamepart)) - { - if (m_session) - PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ()); - else - PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ()); - ++counter; - } - } - - if (counter==0) - SendSysMessage (LANG_COMMAND_NOCREATUREFOUND); - - return true; -} - -bool ChatHandler::HandleLookupObjectCommand(const char* args) -{ - if(!*args) - return false; - - std::string namepart = args; - std::wstring wnamepart; - - // converting string that we try to find to lower case - if(!Utf8toWStr(namepart,wnamepart)) - return false; - - wstrToLower(wnamepart); - - uint32 counter = 0; - - for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ ) - { - GameObjectInfo const* gInfo = sGOStorage.LookupEntry(id); - if(!gInfo) - continue; - - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); - if ( loc_idx >= 0 ) - { - GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id); - if (gl) - { - if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty()) - { - std::string name = gl->Name[loc_idx]; - - if (Utf8FitTo(name, wnamepart)) - { - if (m_session) - PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str()); - else - PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str()); - ++counter; - continue; - } - } - } - } - - std::string name = gInfo->name; - if(name.empty()) - continue; - - if(Utf8FitTo(name, wnamepart)) - { - if (m_session) - PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str()); - else - PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str()); - ++counter; - } - } - - if(counter==0) - SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND); - - return true; -} - -/** \brief GM command level 3 - Create a guild. - * - * This command allows a GM (level 3) to create a guild. - * - * The "args" parameter contains the name of the guild leader - * and then the name of the guild. - * - */ -bool ChatHandler::HandleGuildCreateCommand(const char* args) -{ - - if (!*args) - return false; - - char *lname = strtok ((char*)args, " "); - char *gname = strtok (NULL, ""); - - if (!lname) - return false; - - if (!gname) - { - SendSysMessage (LANG_INSERT_GUILD_NAME); - SetSentErrorMessage (true); - return false; - } - - std::string guildname = gname; - - Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname); - if (!player) - { - SendSysMessage (LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage (true); - return false; - } - - if (player->GetGuildId()) - { - SendSysMessage (LANG_PLAYER_IN_GUILD); - return true; - } - - Guild *guild = new Guild; - if (!guild->create (player,guildname)) - { - delete guild; - SendSysMessage (LANG_GUILD_NOT_CREATED); - SetSentErrorMessage (true); - return false; - } - - objmgr.AddGuild (guild); - return true; -} - -bool ChatHandler::HandleGuildInviteCommand(const char *args) -{ - if (!*args) - return false; - - char* par1 = strtok ((char*)args, " "); - char* par2 = strtok (NULL, ""); - if(!par1 || !par2) - return false; - - std::string glName = par2; - Guild* targetGuild = objmgr.GetGuildByName (glName); - if (!targetGuild) - return false; - - std::string plName = extractPlayerNameFromLink(par1); - if(plName.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 plGuid = 0; - if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) - plGuid = targetPlayer->GetGUID (); - else - plGuid = objmgr.GetPlayerGUIDByName (plName); - - if (!plGuid) - return false; - - // player's guild membership checked in AddMember before add - if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ())) - return false; - - return true; -} - -bool ChatHandler::HandleGuildUninviteCommand(const char *args) -{ - if (!*args) - return false; - - char* par1 = strtok ((char*)args, " "); - if(!par1) - return false; - - std::string plName = extractPlayerNameFromLink(par1); - if(plName.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 plGuid = 0; - uint32 glId = 0; - if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) - { - plGuid = targetPlayer->GetGUID (); - glId = targetPlayer->GetGuildId (); - } - else - { - plGuid = objmgr.GetPlayerGUIDByName (plName); - glId = Player::GetGuildIdFromDB (plGuid); - } - - if (!plGuid || !glId) - return false; - - Guild* targetGuild = objmgr.GetGuildById (glId); - if (!targetGuild) - return false; - - targetGuild->DelMember (plGuid); - - return true; -} - -bool ChatHandler::HandleGuildRankCommand(const char *args) -{ - if (!*args) - return false; - - char* par1 = strtok ((char*)args, " "); - char* par2 = strtok (NULL, " "); - if (!par1 || !par2) - return false; - - std::string plName = extractPlayerNameFromLink(par1); - if(plName.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - - uint64 plGuid = 0; - uint32 glId = 0; - if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) - { - plGuid = targetPlayer->GetGUID (); - glId = targetPlayer->GetGuildId (); - } - else - { - plGuid = objmgr.GetPlayerGUIDByName (plName); - glId = Player::GetGuildIdFromDB (plGuid); - } - - if (!plGuid || !glId) - return false; - - Guild* targetGuild = objmgr.GetGuildById (glId); - if (!targetGuild) - return false; - - uint32 newrank = uint32 (atoi (par2)); - if (newrank > targetGuild->GetLowestRank ()) - return false; - - targetGuild->ChangeRank (plGuid,newrank); - - return true; -} - -bool ChatHandler::HandleGuildDeleteCommand(const char* args) -{ - if (!*args) - return false; - - char* par1 = strtok ((char*)args, " "); - if (!par1) - return false; - - std::string gld = par1; - - Guild* targetGuild = objmgr.GetGuildByName (gld); - if (!targetGuild) - return false; - - targetGuild->Disband (); - - return true; -} - -bool ChatHandler::HandleGetDistanceCommand(const char* args) -{ - WorldObject* obj = NULL; - - if (*args) - { - uint64 guid = extractGuidFromLink((char*)args); - if(guid) - obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); - - if(!obj) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - } - else - { - obj = getSelectedUnit(); - - if(!obj) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - } - - PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj)); - - return true; -} - -bool ChatHandler::HandleDieCommand(const char* /*args*/) -{ - Unit* target = getSelectedUnit(); - - if(!target || !m_session->GetPlayer()->GetSelection()) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - if(target->GetTypeId()==TYPEID_PLAYER) - { - if(HasLowerSecurity((Player*)target,0,false)) - return false; - } - - if( target->isAlive() ) - { - //m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - m_session->GetPlayer()->Kill(target); - } - - return true; -} - -bool ChatHandler::HandleDamageCommand(const char * args) -{ - if (!*args) - return false; - - Unit* target = getSelectedUnit(); - - if(!target || !m_session->GetPlayer()->GetSelection()) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - if( !target->isAlive() ) - return true; - - char* damageStr = strtok((char*)args, " "); - if(!damageStr) - return false; - - int32 damage = atoi((char*)damageStr); - if(damage <=0) - return true; - - char* schoolStr = strtok((char*)NULL, " "); - - // flat melee damage without resistence/etc reduction - if(!schoolStr) - { - m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0); - return true; - } - - uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL; - if(school >= MAX_SPELL_SCHOOL) - return false; - - SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); - - if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL ) - damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK); - - char* spellStr = strtok((char*)NULL, " "); - - // melee damage by specific school - if(!spellStr) - { - uint32 absorb = 0; - uint32 resist = 0; - - m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); - - if (damage <= absorb + resist) - return true; - - damage -= absorb + resist; - - m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); - m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0); - return true; - } - - // non-melee damage - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellid = extractSpellIdFromLink((char*)args); - if(!spellid || !sSpellStore.LookupEntry(spellid)) - return false; - - m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false); - return true; -} - -bool ChatHandler::HandleModifyArenaCommand(const char * args) -{ - if (!*args) - return false; - - Player *target = getSelectedPlayer(); - if(!target) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - int32 amount = (uint32)atoi(args); - - target->ModifyArenaPoints(amount); - - PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints()); - - return true; -} - -bool ChatHandler::HandleReviveCommand(const char* args) -{ - Player* SelectedPlayer = NULL; - - if (*args) - { - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - SelectedPlayer = objmgr.GetPlayer(name.c_str()); - } - else - SelectedPlayer = getSelectedPlayer(); - - if(!SelectedPlayer) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - SelectedPlayer->ResurrectPlayer(0.5f); - SelectedPlayer->SpawnCorpseBones(); - SelectedPlayer->SaveToDB(); - return true; -} - -bool ChatHandler::HandleAuraCommand(const char* args) -{ - Unit *target = getSelectedUnit(); - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellID = extractSpellIdFromLink((char*)args); - - SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID ); - uint8 eff_mask=0; - if(spellInfo) - { - for(uint32 i = 0;i<3;i++) - { - uint8 eff = spellInfo->Effect[i]; - if (eff>=TOTAL_SPELL_EFFECTS) - continue; - if( IsAreaAuraEffect(eff) || - eff == SPELL_EFFECT_APPLY_AURA || - eff == SPELL_EFFECT_PERSISTENT_AREA_AURA ) - { - eff_mask|=1<AddAura(Aur); - - return true; -} - -bool ChatHandler::HandleUnAuraCommand(const char* args) -{ - Unit *target = getSelectedUnit(); - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - std::string argstr = args; - if (argstr == "all") - { - target->RemoveAllAuras(); - return true; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellID = extractSpellIdFromLink((char*)args); - if(!spellID) - return false; - - target->RemoveAurasDueToSpell(spellID); - - return true; -} - -bool ChatHandler::HandleLinkGraveCommand(const char* args) -{ - if(!*args) - return false; - - char* px = strtok((char*)args, " "); - if (!px) - return false; - - uint32 g_id = (uint32)atoi(px); - - uint32 g_team; - - char* px2 = strtok(NULL, " "); - - if (!px2) - g_team = 0; - else if (strncmp(px2,"horde",6)==0) - g_team = HORDE; - else if (strncmp(px2,"alliance",9)==0) - g_team = ALLIANCE; - else - return false; - - WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id); - - if(!graveyard ) - { - PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id); - SetSentErrorMessage(true); - return false; - } - - Player* player = m_session->GetPlayer(); - - uint32 zoneId = player->GetZoneId(); - - AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId); - if(!areaEntry || areaEntry->zone !=0 ) - { - PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId); - SetSentErrorMessage(true); - return false; - } - - if(objmgr.AddGraveYardLink(g_id,zoneId,g_team)) - PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId); - else - PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId); - - return true; -} - -bool ChatHandler::HandleNearGraveCommand(const char* args) -{ - uint32 g_team; - - size_t argslen = strlen(args); - - if(!*args) - g_team = 0; - else if (strncmp((char*)args,"horde",argslen)==0) - g_team = HORDE; - else if (strncmp((char*)args,"alliance",argslen)==0) - g_team = ALLIANCE; - else - return false; - - Player* player = m_session->GetPlayer(); - uint32 zone_id = player->GetZoneId(); - - WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard( - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team); - - if(graveyard) - { - uint32 g_id = graveyard->ID; - - GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id); - if (!data) - { - PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id); - SetSentErrorMessage(true); - return false; - } - - g_team = data->team; - - std::string team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); - - if(g_team == 0) - team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); - else if(g_team == HORDE) - team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); - else if(g_team == ALLIANCE) - team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - - PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id); - } - else - { - std::string team_name; - - if(g_team == 0) - team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); - else if(g_team == HORDE) - team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); - else if(g_team == ALLIANCE) - team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - - if(g_team == ~uint32(0)) - PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); - else - PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str()); - } - - return true; -} - -//-----------------------Npc Commands----------------------- -bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/) -{ - if(sWorld.getAllowMovement()) - { - sWorld.SetAllowMovement(false); - SendSysMessage(LANG_CREATURE_MOVE_DISABLED); - } - else - { - sWorld.SetAllowMovement(true); - SendSysMessage(LANG_CREATURE_MOVE_ENABLED); - } - return true; -} - -bool ChatHandler::HandleNpcChangeEntryCommand(const char *args) -{ - if (!*args) - return false; - - uint32 newEntryNum = atoi(args); - if(!newEntryNum) - return false; - - Unit* unit = getSelectedUnit(); - if(!unit || unit->GetTypeId() != TYPEID_UNIT) - { - SendSysMessage(LANG_SELECT_CREATURE); - SetSentErrorMessage(true); - return false; - } - Creature* creature = (Creature*)unit; - if(creature->UpdateEntry(newEntryNum)) - SendSysMessage(LANG_DONE); - else - SendSysMessage(LANG_ERROR); - return true; -} - -bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/) -{ - Creature* target = getSelectedCreature(); - - if(!target) - { - SendSysMessage(LANG_SELECT_CREATURE); - SetSentErrorMessage(true); - return false; - } - - uint32 faction = target->getFaction(); - uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS); - uint32 displayid = target->GetDisplayId(); - uint32 nativeid = target->GetNativeDisplayId(); - uint32 Entry = target->GetEntry(); - CreatureInfo const* cInfo = target->GetCreatureInfo(); - - int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); - if(curRespawnDelay < 0) - curRespawnDelay = 0; - std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); - std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); - - PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid); - PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); - PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); - PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); - PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); - PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId); - PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); - PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); - - if ((npcflags & UNIT_NPC_FLAG_VENDOR) ) - { - SendSysMessage(LANG_NPCINFO_VENDOR); - } - if ((npcflags & UNIT_NPC_FLAG_TRAINER) ) - { - SendSysMessage(LANG_NPCINFO_TRAINER); - } - - return true; -} - -//play npc emote -bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args) -{ - uint32 emote = atoi((char*)args); - - Creature* target = getSelectedCreature(); - if(!target) - { - SendSysMessage(LANG_SELECT_CREATURE); - SetSentErrorMessage(true); - return false; - } - - target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote); - - return true; -} - -//TODO: NpcCommands that needs to be fixed : - -bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/) -{ - /*if (!*args) - return false; - - uint64 guid = m_session->GetPlayer()->GetSelection(); - if (guid == 0) - { - SendSysMessage(LANG_NO_SELECTION); - return true; - } - - Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); - - if(!pCreature) - { - SendSysMessage(LANG_SELECT_CREATURE); - return true; - } - - char* pSlotID = strtok((char*)args, " "); - if (!pSlotID) - return false; - - char* pItemID = strtok(NULL, " "); - if (!pItemID) - return false; - - uint32 ItemID = atoi(pItemID); - uint32 SlotID = atoi(pSlotID); - - ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID); - - bool added = false; - if(tmpItem) - { - switch(SlotID) - { - case 1: - pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID); - added = true; - break; - case 2: - pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID); - added = true; - break; - case 3: - pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID); - added = true; - break; - default: - PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); - added = false; - break; - } - - if(added) - PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); - } - else - { - PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); - return true; - } - */ - return true; -} -//---------------------------------------------------------- - -bool ChatHandler::HandleExploreCheatCommand(const char* args) -{ - if (!*args) - return false; - - int flag = atoi((char*)args); - - Player *chr = getSelectedPlayer(); - if (chr == NULL) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if (flag != 0) - { - PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str()); - if (needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str()); - } - else - { - PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str()); - if (needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str()); - } - - for (uint8 i=0; i<128; i++) - { - if (flag != 0) - { - m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF); - } - else - { - m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0); - } - } - - return true; -} - -bool ChatHandler::HandleHoverCommand(const char* args) -{ - char* px = strtok((char*)args, " "); - uint32 flag; - if (!px) - flag = 1; - else - flag = atoi(px); - - m_session->GetPlayer()->SetHover(flag); - - if (flag) - SendSysMessage(LANG_HOVER_ENABLED); - else - SendSysMessage(LANG_HOVER_DISABLED); - - return true; -} - -bool ChatHandler::HandleLevelUpCommand(const char* args) -{ - char* px = strtok((char*)args, " "); - char* py = strtok((char*)NULL, " "); - - // command format parsing - char* pname = (char*)NULL; - int addlevel = 1; - - if(px && py) // .levelup name level - { - addlevel = atoi(py); - pname = px; - } - else if(px && !py) // .levelup name OR .levelup level - { - if(isalpha(px[0])) // .levelup name - pname = px; - else // .levelup level - addlevel = atoi(px); - } - // else .levelup - nothing do for preparing - - // player - Player *chr = NULL; - uint64 chr_guid = 0; - - std::string name; - - if(pname) // player by name - { - name = extractPlayerNameFromLink(pname); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - chr = objmgr.GetPlayer(name.c_str()); - if(!chr) // not in game - { - chr_guid = objmgr.GetPlayerGUIDByName(name); - if (chr_guid == 0) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - } - } - else // player by selection - { - chr = getSelectedPlayer(); - - if (chr == NULL) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - name = chr->GetName(); - } - - assert(chr || chr_guid); - - int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid); - int32 newlevel = oldlevel + addlevel; - if(newlevel < 1) - newlevel = 1; - if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level - newlevel = STRONG_MAX_LEVEL; - - if(chr) - { - chr->GiveLevel(newlevel); - chr->InitTalentForLevel(); - chr->SetUInt32Value(PLAYER_XP,0); - - if(oldlevel == newlevel) - ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET); - else - if(oldlevel < newlevel) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel); - else - if(oldlevel > newlevel) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel); - } - else - { - // update level and XP at level, all other will be updated at loading - Tokens values; - Player::LoadValuesArrayFromDB(values,chr_guid); - Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel); - Player::SetUInt32ValueInArray(values,PLAYER_XP,0); - Player::SaveValuesArrayInDB(values,chr_guid); - } - - if(m_session->GetPlayer() != chr) // including chr==NULL - { - std::string nameLink = playerLink(name); - PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel); - } - return true; -} - -bool ChatHandler::HandleShowAreaCommand(const char* args) -{ - if (!*args) - return false; - - Player *chr = getSelectedPlayer(); - if (chr == NULL) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - int area = GetAreaFlagByAreaID(atoi((char*)args)); - int offset = area / 32; - uint32 val = (uint32)(1 << (area % 32)); - - if(area<0 || offset >= 128) - { - SendSysMessage(LANG_BAD_VALUE); - SetSentErrorMessage(true); - return false; - } - - uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); - chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); - - SendSysMessage(LANG_EXPLORE_AREA); - return true; -} - -bool ChatHandler::HandleHideAreaCommand(const char* args) -{ - if (!*args) - return false; - - Player *chr = getSelectedPlayer(); - if (chr == NULL) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - int area = GetAreaFlagByAreaID(atoi((char*)args)); - int offset = area / 32; - uint32 val = (uint32)(1 << (area % 32)); - - if(area<0 || offset >= 128) - { - SendSysMessage(LANG_BAD_VALUE); - SetSentErrorMessage(true); - return false; - } - - uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); - chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val)); - - SendSysMessage(LANG_UNEXPLORE_AREA); - return true; -} - -bool ChatHandler::HandleDebugUpdate(const char* args) -{ - if(!*args) - return false; - - uint32 updateIndex; - uint32 value; - - char* pUpdateIndex = strtok((char*)args, " "); - - Unit* chr = getSelectedUnit(); - if (chr == NULL) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - if(!pUpdateIndex) - { - return true; - } - updateIndex = atoi(pUpdateIndex); - //check updateIndex - if(chr->GetTypeId() == TYPEID_PLAYER) - { - if (updateIndex>=PLAYER_END) return true; - } - else - { - if (updateIndex>=UNIT_END) return true; - } - - char* pvalue = strtok(NULL, " "); - if (!pvalue) - { - value=chr->GetUInt32Value(updateIndex); - - PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value); - return true; - } - - value=atoi(pvalue); - - PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value); - - chr->SetUInt32Value(updateIndex,value); - - return true; -} - -bool ChatHandler::HandleBankCommand(const char* /*args*/) -{ - m_session->SendShowBank( m_session->GetPlayer()->GetGUID() ); - - return true; -} - -bool ChatHandler::HandleChangeWeather(const char* args) -{ - if(!*args) - return false; - - //Weather is OFF - if (!sWorld.getConfig(CONFIG_WEATHER)) - { - SendSysMessage(LANG_WEATHER_DISABLED); - SetSentErrorMessage(true); - return false; - } - - //*Change the weather of a cell - char* px = strtok((char*)args, " "); - char* py = strtok(NULL, " "); - - if (!px || !py) - return false; - - uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand - float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather - - Player *player = m_session->GetPlayer(); - uint32 zoneid = player->GetZoneId(); - - Weather* wth = sWorld.FindWeather(zoneid); - - if(!wth) - wth = sWorld.AddWeather(zoneid); - if(!wth) - { - SendSysMessage(LANG_NO_WEATHER); - SetSentErrorMessage(true); - return false; - } - - wth->SetWeather(WeatherType(type), grade); - - return true; -} - -bool ChatHandler::HandleDebugSetValue(const char* args) -{ - if(!*args) - return false; - - char* px = strtok((char*)args, " "); - char* py = strtok(NULL, " "); - char* pz = strtok(NULL, " "); - - if (!px || !py) - return false; - - Unit* target = getSelectedUnit(); - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = target->GetGUID(); - - uint32 Opcode = (uint32)atoi(px); - if(Opcode >= target->GetValuesCount()) - { - PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); - return false; - } - uint32 iValue; - float fValue; - bool isint32 = true; - if(pz) - isint32 = (bool)atoi(pz); - if(isint32) - { - iValue = (uint32)atoi(py); - sLog.outDebug(GetTrinityString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue); - target->SetUInt32Value( Opcode , iValue ); - PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue); - } - else - { - fValue = (float)atof(py); - sLog.outDebug(GetTrinityString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue); - target->SetFloatValue( Opcode , fValue ); - PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue); - } - - return true; -} - -bool ChatHandler::HandleDebugGetValue(const char* args) -{ - if(!*args) - return false; - - char* px = strtok((char*)args, " "); - char* pz = strtok(NULL, " "); - - if (!px) - return false; - - Unit* target = getSelectedUnit(); - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = target->GetGUID(); - - uint32 Opcode = (uint32)atoi(px); - if(Opcode >= target->GetValuesCount()) - { - PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); - return false; - } - uint32 iValue; - float fValue; - bool isint32 = true; - if(pz) - isint32 = (bool)atoi(pz); - - if(isint32) - { - iValue = target->GetUInt32Value( Opcode ); - sLog.outDebug(GetTrinityString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue); - PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue); - } - else - { - fValue = target->GetFloatValue( Opcode ); - sLog.outDebug(GetTrinityString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue); - PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue); - } - - return true; -} - -bool ChatHandler::HandleDebugSet32Bit(const char* args) -{ - if(!*args) - return false; - - Unit* target = getSelectedUnit(); - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - char* px = strtok((char*)args, " "); - char* py = strtok(NULL, " "); - - if (!px || !py) - return false; - - uint32 Opcode = (uint32)atoi(px); - uint32 Value = (uint32)atoi(py); - if (Value > 32) //uint32 = 32 bits - return false; - - sLog.outDebug(GetTrinityString(LANG_SET_32BIT), Opcode, Value); - - uint32 iValue = Value ? 1 << (Value - 1) : 0; - target->SetUInt32Value( Opcode , iValue); - - PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode, iValue); - return true; -} - -bool ChatHandler::HandleDebugMod32Value(const char* args) -{ - if(!*args) - return false; - - char* px = strtok((char*)args, " "); - char* py = strtok(NULL, " "); - - if (!px || !py) - return false; - - uint32 Opcode = (uint32)atoi(px); - int Value = atoi(py); - - if(Opcode >= m_session->GetPlayer()->GetValuesCount()) - { - PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount()); - return false; - } - - sLog.outDebug(GetTrinityString(LANG_CHANGE_32BIT), Opcode, Value); - - int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode ); - - CurrentValue += Value; - m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue ); - - PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue); - - return true; -} - -bool ChatHandler::HandleTeleAddCommand(const char * args) -{ - if(!*args) - return false; - - Player *player=m_session->GetPlayer(); - if (!player) - return false; - - std::string name = args; - - if(objmgr.GetGameTele(name)) - { - SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST); - SetSentErrorMessage(true); - return false; - } - - GameTele tele; - tele.position_x = player->GetPositionX(); - tele.position_y = player->GetPositionY(); - tele.position_z = player->GetPositionZ(); - tele.orientation = player->GetOrientation(); - tele.mapId = player->GetMapId(); - tele.name = name; - - if(objmgr.AddGameTele(tele)) - { - SendSysMessage(LANG_COMMAND_TP_ADDED); - } - else - { - SendSysMessage(LANG_COMMAND_TP_ADDEDERR); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleTeleDelCommand(const char * args) -{ - if(!*args) - return false; - - std::string name = args; - - if(!objmgr.DeleteGameTele(name)) - { - SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); - SetSentErrorMessage(true); - return false; - } - - SendSysMessage(LANG_COMMAND_TP_DELETED); - return true; -} - -bool ChatHandler::HandleListAurasCommand (const char * /*args*/) -{ - Unit *unit = getSelectedUnit(); - if(!unit) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - char const* talentStr = GetTrinityString(LANG_TALENT); - char const* passiveStr = GetTrinityString(LANG_PASSIVE); - - Unit::AuraMap const& uAuras = unit->GetAuras(); - PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); - for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) - { - bool talent = GetTalentSpellCost(itr->second->GetId()) > 0; - - char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()]; - - if (m_session) - { - std::ostringstream ss_name; - ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r"; - - PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(), - itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(), - itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), - ss_name.str().c_str(), - (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), - IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); - } - else - { - PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(), - itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(), - itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), - name, - (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), - IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); - } - } - for (int i = 0; i < TOTAL_AURAS; i++) - { - Unit::AuraEffectList const& uAuraList = unit->GetAurasByType(AuraType(i)); - if (uAuraList.empty()) continue; - PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i); - for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr) - { - char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()]; - - std::ostringstream ss_name; - ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r"; - - PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), - (*itr)->GetAmount()); - } - } - return true; -} - -bool ChatHandler::HandleResetAchievementsCommand (const char * args) -{ - char* pName = strtok((char*)args, ""); - Player *player = NULL; - uint64 guid = 0; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - { - player = getSelectedPlayer(); - if(player) - guid = player->GetGUID(); - } - - if(!player && !guid) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - return true; - } - - if(player) - player->GetAchievementMgr().Reset(); - else if(guid) - AchievementMgr::DeleteFromDB(GUID_LOPART(guid)); - - return true; -} - -bool ChatHandler::HandleResetHonorCommand (const char * args) -{ - char* pName = strtok((char*)args, ""); - Player *player = NULL; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - return true; - } - - player->SetUInt32Value(PLAYER_FIELD_KILLS, 0); - player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); - player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0); - player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); - - return true; -} - -static bool HandleResetStatsOrLevelHelper(Player* player) -{ - PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); - if(!info) return false; - - ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass()); - if(!cEntry) - { - sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass()); - return false; - } - - uint8 powertype = cEntry->powerType; - - // reset m_form if no aura - if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) - player->m_form = FORM_NONE; - - player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); - player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH ); - - player->setFactionForRace(player->getRace()); - - player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) ); - - // reset only if player not in some form; - if(player->m_form==FORM_NONE) - { - switch(player->getGender()) - { - case GENDER_FEMALE: - player->SetDisplayId(info->displayId_f); - player->SetNativeDisplayId(info->displayId_f); - break; - case GENDER_MALE: - player->SetDisplayId(info->displayId_m); - player->SetNativeDisplayId(info->displayId_m); - break; - default: - break; - } - } - - player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP ); - player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form); - - player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - - //-1 is default value - player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); - - //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 ); - return true; -} - -bool ChatHandler::HandleResetLevelCommand(const char * args) -{ - char* pName = strtok((char*)args, ""); - Player *player = NULL; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if(!HandleResetStatsOrLevelHelper(player)) - return false; - - // set starting level - uint32 start_level = player->getClass() != CLASS_DEATH_KNIGHT - ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) - : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - - player->SetLevel(start_level); - player->InitRunes(); - player->InitStatsForLevel(true); - player->InitTaxiNodesForLevel(); - player->InitGlyphsForLevel(); - player->InitTalentForLevel(); - player->SetUInt32Value(PLAYER_XP,0); - - // reset level to summoned pet - Guardian* pet = player->GetGuardianPet(); - if(pet) - { - pet->InitStatsForLevel(1); - if(pet->isPet()) - ((Pet*)pet)->InitTalentForLevel(); - } - return true; -} - -bool ChatHandler::HandleResetStatsCommand(const char * args) -{ - char* pName = strtok((char*)args, ""); - Player *player = NULL; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if(!HandleResetStatsOrLevelHelper(player)) - return false; - - player->InitRunes(); - player->InitStatsForLevel(true); - player->InitTaxiNodesForLevel(); - player->InitGlyphsForLevel(); - player->InitTalentForLevel(); - - return true; -} - -bool ChatHandler::HandleResetSpellsCommand(const char * args) -{ - char* pName = strtok((char*)args, ""); - Player *player = NULL; - uint64 playerGUID = 0; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(name.c_str()); - if(!player) - playerGUID = objmgr.GetPlayerGUIDByName(name); - } - else - player = getSelectedPlayer(); - - if(!player && !playerGUID) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if(player) - { - player->resetSpells(); - - ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS); - if(m_session->GetPlayer()!=player) - PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(player).c_str()); - } - else - { - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID)); - PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName); - } - - return true; -} - -bool ChatHandler::HandleResetTalentsCommand(const char * args) -{ - char* pName = strtok((char*)args, ""); - Player *player = NULL; - uint64 playerGUID = 0; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(name.c_str()); - if(!player) - playerGUID = objmgr.GetPlayerGUIDByName(name); - } - else - player = getSelectedPlayer(); - - if(player) - { - player->resetTalents(true); - - ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS); - if(m_session->GetPlayer()!=player) - PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str()); - - return true; - } - else if (playerGUID) - { - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) ); - std::string nameLink = playerLink(pName); - PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str()); - return true; - } - // Try reset talenents as Hunter Pet - Creature* creature = getSelectedCreature(); - if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET) - { - ((Pet *)creature)->resetTalents(true); - Unit *owner = creature->GetOwner(); - if (owner && owner->GetTypeId() == TYPEID_PLAYER) - { - player = (Player *)owner; - ChatHandler(player).SendSysMessage(LANG_RESET_PET_TALENTS); - if(m_session->GetPlayer()!=player) - PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(player).c_str()); - } - return true; - } - - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; -} - -bool ChatHandler::HandleResetAllCommand(const char * args) -{ - if(!*args) - return false; - - std::string casename = args; - - AtLoginFlags atLogin; - - // Command specially created as single command to prevent using short case names - if(casename=="spells") - { - atLogin = AT_LOGIN_RESET_SPELLS; - sWorld.SendWorldText(LANG_RESETALL_SPELLS); - } - else if(casename=="talents") - { - atLogin = AT_LOGIN_RESET_TALENTS; - sWorld.SendWorldText(LANG_RESETALL_TALENTS); - } - else - { - PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args); - SetSentErrorMessage(true); - return false; - } - - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin); - HashMapHolder::MapType const& plist = ObjectAccessor::Instance().GetPlayers(); - for(HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) - itr->second->SetAtLoginFlag(atLogin); - - return true; -} - -bool ChatHandler::HandleServerShutDownCancelCommand(const char* args) -{ - sWorld.ShutdownCancel(); - return true; -} - -bool ChatHandler::HandleServerShutDownCommand(const char* args) -{ - if(!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld.ShutdownServ (time, 0, exitcode); - } - else - sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleServerRestartCommand(const char* args) -{ - if(!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode); - } - else - sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleServerIdleRestartCommand(const char* args) -{ - if(!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode); - } - else - sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleServerIdleShutDownCommand(const char* args) -{ - if(!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode); - } - else - sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleQuestAdd(const char* args) -{ - Player* player = getSelectedPlayer(); - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - // .addquest #entry' - // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args,"Hquest"); - if(!cId) - return false; - - uint32 entry = atol(cId); - - Quest const* pQuest = objmgr.GetQuestTemplate(entry); - - if(!pQuest) - { - PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry); - SetSentErrorMessage(true); - return false; - } - - // check item starting quest (it can work incorrectly if added without item in inventory) - for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) - { - ItemPrototype const *pProto = sItemStorage.LookupEntry(id); - if (!pProto) - continue; - - if (pProto->StartQuest == entry) - { - PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId); - SetSentErrorMessage(true); - return false; - } - } - - // ok, normal (creature/GO starting) quest - if( player->CanAddQuest( pQuest, true ) ) - { - player->AddQuest( pQuest, NULL ); - - if ( player->CanCompleteQuest( entry ) ) - player->CompleteQuest( entry ); - } - - return true; -} - -bool ChatHandler::HandleQuestRemove(const char* args) -{ - Player* player = getSelectedPlayer(); - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - // .removequest #entry' - // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args,"Hquest"); - if(!cId) - return false; - - uint32 entry = atol(cId); - - Quest const* pQuest = objmgr.GetQuestTemplate(entry); - - if(!pQuest) - { - PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); - SetSentErrorMessage(true); - return false; - } - - // remove all quest entries for 'entry' from quest log - for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot ) - { - uint32 quest = player->GetQuestSlotQuestId(slot); - if(quest==entry) - { - player->SetQuestSlot(slot,0); - - // we ignore unequippable quest items in this case, its' still be equipped - player->TakeQuestSourceItem( quest, false ); - } - } - - // set quest status to not started (will updated in DB at next save) - player->SetQuestStatus( entry, QUEST_STATUS_NONE); - - // reset rewarded for restart repeatable quest - player->getQuestStatusMap()[entry].m_rewarded = false; - - SendSysMessage(LANG_COMMAND_QUEST_REMOVED); - return true; -} - -bool ChatHandler::HandleQuestComplete(const char* args) -{ - Player* player = getSelectedPlayer(); - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - // .quest complete #entry - // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args,"Hquest"); - if(!cId) - return false; - - uint32 entry = atol(cId); - - Quest const* pQuest = objmgr.GetQuestTemplate(entry); - - // If player doesn't have the quest - if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) - { - PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); - SetSentErrorMessage(true); - return false; - } - - // Add quest items for quests that require items - for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x) - { - uint32 id = pQuest->ReqItemId[x]; - uint32 count = pQuest->ReqItemCount[x]; - if(!id || !count) - continue; - - uint32 curItemCount = player->GetItemCount(id,true); - - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount ); - if( msg == EQUIP_ERR_OK ) - { - Item* item = player->StoreNewItem( dest, id, true); - player->SendNewItem(item,count-curItemCount,true,false); - } - } - - // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10") - for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++) - { - uint32 creature = pQuest->ReqCreatureOrGOId[i]; - uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i]; - - if(uint32 spell_id = pQuest->ReqSpell[i]) - { - for(uint16 z = 0; z < creaturecount; ++z) - player->CastedCreatureOrGO(creature,0,spell_id); - } - else if(creature > 0) - { - for(uint16 z = 0; z < creaturecount; ++z) - player->KilledMonster(creature,0); - } - else if(creature < 0) - { - for(uint16 z = 0; z < creaturecount; ++z) - player->CastedCreatureOrGO(creature,0,0); - } - } - - // If the quest requires reputation to complete - if(uint32 repFaction = pQuest->GetRepObjectiveFaction()) - { - uint32 repValue = pQuest->GetRepObjectiveValue(); - uint32 curRep = player->GetReputationMgr().GetReputation(repFaction); - if(curRep < repValue) - if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction)) - player->GetReputationMgr().SetReputation(factionEntry,repValue); - } - - // If the quest requires money - int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney(); - if(ReqOrRewMoney < 0) - player->ModifyMoney(-ReqOrRewMoney); - - player->CompleteQuest(entry); - return true; -} - -bool ChatHandler::HandleBanAccountCommand(const char* args) -{ - return HandleBanHelper(BAN_ACCOUNT,args); -} - -bool ChatHandler::HandleBanCharacterCommand(const char* args) -{ - return HandleBanHelper(BAN_CHARACTER,args); -} - -bool ChatHandler::HandleBanIPCommand(const char* args) -{ - return HandleBanHelper(BAN_IP,args); -} - -bool ChatHandler::HandleBanHelper(BanMode mode, const char* args) -{ - if (!*args) - return false; - - char* cnameOrIP = strtok ((char*)args, " "); - if (!cnameOrIP) - return false; - - std::string nameOrIP = cnameOrIP; - - char* duration = strtok (NULL," "); - if(!duration || !atoi(duration)) - return false; - - char* reason = strtok (NULL,""); - if(!reason) - return false; - - switch(mode) - { - case BAN_ACCOUNT: - if(!AccountMgr::normilizeString(nameOrIP)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str()); - SetSentErrorMessage(true); - return false; - } - break; - case BAN_CHARACTER: - if(!normalizePlayerName(nameOrIP)) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - break; - case BAN_IP: - if(!IsIPAddress(nameOrIP.c_str())) - return false; - break; - } - - switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : "")) - { - case BAN_SUCCESS: - if(atoi(duration)>0) - PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason); - else - PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason); - break; - case BAN_SYNTAX_ERROR: - return false; - case BAN_NOTFOUND: - switch(mode) - { - default: - PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str()); - break; - case BAN_CHARACTER: - PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str()); - break; - case BAN_IP: - PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str()); - break; - } - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleUnBanAccountCommand(const char* args) -{ - return HandleUnBanHelper(BAN_ACCOUNT,args); -} - -bool ChatHandler::HandleUnBanCharacterCommand(const char* args) -{ - return HandleUnBanHelper(BAN_CHARACTER,args); -} - -bool ChatHandler::HandleUnBanIPCommand(const char* args) -{ - return HandleUnBanHelper(BAN_IP,args); -} - -bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args) -{ - if (!*args) - return false; - - char* cnameOrIP = strtok ((char*)args, " "); - if(!cnameOrIP) - return false; - - std::string nameOrIP = cnameOrIP; - - switch(mode) - { - case BAN_ACCOUNT: - if(!AccountMgr::normilizeString(nameOrIP)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str()); - SetSentErrorMessage(true); - return false; - } - break; - case BAN_CHARACTER: - if(!normalizePlayerName(nameOrIP)) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - break; - case BAN_IP: - if(!IsIPAddress(nameOrIP.c_str())) - return false; - break; - } - - if(sWorld.RemoveBanAccount(mode,nameOrIP)) - PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str()); - else - PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str()); - - return true; -} - -bool ChatHandler::HandleBanInfoAccountCommand(const char* args) -{ - if (!*args) - return false; - - char* cname = strtok((char*)args, ""); - if(!cname) - return false; - - std::string account_name = cname; - if(!AccountMgr::normilizeString(account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - uint32 accountid = accmgr.GetId(account_name); - if(!accountid) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - return true; - } - - return HandleBanInfoHelper(accountid,account_name.c_str()); -} - -bool ChatHandler::HandleBanInfoCharacterCommand(const char* args) -{ - if (!*args) - return false; - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name); - if(!accountid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - std::string accountname; - if(!accmgr.GetName(accountid,accountname)) - { - PSendSysMessage(LANG_BANINFO_NOCHARACTER); - return true; - } - - return HandleBanInfoHelper(accountid,accountname.c_str()); -} - -bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname) -{ - QueryResult *result = LoginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid); - if(!result) - { - PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname); - return true; - } - - PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname); - do - { - Field* fields = result->Fetch(); - - time_t unbandate = time_t(fields[3].GetUInt64()); - bool active = false; - if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) ) - active = true; - bool permanent = (fields[1].GetUInt64() == (uint64)0); - std::string bantime = permanent?GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true); - PSendSysMessage(LANG_BANINFO_HISTORYENTRY, - fields[0].GetString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES):GetTrinityString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString()); - }while (result->NextRow()); - - delete result; - return true; -} - -bool ChatHandler::HandleBanInfoIPCommand(const char* args) -{ - if (!*args) - return false; - - char* cIP = strtok ((char*)args, ""); - if(!cIP) - return false; - - if (!IsIPAddress(cIP)) - return false; - - std::string IP = cIP; - - LoginDatabase.escape_string(IP); - QueryResult *result = LoginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str()); - if(!result) - { - PSendSysMessage(LANG_BANINFO_NOIP); - return true; - } - - Field *fields = result->Fetch(); - bool permanent = !fields[6].GetUInt64(); - PSendSysMessage(LANG_BANINFO_IPENTRY, - fields[0].GetString(), fields[1].GetString(), permanent ? GetTrinityString(LANG_BANINFO_NEVER):fields[2].GetString(), - permanent ? GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString()); - delete result; - return true; -} - -bool ChatHandler::HandleBanListCharacterCommand(const char* args) -{ - LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - - char* cFilter = strtok ((char*)args, " "); - if(!cFilter) - return false; - - std::string filter = cFilter; - LoginDatabase.escape_string(filter); - QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str()); - if (!result) - { - PSendSysMessage(LANG_BANLIST_NOCHARACTER); - return true; - } - - return HandleBanListHelper(result); -} - -bool ChatHandler::HandleBanListAccountCommand(const char* args) -{ - LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - - char* cFilter = strtok((char*)args, " "); - std::string filter = cFilter ? cFilter : ""; - LoginDatabase.escape_string(filter); - - QueryResult* result; - - if(filter.empty()) - { - result = LoginDatabase.Query("SELECT account.id, username FROM account, account_banned" - " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id"); - } - else - { - result = LoginDatabase.PQuery("SELECT account.id, username FROM account, account_banned" - " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id", - filter.c_str()); - } - - if (!result) - { - PSendSysMessage(LANG_BANLIST_NOACCOUNT); - return true; - } - - return HandleBanListHelper(result); -} - -bool ChatHandler::HandleBanListHelper(QueryResult* result) -{ - PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); - - // Chat short output - if(m_session) - { - do - { - Field* fields = result->Fetch(); - uint32 accountid = fields[0].GetUInt32(); - - QueryResult* banresult = LoginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid); - if(banresult) - { - Field* fields2 = banresult->Fetch(); - PSendSysMessage("%s",fields2[0].GetString()); - delete banresult; - } - } while (result->NextRow()); - } - // Console wide output - else - { - SendSysMessage(LANG_BANLIST_ACCOUNTS); - SendSysMessage("==============================================================================="); - SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER); - do - { - SendSysMessage("-------------------------------------------------------------------------------"); - Field *fields = result->Fetch(); - uint32 account_id = fields[0].GetUInt32 (); - - std::string account_name; - - // "account" case, name can be get in same query - if(result->GetFieldCount() > 1) - account_name = fields[1].GetCppString(); - // "character" case, name need extract from another DB - else - accmgr.GetName (account_id,account_name); - - // No SQL injection. id is uint32. - QueryResult *banInfo = LoginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id); - if (banInfo) - { - Field *fields2 = banInfo->Fetch(); - do - { - time_t t_ban = fields2[0].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); - - if (fields2[0].GetUInt64() == fields2[1].GetUInt64()) - { - PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", - account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, - fields2[2].GetString(),fields2[3].GetString()); - } - else - { - time_t t_unban = fields2[1].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); - PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", - account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, - aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, - fields2[2].GetString(),fields2[3].GetString()); - } - }while ( banInfo->NextRow() ); - delete banInfo; - } - }while( result->NextRow() ); - SendSysMessage("==============================================================================="); - } - - delete result; - return true; -} - -bool ChatHandler::HandleBanListIPCommand(const char* args) -{ - LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - - char* cFilter = strtok((char*)args, " "); - std::string filter = cFilter ? cFilter : ""; - LoginDatabase.escape_string(filter); - - QueryResult* result; - - if(filter.empty()) - { - result = LoginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned" - " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())" - " ORDER BY unbandate" ); - } - else - { - result = LoginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned" - " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'") - " ORDER BY unbandate",filter.c_str() ); - } - - if(!result) - { - PSendSysMessage(LANG_BANLIST_NOIP); - return true; - } - - PSendSysMessage(LANG_BANLIST_MATCHINGIP); - // Chat short output - if(m_session) - { - do - { - Field* fields = result->Fetch(); - PSendSysMessage("%s",fields[0].GetString()); - } while (result->NextRow()); - } - // Console wide output - else - { - SendSysMessage(LANG_BANLIST_IPS); - SendSysMessage("==============================================================================="); - SendSysMessage(LANG_BANLIST_IPS_HEADER); - do - { - SendSysMessage("-------------------------------------------------------------------------------"); - Field *fields = result->Fetch(); - time_t t_ban = fields[1].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); - if ( fields[1].GetUInt64() == fields[2].GetUInt64() ) - { - PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", - fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, - fields[3].GetString(), fields[4].GetString()); - } - else - { - time_t t_unban = fields[2].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); - PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", - fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, - aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, - fields[3].GetString(), fields[4].GetString()); - } - }while( result->NextRow() ); - SendSysMessage("==============================================================================="); - } - - delete result; - return true; -} - -bool ChatHandler::HandleRespawnCommand(const char* /*args*/) -{ - Player* pl = m_session->GetPlayer(); - - // accept only explicitly selected target (not implicitly self targeting case) - Unit* target = getSelectedUnit(); - if(pl->GetSelection() && target) - { - if(target->GetTypeId()!=TYPEID_UNIT) - { - SendSysMessage(LANG_SELECT_CREATURE); - SetSentErrorMessage(true); - return false; - } - - if(target->isDead()) - ((Creature*)target)->Respawn(); - return true; - } - - CellPair p(Trinity::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - MaNGOS::RespawnDo u_do; - MaNGOS::WorldObjectWorker worker(pl,u_do); - - TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); - CellLock cell_lock(cell, p); - cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl)); - - return true; -} - -bool ChatHandler::HandleGMFlyCommand(const char* args) -{ - if (!*args) - return false; - - Player *target = getSelectedPlayer(); - if (!target) - target = m_session->GetPlayer(); - - WorldPacket data(12); - if (strncmp(args, "on", 3) == 0) - data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); - else if (strncmp(args, "off", 4) == 0) - data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); - else - { - SendSysMessage(LANG_USE_BOL); - return false; - } - data.append(target->GetPackGUID()); - data << uint32(0); // unknown - target->SendMessageToSet(&data, true); - PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args); - return true; -} - -bool ChatHandler::HandlePDumpLoadCommand(const char *args) -{ - if (!*args) - return false; - - char * file = strtok((char*)args, " "); - if(!file) - return false; - - char * account = strtok(NULL, " "); - if(!account) - return false; - - std::string account_name = account; - if(!AccountMgr::normilizeString(account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - uint32 account_id = accmgr.GetId(account_name); - if(!account_id) - { - account_id = atoi(account); // use original string - if(!account_id) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - } - - if(!accmgr.GetName(account_id,account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - char* guid_str = NULL; - char* name_str = strtok(NULL, " "); - - std::string name; - if(name_str) - { - name = name_str; - // normalize the name if specified and check if it exists - if(!normalizePlayerName(name)) - { - PSendSysMessage(LANG_INVALID_CHARACTER_NAME); - SetSentErrorMessage(true); - return false; - } - - if(!ObjectMgr::IsValidName(name,true)) - { - PSendSysMessage(LANG_INVALID_CHARACTER_NAME); - SetSentErrorMessage(true); - return false; - } - - guid_str = strtok(NULL, " "); - } - - uint32 guid = 0; - - if(guid_str) - { - guid = atoi(guid_str); - if(!guid) - { - PSendSysMessage(LANG_INVALID_CHARACTER_GUID); - SetSentErrorMessage(true); - return false; - } - - if(objmgr.GetPlayerAccountIdByGUID(guid)) - { - PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid); - SetSentErrorMessage(true); - return false; - } - } - - switch(PlayerDumpReader().LoadDump(file, account_id, name, guid)) - { - case DUMP_SUCCESS: - PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS); - break; - case DUMP_FILE_OPEN_ERROR: - PSendSysMessage(LANG_FILE_OPEN_FAIL,file); - SetSentErrorMessage(true); - return false; - case DUMP_FILE_BROKEN: - PSendSysMessage(LANG_DUMP_BROKEN,file); - SetSentErrorMessage(true); - return false; - case DUMP_TOO_MANY_CHARS: - PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id); - SetSentErrorMessage(true); - return false; - default: - PSendSysMessage(LANG_COMMAND_IMPORT_FAILED); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandlePDumpWriteCommand(const char *args) -{ - if (!*args) - return false; - - char* file = strtok((char*)args, " "); - char* p2 = strtok(NULL, " "); - - if(!file || !p2) - return false; - - uint32 guid; - // character name can't start from number - if (isNumeric(p2[0])) - guid = atoi(p2); - else - { - std::string name = extractPlayerNameFromLink(p2); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - guid = objmgr.GetPlayerGUIDByName(name); - } - - if(!objmgr.GetPlayerAccountIdByGUID(guid)) - { - PSendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - switch(PlayerDumpWriter().WriteDump(file, guid)) - { - case DUMP_SUCCESS: - PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS); - break; - case DUMP_FILE_OPEN_ERROR: - PSendSysMessage(LANG_FILE_OPEN_FAIL,file); - SetSentErrorMessage(true); - return false; - default: - PSendSysMessage(LANG_COMMAND_EXPORT_FAILED); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleMovegensCommand(const char* /*args*/) -{ - Unit* unit = getSelectedUnit(); - if(!unit) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow()); - - MotionMaster* mm = unit->GetMotionMaster(); - for(int i = 0; i < MAX_MOTION_SLOT; ++i) - { - MovementGenerator* mg = mm->GetMotionSlot(i); - if(!mg) - { - SendSysMessage("Empty"); - continue; - } - switch(mg->GetMovementGeneratorType()) - { - case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break; - case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break; - case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break; - case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break; - case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break; - case TARGETED_MOTION_TYPE: - { - if(unit->GetTypeId()==TYPEID_PLAYER) - { - TargetedMovementGenerator const* mgen = static_cast const*>(mg); - Unit* target = mgen->GetTarget(); - if(target) - PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow()); - else - SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); - } - else - { - TargetedMovementGenerator const* mgen = static_cast const*>(mg); - Unit* target = mgen->GetTarget(); - if(target) - PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow()); - else - SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); - } - break; - } - case HOME_MOTION_TYPE: - if(unit->GetTypeId()==TYPEID_UNIT) - { - float x,y,z; - mg->GetDestination(x,y,z); - PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z); - } - else - SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); - break; - case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break; - case POINT_MOTION_TYPE: - { - float x,y,z; - mg->GetDestination(x,y,z); - PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z); - break; - } - case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break; - case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break; - default: - PSendSysMessage(LANG_MOVEGENS_UNKNOWN,mg->GetMovementGeneratorType()); - break; - } - } - return true; -} - -bool ChatHandler::HandlePLimitCommand(const char *args) -{ - if(*args) - { - char* param = strtok((char*)args, " "); - if(!param) - return false; - - int l = strlen(param); - - if( strncmp(param,"player",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_PLAYER); - else if(strncmp(param,"moderator",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_MODERATOR); - else if(strncmp(param,"gamemaster",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_GAMEMASTER); - else if(strncmp(param,"administrator",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); - else if(strncmp(param,"reset",l) == 0 ) - sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) ); - else - { - int val = atoi(param); - if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR; - - sWorld.SetPlayerLimit(val); - } - - // kick all low security level players - if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER) - sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); - } - - uint32 pLimit = sWorld.GetPlayerAmountLimit(); - AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); - char const* secName = ""; - switch(allowedAccountType) - { - case SEC_PLAYER: secName = "Player"; break; - case SEC_MODERATOR: secName = "Moderator"; break; - case SEC_GAMEMASTER: secName = "Gamemaster"; break; - case SEC_ADMINISTRATOR: secName = "Administrator"; break; - default: secName = ""; break; - } - - PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName); - - return true; -} - -bool ChatHandler::HandleCastCommand(const char* args) -{ - if(!*args) - return false; - - Unit* target = getSelectedUnit(); - - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if(!spell) - return false; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if(!spellInfo) - return false; - - if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); - SetSentErrorMessage(true); - return false; - } - - char* trig_str = strtok(NULL, " "); - if(trig_str) - { - int l = strlen(trig_str); - if(strncmp(trig_str,"triggered",l) != 0 ) - return false; - } - - bool triggered = (trig_str != NULL); - - m_session->GetPlayer()->CastSpell(target,spell,triggered); - - return true; -} - -bool ChatHandler::HandleCastBackCommand(const char* args) -{ - Creature* caster = getSelectedCreature(); - - if(!caster) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if(!spell || !sSpellStore.LookupEntry(spell)) - return false; - - char* trig_str = strtok(NULL, " "); - if(trig_str) - { - int l = strlen(trig_str); - if(strncmp(trig_str,"triggered",l) != 0 ) - return false; - } - - bool triggered = (trig_str != NULL); - - // update orientation at server - caster->SetOrientation(caster->GetAngle(m_session->GetPlayer())); - - // and client - WorldPacket data; - caster->BuildHeartBeatMsg(&data); - caster->SendMessageToSet(&data,true); - - caster->CastSpell(m_session->GetPlayer(),spell,triggered); - - return true; -} - -bool ChatHandler::HandleCastDistCommand(const char* args) -{ - if(!*args) - return false; - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if(!spell) - return false; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if(!spellInfo) - return false; - - if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); - SetSentErrorMessage(true); - return false; - } - - char *distStr = strtok(NULL, " "); - - float dist = 0; - - if(distStr) - sscanf(distStr, "%f", &dist); - - char* trig_str = strtok(NULL, " "); - if(trig_str) - { - int l = strlen(trig_str); - if(strncmp(trig_str,"triggered",l) != 0 ) - return false; - } - - bool triggered = (trig_str != NULL); - - float x,y,z; - m_session->GetPlayer()->GetClosePoint(x,y,z,dist); - - m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered); - return true; -} - -bool ChatHandler::HandleCastTargetCommand(const char* args) -{ - Creature* caster = getSelectedCreature(); - - if(!caster) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - if(!caster->getVictim()) - { - SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if(!spell || !sSpellStore.LookupEntry(spell)) - return false; - - char* trig_str = strtok(NULL, " "); - if(trig_str) - { - int l = strlen(trig_str); - if(strncmp(trig_str,"triggered",l) != 0 ) - return false; - } - - bool triggered = (trig_str != NULL); - - // update orientation at server - caster->SetOrientation(caster->GetAngle(m_session->GetPlayer())); - - // and client - WorldPacket data; - caster->BuildHeartBeatMsg(&data); - caster->SendMessageToSet(&data,true); - - caster->CastSpell(caster->getVictim(),spell,triggered); - - return true; -} - -/* -ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator -Without this function 3rd party scripting library will get linking errors (unresolved external) -when attempting to use the PointMovementGenerator -*/ -bool ChatHandler::HandleComeToMeCommand(const char *args) -{ - char* newFlagStr = strtok((char*)args, " "); - - if(!newFlagStr) - return false; - - uint32 newFlags = (uint32)strtoul(newFlagStr, NULL, 0); - - Creature* caster = getSelectedCreature(); - if(!caster) - { - m_session->GetPlayer()->SetUnitMovementFlags(newFlags); - SendSysMessage(LANG_SELECT_CREATURE); - SetSentErrorMessage(true); - return false; - } - - caster->SetUnitMovementFlags(newFlags); - - Player* pl = m_session->GetPlayer(); - - caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ()); - return true; -} - -bool ChatHandler::HandleCastSelfCommand(const char* args) -{ - if(!*args) - return false; - - Unit* target = getSelectedUnit(); - - if(!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if(!spell) - return false; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if(!spellInfo) - return false; - - if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); - SetSentErrorMessage(true); - return false; - } - - target->CastSpell(target,spell,false); - - return true; -} - -std::string GetTimeString(uint32 time) -{ - uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE; - std::ostringstream ss; - if(days) ss << days << "d "; - if(hours) ss << hours << "h "; - ss << minute << "m"; - return ss.str(); -} - -bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) -{ - Player* player = getSelectedPlayer(); - if (!player) player = m_session->GetPlayer(); - uint32 counter = 0; - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) - { - Player::BoundInstancesMap &binds = player->GetBoundInstances(i); - for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr) - { - InstanceSave *save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; - } - } - PSendSysMessage("player binds: %d", counter); - counter = 0; - Group *group = player->GetGroup(); - if(group) - { - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) - { - Group::BoundInstancesMap &binds = group->GetBoundInstances(i); - for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr) - { - InstanceSave *save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; - } - } - } - PSendSysMessage("group binds: %d", counter); - - return true; -} - -bool ChatHandler::HandleInstanceUnbindCommand(const char* args) -{ - if(!*args) - return false; - - std::string cmd = args; - if(cmd == "all") - { - Player* player = getSelectedPlayer(); - if (!player) player = m_session->GetPlayer(); - uint32 counter = 0; - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) - { - Player::BoundInstancesMap &binds = player->GetBoundInstances(i); - for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) - { - if(itr->first != player->GetMapId()) - { - InstanceSave *save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); - player->UnbindInstance(itr, i); - counter++; - } - else - ++itr; - } - } - PSendSysMessage("instances unbound: %d", counter); - } - return true; -} - -bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/) -{ - PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances()); - PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances()); - PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves()); - PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal()); - PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal()); - return true; -} - -bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) -{ - Player* pl = m_session->GetPlayer(); - - Map* map = pl->GetMap(); - if (!map->IsDungeon()) - { - PSendSysMessage("Map is not a dungeon."); - SetSentErrorMessage(true); - return false; - } - - if (!((InstanceMap*)map)->GetInstanceData()) - { - PSendSysMessage("Map has no instance data."); - SetSentErrorMessage(true); - return false; - } - - ((InstanceMap*)map)->GetInstanceData()->SaveToDB(); - return true; -} - -/// Display the list of GMs -bool ChatHandler::HandleGMListFullCommand(const char* /*args*/) -{ - ///- Get the accounts with GM Level >0 - QueryResult *result = LoginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" ); - if(result) - { - SendSysMessage(LANG_GMLIST); - SendSysMessage("========================"); - SendSysMessage(LANG_GMLIST_HEADER); - SendSysMessage("========================"); - - ///- Circle through them. Display username and GM level - do - { - Field *fields = result->Fetch(); - PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString()); - }while( result->NextRow() ); - - PSendSysMessage("========================"); - delete result; - } - else - PSendSysMessage(LANG_GMLIST_EMPTY); - return true; -} - -/// Define the 'Message of the day' for the realm -bool ChatHandler::HandleServerSetMotdCommand(const char* args) -{ - sWorld.SetMotd(args); - PSendSysMessage(LANG_MOTD_NEW, args); - return true; -} - -/// Set whether we accept new clients -bool ChatHandler::HandleServerSetClosedCommand(const char* args) -{ - std::string arg = args; - - if(args == "on") - { - SendSysMessage(LANG_WORLD_CLOSED); - sWorld.SetClosed(true); - return true; - } - if(args == "off") - { - SendSysMessage(LANG_WORLD_OPENED); - sWorld.SetClosed(false); - return true; - } - - SendSysMessage(LANG_USE_BOL); - SetSentErrorMessage(true); - return false; -} - -/// Set/Unset the expansion level for an account -bool ChatHandler::HandleAccountSetAddonCommand(const char* args) -{ - ///- Get the command line arguments - char *szAcc = strtok((char*)args," "); - char *szExp = strtok(NULL," "); - - if(!szAcc) - return false; - - std::string account_name; - uint32 account_id; - - if(!szExp) - { - Player* player = getSelectedPlayer(); - if(!player) - return false; - - account_id = player->GetSession()->GetAccountId(); - accmgr.GetName(account_id,account_name); - szExp = szAcc; - } - else - { - ///- Convert Account name to Upper Format - account_name = szAcc; - if(!AccountMgr::normilizeString(account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - account_id = accmgr.GetId(account_name); - if(!account_id) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - } - - // Let set addon state only for lesser (strong) security level - // or to self account - if (m_session && m_session->GetAccountId () != account_id && - HasLowerSecurityAccount (NULL,account_id,true)) - return false; - - int lev=atoi(szExp); //get int anyway (0 if error) - if(lev < 0) - return false; - - // No SQL injection - LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id); - PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev); - return true; -} - -//Send items by mail -bool ChatHandler::HandleSendItemsCommand(const char* args) -{ - if(!*args) - return false; - - // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - char* tail1 = strtok(NULL, ""); - if(!tail1) - return false; - - char* msgSubject; - if(*tail1=='"') - msgSubject = strtok(tail1+1, "\""); - else - { - char* space = strtok(tail1, "\""); - if(!space) - return false; - msgSubject = strtok(NULL, "\""); - } - - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if(!tail2) - return false; - - char* msgText; - if(*tail2=='"') - msgText = strtok(tail2+1, "\""); - else - { - char* space = strtok(tail2, "\""); - if(!space) - return false; - msgText = strtok(NULL, "\""); - } - - if (!msgText) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // extract items - typedef std::pair ItemPair; - typedef std::list< ItemPair > ItemPairs; - ItemPairs items; - - // get all tail string - char* tail = strtok(NULL, ""); - - // get from tail next item str - while(char* itemStr = strtok(tail, " ")) - { - // and get new tail - tail = strtok(NULL, ""); - - // parse item str - char* itemIdStr = strtok(itemStr, ":"); - char* itemCountStr = strtok(NULL, " "); - - uint32 item_id = atoi(itemIdStr); - if(!item_id) - return false; - - ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id); - if(!item_proto) - { - PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); - SetSentErrorMessage(true); - return false; - } - - uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1; - if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)) - { - PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id); - SetSentErrorMessage(true); - return false; - } - - while(item_count > item_proto->GetMaxStackSize()) - { - items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize())); - item_count -= item_proto->GetMaxStackSize(); - } - - items.push_back(ItemPair(item_id,item_count)); - - if(items.size() > MAX_MAIL_ITEMS) - { - PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); - SetSentErrorMessage(true); - return false; - } - } - - uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); - if(!receiver_guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - // from console show not existed sender - uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; - - uint32 messagetype = MAIL_NORMAL; - uint32 stationery = MAIL_STATIONERY_GM; - uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; - - Player *receiver = objmgr.GetPlayer(receiver_guid); - - // fill mail - MailItemsInfo mi; // item list preparing - - for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) - { - if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0)) - { - item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted - mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); - } - } - - WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE); - - std::string nameLink = playerLink(name); - PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; -} - -///Send money by mail -bool ChatHandler::HandleSendMoneyCommand(const char* args) -{ - if (!*args) - return false; - - /// format: name "subject text" "mail text" money - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char* msgSubject; - if (*tail1=='"') - msgSubject = strtok(tail1+1, "\""); - else - { - char* space = strtok(tail1, "\""); - if (!space) - return false; - msgSubject = strtok(NULL, "\""); - } - - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char* msgText; - if (*tail2=='"') - msgText = strtok(tail2+1, "\""); - else - { - char* space = strtok(tail2, "\""); - if (!space) - return false; - msgText = strtok(NULL, "\""); - } - - if (!msgText) - return false; - - char* money_str = strtok(NULL, ""); - int32 money = money_str ? atoi(money_str) : 0; - if (money <= 0) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); - if (!receiver_guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - // from console show not existed sender - uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; - - uint32 messagetype = MAIL_NORMAL; - uint32 stationery = MAIL_STATIONERY_GM; - uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; - - Player *receiver = objmgr.GetPlayer(receiver_guid); - - WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE); - - std::string nameLink = playerLink(name); - PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; -} - -/// Send a message to a player in game -bool ChatHandler::HandleSendMessageCommand(const char* args) -{ - ///- Get the command line arguments - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - char* msg_str = strtok(NULL, ""); - if(!msg_str) - return false; - - ///- Find the player and check that he is not logging out. - Player *rPlayer = objmgr.GetPlayer(name.c_str()); - if(!rPlayer) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - if(rPlayer->GetSession()->isLogingOut()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - ///- Send the message - //Use SendAreaTriggerMessage for fastest delivery. - rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str); - rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); - - //Confirmation message - std::string nameLink = playerLink(name); - PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str); - return true; -} - -bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/) -{ - sBattleGroundMgr.DistributeArenaPoints(); - return true; -} - -bool ChatHandler::HandleModifyGenderCommand(const char *args) -{ - if(!*args) - return false; - - Player *player = getSelectedPlayer(); - - if(!player) - { - PSendSysMessage(LANG_NO_PLAYER); - SetSentErrorMessage(true); - return false; - } - - PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); - if(!info) - return false; - - char const* gender_str = (char*)args; - int gender_len = strlen(gender_str); - - Gender gender; - - if(!strncmp(gender_str, "male", gender_len)) // MALE - { - if(player->getGender() == GENDER_MALE) - return true; - - gender = GENDER_MALE; - } - else if (!strncmp(gender_str, "female", gender_len)) // FEMALE - { - if(player->getGender() == GENDER_FEMALE) - return true; - - gender = GENDER_FEMALE; - } - else - { - SendSysMessage(LANG_MUST_MALE_OR_FEMALE); - SetSentErrorMessage(true); - return false; - } - - // Set gender - player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); - player->SetByteValue(PLAYER_BYTES_3, 0, gender); - - // Change display ID - player->SetDisplayId(gender ? info->displayId_f : info->displayId_m); - player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m); - - char const* gender_full = gender ? "female" : "male"; - - PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full); - - if (needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str()); - - return true; -} - -/*------------------------------------------ - *-------------TRINITY---------------------- - *-------------------------------------*/ - -bool ChatHandler::HandlePlayAllCommand(const char* args) -{ - if(!*args) - return false; - - uint32 soundId = atoi((char*)args); - - if(!sSoundEntriesStore.LookupEntry(soundId)) - { - PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); - SetSentErrorMessage(true); - return false; - } - - WorldPacket data(SMSG_PLAY_SOUND, 4); - data << uint32(soundId) << m_session->GetPlayer()->GetGUID(); - sWorld.SendGlobalMessage(&data); - - PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); - return true; -} - -bool ChatHandler::HandleFreezeCommand(const char *args) -{ - std::string name; - Player* player; - char* TargetName = strtok((char*)args, " "); //get entered name - if (!TargetName) //if no name entered use target - { - player = getSelectedPlayer(); - if (player) //prevent crash with creature as target - { - name = player->GetName(); - normalizePlayerName(name); - } - } - else // if name entered - { - name = TargetName; - normalizePlayerName(name); - player = objmgr.GetPlayer(name.c_str()); //get player by name - } - - if (!player) - { - SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - - if (player==m_session->GetPlayer()) - { - SendSysMessage(LANG_COMMAND_FREEZE_ERROR); - return true; - } - - //effect - if ((player) && (!(player==m_session->GetPlayer()))) - { - PSendSysMessage(LANG_COMMAND_FREEZE,name.c_str()); - - //stop combat + make player unattackable + duel stop + stop some spells - player->setFaction(35); - player->CombatStop(); - if(player->IsNonMeleeSpellCasted(true)) - player->InterruptNonMeleeSpells(true); - player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - player->SetUInt32Value(PLAYER_DUEL_TEAM, 1); - - //if player class = hunter || warlock remove pet if alive - if((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) - { - if(Pet* pet = player->GetPet()) - { - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - // not let dismiss dead pet - if(pet && pet->isAlive()) - player->RemovePet(pet,PET_SAVE_NOT_IN_SLOT); - } - } - - //m_session->GetPlayer()->CastSpell(player,spellID,false); - SpellEntry const *spellInfo = sSpellStore.LookupEntry( 9454 ); - Aura *Aur = new Aura(spellInfo, 1, NULL, player); - player->AddAura(Aur); - - //save player - player->SaveToDB(); - } - return true; -} - -bool ChatHandler::HandleUnFreezeCommand(const char *args) -{ - std::string name; - Player* player; - char* TargetName = strtok((char*)args, " "); //get entered name - if (!TargetName) //if no name entered use target - { - player = getSelectedPlayer(); - if (player) //prevent crash with creature as target - { - name = player->GetName(); - } - } - - else // if name entered - { - name = TargetName; - normalizePlayerName(name); - player = objmgr.GetPlayer(name.c_str()); //get player by name - } - - //effect - if (player) - { - PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str()); - - //Reset player faction + allow combat + allow duels - player->setFactionForRace(player->getRace()); - player->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - //allow movement and spells - player->RemoveAurasDueToSpell(9454); - - //save player - player->SaveToDB(); - } - - if (!player) - { - if (TargetName) - { - //check for offline players - QueryResult *result = CharacterDatabase.PQuery("SELECT characters.guid FROM `characters` WHERE characters.name = '%s'",name.c_str()); - if(!result) - { - SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - //if player found: delete his freeze aura - Field *fields=result->Fetch(); - uint64 pguid = fields[0].GetUInt64(); - delete result; - CharacterDatabase.PQuery("DELETE FROM `character_aura` WHERE character_aura.spell = 9454 AND character_aura.guid = '%u'",pguid); - PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str()); - return true; - } - else - { - SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - } - - return true; -} - -bool ChatHandler::HandleListFreezeCommand(const char* args) -{ - //Get names from DB - QueryResult *result = CharacterDatabase.PQuery("SELECT characters.name FROM `characters` LEFT JOIN `character_aura` ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454"); - if(!result) - { - SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); - return true; - } - //Header of the names - PSendSysMessage(LANG_COMMAND_LIST_FREEZE); - - //Output of the results - do - { - Field *fields = result->Fetch(); - std::string fplayers = fields[0].GetCppString(); - PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS,fplayers.c_str()); - } while (result->NextRow()); - - delete result; - return true; -} - -bool ChatHandler::HandleGroupLeaderCommand(const char* args) -{ - Player* plr = NULL; - Group* group = NULL; - uint64 guid = 0; - char* cname = strtok((char*)args, " "); - - if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid)) - if(group && group->GetLeaderGUID() != guid) - group->ChangeLeader(guid); - - return true; -} - -bool ChatHandler::HandleGroupDisbandCommand(const char* args) -{ - Player* plr = NULL; - Group* group = NULL; - uint64 guid = 0; - char* cname = strtok((char*)args, " "); - - if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid)) - if(group) - group->Disband(); - - return true; -} - -bool ChatHandler::HandleGroupRemoveCommand(const char* args) -{ - Player* plr = NULL; - Group* group = NULL; - uint64 guid = 0; - char* cname = strtok((char*)args, " "); - - if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid, true)) - if(group) - group->RemoveMember(guid, 0); - - return true; -} - -bool ChatHandler::HandlePossessCommand(const char* args) -{ - Unit* pUnit = getSelectedUnit(); - if(!pUnit) - return false; - - m_session->GetPlayer()->CastSpell(pUnit, 530, true); - return true; -} - -bool ChatHandler::HandleUnPossessCommand(const char* args) -{ - Unit* pUnit = getSelectedUnit(); - if(!pUnit) pUnit = m_session->GetPlayer(); - - pUnit->RemoveAurasByType(SPELL_AURA_MOD_CHARM); - pUnit->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET); - pUnit->RemoveAurasByType(SPELL_AURA_MOD_POSSESS); - - return true; -} - -bool ChatHandler::HandleBindSightCommand(const char* args) -{ - Unit* pUnit = getSelectedUnit(); - if (!pUnit) - return false; - - m_session->GetPlayer()->CastSpell(pUnit, 6277, true); - return true; -} - -bool ChatHandler::HandleUnbindSightCommand(const char* args) -{ - if (m_session->GetPlayer()->isPossessing()) - return false; - - m_session->GetPlayer()->StopCastingBindSight(); - return true; -} - +/* +* Copyright (C) 2005-2009 MaNGOS +* +* Copyright (C) 2008-2009 Trinity +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectMgr.h" +#include "AuctionHouseMgr.h" +#include "AccountMgr.h" +#include "PlayerDump.h" +#include "SpellMgr.h" +#include "Player.h" +#include "Opcodes.h" +#include "GameObject.h" +#include "Chat.h" +#include "Log.h" +#include "Guild.h" +#include "ObjectAccessor.h" +#include "MapManager.h" +#include "ScriptCalls.h" +#include "Language.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" +#include "Weather.h" +#include "PointMovementGenerator.h" +#include "TargetedMovementGenerator.h" +#include "SkillDiscovery.h" +#include "SkillExtraItems.h" +#include "SystemConfig.h" +#include "Config/ConfigEnv.h" +#include "Util.h" +#include "ItemEnchantmentMgr.h" +#include "BattleGroundMgr.h" +#include "InstanceSaveMgr.h" +#include "InstanceData.h" +#include "AuctionHouseBot.h" + +bool ChatHandler::HandleAHBotOptionsCommand(const char* args) +{ + uint32 ahMapID = 0; + char * opt = strtok((char*)args, " "); + char * ahMapIdStr = strtok(NULL, " "); + if (ahMapIdStr) + { + ahMapID = (uint32) strtoul(ahMapIdStr, NULL, 0); + } + if (!opt) + { + PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter"); + PSendSysMessage("Try ahbotoptions help to see a list of options."); + return false; + } + int l = strlen(opt); + + if (strncmp(opt,"help",l) == 0) + { + PSendSysMessage("AHBot commands:"); + PSendSysMessage("ahexpire"); + PSendSysMessage("minitems"); + PSendSysMessage("maxitems"); + PSendSysMessage("mintime"); + PSendSysMessage("maxtime"); + PSendSysMessage("percentages"); + PSendSysMessage("minprice"); + PSendSysMessage("maxprice"); + PSendSysMessage("minbidprice"); + PSendSysMessage("maxbidprice"); + PSendSysMessage("maxstack"); + PSendSysMessage("buyerprice"); + PSendSysMessage("bidinterval"); + PSendSysMessage("bidsperinterval"); + return true; + } + else if (strncmp(opt,"ahexpire",l) == 0) + { + if (!ahMapIdStr) + { + PSendSysMessage("Syntax is: ahbotoptions ahexpire $ahMapID (2, 6 or 7)"); + return false; + } + AuctionHouseBotCommands(0, ahMapID, NULL, NULL); + } + else if (strncmp(opt,"minitems",l) == 0) + { + char * param1 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1)) + { + PSendSysMessage("Syntax is: ahbotoptions minitems $ahMapID (2, 6 or 7) $minItems"); + return false; + } + AuctionHouseBotCommands(1, ahMapID, NULL, param1); + } + else if (strncmp(opt,"maxitems",l) == 0) + { + char * param1 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1)) + { + PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems"); + return false; + } + AuctionHouseBotCommands(2, ahMapID, NULL, param1); + } + else if (strncmp(opt,"mintime",l) == 0) + { + char * param1 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1)) + { + PSendSysMessage("Syntax is: ahbotoptions mintime $ahMapID (2, 6 or 7) $mintime"); + return false; + } + AuctionHouseBotCommands(3, ahMapID, NULL, param1); + } + else if (strncmp(opt,"maxtime",l) == 0) + { + char * param1 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1)) + { + PSendSysMessage("Syntax is: ahbotoptions maxtime $ahMapID (2, 6 or 7) $maxtime"); + return false; + } + AuctionHouseBotCommands(4, ahMapID, NULL, param1); + } + else if (strncmp(opt,"percentages",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + char * param3 = strtok(NULL, " "); + char * param4 = strtok(NULL, " "); + char * param5 = strtok(NULL, " "); + char * param6 = strtok(NULL, " "); + char * param7 = strtok(NULL, " "); + char * param8 = strtok(NULL, " "); + char * param9 = strtok(NULL, " "); + char * param10 = strtok(NULL, " "); + char * param11 = strtok(NULL, " "); + char * param12 = strtok(NULL, " "); + char * param13 = strtok(NULL, " "); + char * param14 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param14)) + { + PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14"); + PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); + PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); + PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); + PSendSysMessage("The total must add up to 100%"); + return false; + } + uint32 greytg = (uint32) strtoul(param1, NULL, 0); + uint32 whitetg = (uint32) strtoul(param2, NULL, 0); + uint32 greentg = (uint32) strtoul(param3, NULL, 0); + uint32 bluetg = (uint32) strtoul(param3, NULL, 0); + uint32 purpletg = (uint32) strtoul(param5, NULL, 0); + uint32 orangetg = (uint32) strtoul(param6, NULL, 0); + uint32 yellowtg = (uint32) strtoul(param7, NULL, 0); + uint32 greyi = (uint32) strtoul(param8, NULL, 0); + uint32 whitei = (uint32) strtoul(param9, NULL, 0); + uint32 greeni = (uint32) strtoul(param10, NULL, 0); + uint32 bluei = (uint32) strtoul(param11, NULL, 0); + uint32 purplei = (uint32) strtoul(param12, NULL, 0); + uint32 orangei = (uint32) strtoul(param13, NULL, 0); + uint32 yellowi = (uint32) strtoul(param14, NULL, 0); + uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi; + if ((totalPercent == 0) || (totalPercent != 100)) + { + PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14"); + PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); + PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); + PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); + PSendSysMessage("The total must add up to 100%"); + return false; + } + char param[100]; + param[0] = '\0'; + strcat(param, param1); + strcat(param, " "); + strcat(param, param2); + strcat(param, " "); + strcat(param, param3); + strcat(param, " "); + strcat(param, param4); + strcat(param, " "); + strcat(param, param5); + strcat(param, " "); + strcat(param, param6); + strcat(param, " "); + strcat(param, param7); + strcat(param, " "); + strcat(param, param8); + strcat(param, " "); + strcat(param, param9); + strcat(param, " "); + strcat(param, param10); + strcat(param, " "); + strcat(param, param11); + strcat(param, " "); + strcat(param, param12); + strcat(param, " "); + strcat(param, param13); + strcat(param, " "); + strcat(param, param14); + AuctionHouseBotCommands(5, ahMapID, NULL, param); + } + else if (strncmp(opt,"minprice",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1) || (!param2)) + { + PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + if (strncmp(param1,"grey",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_GREY, param2); + } + else if (strncmp(param1,"white",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_WHITE, param2); + } + else if (strncmp(param1,"green",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_GREEN, param2); + } + else if (strncmp(param1,"blue",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_BLUE, param2); + } + else if (strncmp(param1,"purple",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_PURPLE, param2); + } + else if (strncmp(param1,"orange",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_ORANGE, param2); + } + else if (strncmp(param1,"yellow",l) == 0) + { + AuctionHouseBotCommands(6, ahMapID, AHB_YELLOW, param2); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + } + else if (strncmp(opt,"maxprice",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1) || (!param2)) + { + PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + if (strncmp(param1,"grey",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_GREY, param2); + } + else if (strncmp(param1,"white",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_WHITE, param2); + } + else if (strncmp(param1,"green",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_GREEN, param2); + } + else if (strncmp(param1,"blue",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_BLUE, param2); + } + else if (strncmp(param1,"purple",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_PURPLE, param2); + } + else if (strncmp(param1,"orange",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_ORANGE, param2); + } + else if (strncmp(param1,"yellow",l) == 0) + { + AuctionHouseBotCommands(7, ahMapID, AHB_YELLOW, param2); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + } + else if (strncmp(opt,"minbidprice",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1) || (!param2)) + { + PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + uint32 minBidPrice = (uint32) strtoul(param2, NULL, 0); + if ((minBidPrice < 1) || (minBidPrice > 100)) + { + PSendSysMessage("The min bid price multiplier must be between 1 and 100"); + return false; + } + if (strncmp(param1,"grey",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_GREY, param2); + } + else if (strncmp(param1,"white",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_WHITE, param2); + } + else if (strncmp(param1,"green",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_GREEN, param2); + } + else if (strncmp(param1,"blue",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_BLUE, param2); + } + else if (strncmp(param1,"purple",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_PURPLE, param2); + } + else if (strncmp(param1,"orange",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_ORANGE, param2); + } + else if (strncmp(param1,"yellow",l) == 0) + { + AuctionHouseBotCommands(8, ahMapID, AHB_YELLOW, param2); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + } + else if (strncmp(opt,"maxbidprice",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1) || (!param2)) + { + PSendSysMessage("Syntax is: ahbotoptions maxbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + uint32 maxBidPrice = (uint32) strtoul(param2, NULL, 0); + if ((maxBidPrice < 1) || (maxBidPrice > 100)) + { + PSendSysMessage("The max bid price multiplier must be between 1 and 100"); + return false; + } + if (strncmp(param1,"grey",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_GREY, param2); + } + else if (strncmp(param1,"white",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_WHITE, param2); + } + else if (strncmp(param1,"green",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_GREEN, param2); + } + else if (strncmp(param1,"blue",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_BLUE, param2); + } + else if (strncmp(param1,"purple",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_PURPLE, param2); + } + else if (strncmp(param1,"orange",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_ORANGE, param2); + } + else if (strncmp(param1,"yellow",l) == 0) + { + AuctionHouseBotCommands(9, ahMapID, AHB_YELLOW, param2); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions max bidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); + return false; + } + } + else if (strncmp(opt,"maxstack",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1) || (!param2)) + { + PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); + return false; + } + uint32 maxStack = (uint32) strtoul(param2, NULL, 0); + if (maxStack < 0) + { + PSendSysMessage("maxstack can't be a negative number."); + return false; + } + if (strncmp(param1,"grey",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_GREY, param2); + } + else if (strncmp(param1,"white",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_WHITE, param2); + } + else if (strncmp(param1,"green",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_GREEN, param2); + } + else if (strncmp(param1,"blue",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_BLUE, param2); + } + else if (strncmp(param1,"purple",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_PURPLE, param2); + } + else if (strncmp(param1,"orange",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_ORANGE, param2); + } + else if (strncmp(param1,"yellow",l) == 0) + { + AuctionHouseBotCommands(10, ahMapID, AHB_YELLOW, param2); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); + return false; + } + } + else if (strncmp(opt,"buyerprice",l) == 0) + { + char * param1 = strtok(NULL, " "); + char * param2 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1) || (!param2)) + { + PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); + return false; + } + if (strncmp(param1,"grey",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_GREY, param2); + } + else if (strncmp(param1,"white",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_WHITE, param2); + } + else if (strncmp(param1,"green",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_GREEN, param2); + } + else if (strncmp(param1,"blue",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_BLUE, param2); + } + else if (strncmp(param1,"purple",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_PURPLE, param2); + } + else if (strncmp(param1,"orange",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_ORANGE, param2); + } + else if (strncmp(param1,"yellow",l) == 0) + { + AuctionHouseBotCommands(11, ahMapID, AHB_YELLOW, param2); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); + return false; + } + } + else if (strncmp(opt,"bidinterval",l) == 0) + { + char * param1 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1)) + { + PSendSysMessage("Syntax is: ahbotoptions bidinterval $ahMapID (2, 6 or 7) $interval(in minutes)"); + return false; + } + AuctionHouseBotCommands(12, ahMapID, NULL, param1); + } + else if (strncmp(opt,"bidsperinterval",l) == 0) + { + char * param1 = strtok(NULL, " "); + if ((!ahMapIdStr) || (!param1)) + { + PSendSysMessage("Syntax is: ahbotoptions bidsperinterval $ahMapID (2, 6 or 7) $bids"); + return false; + } + AuctionHouseBotCommands(13, ahMapID, NULL, param1); + } + else + { + PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter"); + PSendSysMessage("Try ahbotoptions help to see a list of options."); + return false; + } + return true; +} + +//reload commands +bool ChatHandler::HandleReloadAllCommand(const char*) +{ + HandleReloadSkillFishingBaseLevelCommand(""); + + HandleReloadAllAreaCommand(""); + HandleReloadAllLootCommand(""); + HandleReloadAllNpcCommand(""); + HandleReloadAllQuestCommand(""); + HandleReloadAllSpellCommand(""); + HandleReloadAllItemCommand(""); + HandleReloadAllLocalesCommand(""); + + HandleReloadCommandCommand(""); + HandleReloadReservedNameCommand(""); + HandleReloadTrinityStringCommand(""); + HandleReloadGameTeleCommand(""); + return true; +} + +bool ChatHandler::HandleReloadAllAreaCommand(const char*) +{ + //HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand + HandleReloadAreaTriggerTeleportCommand(""); + HandleReloadAreaTriggerTavernCommand(""); + HandleReloadGameGraveyardZoneCommand(""); + return true; +} + +bool ChatHandler::HandleReloadAllLootCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables..." ); + LoadLootTables(); + SendGlobalGMSysMessage("DB tables `*_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/) +{ + HandleReloadNpcGossipCommand("a"); + HandleReloadNpcOptionCommand("a"); + HandleReloadNpcTrainerCommand("a"); + HandleReloadNpcVendorCommand("a"); + HandleReloadPointsOfInterestCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllQuestCommand(const char* /*args*/) +{ + HandleReloadQuestAreaTriggersCommand("a"); + HandleReloadQuestTemplateCommand("a"); + + sLog.outString( "Re-Loading Quests Relations..." ); + objmgr.LoadQuestRelations(); + SendGlobalGMSysMessage("DB tables `*_questrelation` and `*_involvedrelation` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAllScriptsCommand(const char*) +{ + if(sWorld.IsScriptScheduled()) + { + PSendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + sLog.outString( "Re-Loading Scripts..." ); + HandleReloadGameObjectScriptsCommand("a"); + HandleReloadEventScriptsCommand("a"); + HandleReloadQuestEndScriptsCommand("a"); + HandleReloadQuestStartScriptsCommand("a"); + HandleReloadSpellScriptsCommand("a"); + SendGlobalGMSysMessage("DB tables `*_scripts` reloaded."); + HandleReloadDbScriptStringCommand("a"); + HandleReloadWpScriptsCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllSpellCommand(const char*) +{ + HandleReloadSkillDiscoveryTemplateCommand("a"); + HandleReloadSkillExtraItemTemplateCommand("a"); + HandleReloadSpellAffectCommand("a"); + HandleReloadSpellRequiredCommand("a"); + HandleReloadSpellAreaCommand("a"); + HandleReloadSpellElixirCommand("a"); + HandleReloadSpellLearnSpellCommand("a"); + HandleReloadSpellLinkedSpellCommand("a"); + HandleReloadSpellProcEventCommand("a"); + HandleReloadSpellBonusesCommand("a"); + HandleReloadSpellScriptTargetCommand("a"); + HandleReloadSpellTargetPositionCommand("a"); + HandleReloadSpellThreatsCommand("a"); + HandleReloadSpellPetAurasCommand("a"); + HandleReloadSpellDisabledCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllItemCommand(const char*) +{ + HandleReloadPageTextsCommand("a"); + HandleReloadItemEnchantementsCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/) +{ + HandleReloadLocalesCreatureCommand("a"); + HandleReloadLocalesGameobjectCommand("a"); + HandleReloadLocalesItemCommand("a"); + HandleReloadLocalesNpcTextCommand("a"); + HandleReloadLocalesPageTextCommand("a"); + HandleReloadLocalesPointsOfInterestCommand("a"); + HandleReloadLocalesQuestCommand("a"); + return true; +} + +bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading config settings..." ); + sWorld.LoadConfigSettings(true); + SendGlobalGMSysMessage("World config settings reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*) +{ + sLog.outString( "Re-Loading Tavern Area Triggers..." ); + objmgr.LoadTavernAreaTriggers(); + SendGlobalGMSysMessage("DB table `areatrigger_tavern` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAreaTriggerTeleportCommand(const char*) +{ + sLog.outString( "Re-Loading AreaTrigger teleport definitions..." ); + objmgr.LoadAreaTriggerTeleports(); + SendGlobalGMSysMessage("DB table `areatrigger_teleport` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadAccessRequirementCommand(const char*) +{ + sLog.outString( "Re-Loading Access Requirement definitions..." ); + objmgr.LoadAccessRequirements(); + SendGlobalGMSysMessage("DB table `access_requirement` reloaded."); + return true; + } + +bool ChatHandler::HandleReloadCommandCommand(const char*) +{ + load_command_table = true; + SendGlobalGMSysMessage("DB table `command` will be reloaded at next chat command use."); + return true; +} + +bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`creature_questrelation`)" ); + objmgr.LoadCreatureQuestRelations(); + SendGlobalGMSysMessage("DB table `creature_questrelation` (creature quest givers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" ); + objmgr.LoadCreatureInvolvedRelations(); + SendGlobalGMSysMessage("DB table `creature_involvedrelation` (creature quest takers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" ); + objmgr.LoadGameobjectQuestRelations(); + SendGlobalGMSysMessage("DB table `gameobject_questrelation` (gameobject quest givers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGOQuestInvRelationsCommand(const char*) +{ + sLog.outString( "Loading Quests Relations... (`gameobject_involvedrelation`)" ); + objmgr.LoadGameobjectInvolvedRelations(); + SendGlobalGMSysMessage("DB table `gameobject_involvedrelation` (gameobject quest takers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadQuestAreaTriggersCommand(const char*) +{ + sLog.outString( "Re-Loading Quest Area Triggers..." ); + objmgr.LoadQuestAreaTriggers(); + SendGlobalGMSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadQuestTemplateCommand(const char*) +{ + sLog.outString( "Re-Loading Quest Templates..." ); + objmgr.LoadQuests(); + SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded."); + + /// dependent also from `gameobject` but this table not reloaded anyway + sLog.outString( "Re-Loading GameObjects for quests..." ); + objmgr.LoadGameObjectForQuests(); + SendGlobalGMSysMessage("Data GameObjects for quests reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesCreatureCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`creature_loot_template`)" ); + LoadLootTemplates_Creature(); + LootTemplates_Creature.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `creature_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesDisenchantCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`disenchant_loot_template`)" ); + LoadLootTemplates_Disenchant(); + LootTemplates_Disenchant.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `disenchant_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesFishingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`fishing_loot_template`)" ); + LoadLootTemplates_Fishing(); + LootTemplates_Fishing.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `fishing_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesGameobjectCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`gameobject_loot_template`)" ); + LoadLootTemplates_Gameobject(); + LootTemplates_Gameobject.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `gameobject_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`item_loot_template`)" ); + LoadLootTemplates_Item(); + LootTemplates_Item.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `item_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" ); + LoadLootTemplates_Milling(); + LootTemplates_Milling.CheckLootRefs(); + SendGlobalSysMessage("DB table `milling_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" ); + LoadLootTemplates_Pickpocketing(); + LootTemplates_Pickpocketing.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `pickpocketing_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`prospecting_loot_template`)" ); + LoadLootTemplates_Prospecting(); + LootTemplates_Prospecting.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `prospecting_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" ); + LoadLootTemplates_QuestMail(); + LootTemplates_QuestMail.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `quest_mail_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesReferenceCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`reference_loot_template`)" ); + LoadLootTemplates_Reference(); + SendGlobalGMSysMessage("DB table `reference_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`skinning_loot_template`)" ); + LoadLootTemplates_Skinning(); + LootTemplates_Skinning.CheckLootRefs(); + SendGlobalGMSysMessage("DB table `skinning_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" ); + LoadLootTemplates_Spell(); + LootTemplates_Spell.CheckLootRefs(); + SendGlobalSysMessage("DB table `spell_loot_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadTrinityStringCommand(const char*) +{ + sLog.outString( "Re-Loading trinity_string Table!" ); + objmgr.LoadTrinityStrings(); + SendGlobalGMSysMessage("DB table `trinity_string` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcOptionCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_option` Table!" ); + objmgr.LoadNpcOptions(); + SendGlobalGMSysMessage("DB table `npc_option` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcGossipCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_gossip` Table!" ); + objmgr.LoadNpcTextId(); + SendGlobalGMSysMessage("DB table `npc_gossip` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcTrainerCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_trainer` Table!" ); + objmgr.LoadTrainerSpell(); + SendGlobalGMSysMessage("DB table `npc_trainer` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadNpcVendorCommand(const char*) +{ + sLog.outString( "Re-Loading `npc_vendor` Table!" ); + objmgr.LoadVendors(); + SendGlobalGMSysMessage("DB table `npc_vendor` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadPointsOfInterestCommand(const char*) +{ + sLog.outString( "Re-Loading `points_of_interest` Table!" ); + objmgr.LoadPointsOfInterest(); + SendGlobalSysMessage("DB table `points_of_interest` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadReservedNameCommand(const char*) +{ + sLog.outString( "Loading ReservedNames... (`reserved_name`)" ); + objmgr.LoadReservedPlayersNames(); + SendGlobalGMSysMessage("DB table `reserved_name` (player reserved names) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSkillDiscoveryTemplateCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading Skill Discovery Table..." ); + LoadSkillDiscoveryTable(); + SendGlobalGMSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSkillExtraItemTemplateCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading Skill Extra Item Table..." ); + LoadSkillExtraItemTable(); + SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSkillFishingBaseLevelCommand(const char* /*args*/) +{ + sLog.outString( "Re-Loading Skill Fishing base level requirements..." ); + objmgr.LoadFishingBaseSkillLevel(); + SendGlobalGMSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellAffectCommand(const char*) +{ + sLog.outString( "Re-Loading SpellAffect definitions..." ); + spellmgr.LoadSpellAffects(); + SendGlobalGMSysMessage("DB table `spell_affect` (spell mods apply requirements) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellAreaCommand(const char*) +{ + sLog.outString( "Re-Loading SpellArea Data..." ); + spellmgr.LoadSpellAreas(); + SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellRequiredCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Required Data... " ); + spellmgr.LoadSpellRequired(); + SendGlobalGMSysMessage("DB table `spell_required` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellElixirCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Elixir types..." ); + spellmgr.LoadSpellElixirs(); + SendGlobalGMSysMessage("DB table `spell_elixir` (spell elixir types) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellLearnSpellCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Learn Spells..." ); + spellmgr.LoadSpellLearnSpells(); + SendGlobalGMSysMessage("DB table `spell_learn_spell` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellLinkedSpellCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Linked Spells..." ); + spellmgr.LoadSpellLinked(); + SendGlobalGMSysMessage("DB table `spell_linked_spell` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellProcEventCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Proc Event conditions..." ); + spellmgr.LoadSpellProcEvents(); + SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellBonusesCommand(const char*) +{ + sLog.outString( "Re-Loading Spell Bonus Data..." ); + spellmgr.LoadSpellBonusess(); + SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*) +{ + sLog.outString( "Re-Loading SpellsScriptTarget..." ); + spellmgr.LoadSpellScriptTarget(); + SendGlobalGMSysMessage("DB table `spell_script_target` (spell targets selection in case specific creature/GO requirements) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellTargetPositionCommand(const char*) +{ + sLog.outString( "Re-Loading Spell target coordinates..." ); + spellmgr.LoadSpellTargetPositions(); + SendGlobalGMSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellThreatsCommand(const char*) +{ + sLog.outString( "Re-Loading Aggro Spells Definitions..."); + spellmgr.LoadSpellThreats(); + SendGlobalGMSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded."); + return true; +} + +bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*) +{ + sLog.outString( "Re-Loading Spell pet auras..."); + spellmgr.LoadSpellPetAuras(); + SendGlobalGMSysMessage("DB table `spell_pet_auras` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadPageTextsCommand(const char*) +{ + sLog.outString( "Re-Loading Page Texts..." ); + objmgr.LoadPageTexts(); + SendGlobalGMSysMessage("DB table `page_texts` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*) +{ + sLog.outString( "Re-Loading Item Random Enchantments Table..." ); + LoadRandomEnchantmentsTable(); + SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `gameobject_scripts`..."); + + objmgr.LoadGameObjectScripts(); + + if(*arg!='a') + SendGlobalGMSysMessage("DB table `gameobject_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `event_scripts`..."); + + objmgr.LoadEventScripts(); + + if(*arg!='a') + SendGlobalGMSysMessage("DB table `event_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadWpScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `waypoint_scripts`..."); + + objmgr.LoadWaypointScripts(); + + if(*arg!='a') + SendGlobalGMSysMessage("DB table `waypoint_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `quest_end_scripts`..."); + + objmgr.LoadQuestEndScripts(); + + if(*arg!='a') + SendGlobalGMSysMessage("DB table `quest_end_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadQuestStartScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `quest_start_scripts`..."); + + objmgr.LoadQuestStartScripts(); + + if(*arg!='a') + SendGlobalGMSysMessage("DB table `quest_start_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg) +{ + if(sWorld.IsScriptScheduled()) + { + SendSysMessage("DB scripts used currently, please attempt reload later."); + SetSentErrorMessage(true); + return false; + } + + if(*arg!='a') + sLog.outString( "Re-Loading Scripts from `spell_scripts`..."); + + objmgr.LoadSpellScripts(); + + if(*arg!='a') + SendGlobalGMSysMessage("DB table `spell_scripts` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg) +{ + sLog.outString( "Re-Loading Script strings from `db_script_string`..."); + objmgr.LoadDbScriptStrings(); + SendGlobalGMSysMessage("DB table `db_script_string` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Graveyard-zone links..."); + + objmgr.LoadGraveyardZones(); + + SendGlobalGMSysMessage("DB table `game_graveyard_zone` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Game Tele coordinates..."); + + objmgr.LoadGameTele(); + + SendGlobalGMSysMessage("DB table `game_tele` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadSpellDisabledCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading spell disabled table..."); + + objmgr.LoadSpellDisabledEntrys(); + + SendGlobalGMSysMessage("DB table `spell_disabled` reloaded."); + + return true; +} + +bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Creature ..."); + objmgr.LoadCreatureLocales(); + SendGlobalGMSysMessage("DB table `locales_creature` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesGameobjectCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Gameobject ... "); + objmgr.LoadGameObjectLocales(); + SendGlobalGMSysMessage("DB table `locales_gameobject` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Item ... "); + objmgr.LoadItemLocales(); + SendGlobalGMSysMessage("DB table `locales_item` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales NPC Text ... "); + objmgr.LoadNpcTextLocales(); + SendGlobalGMSysMessage("DB table `locales_npc_text` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesPageTextCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Page Text ... "); + objmgr.LoadPageTextLocales(); + SendGlobalGMSysMessage("DB table `locales_page_text` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesPointsOfInterestCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Points Of Interest ... "); + objmgr.LoadPointOfInterestLocales(); + SendGlobalSysMessage("DB table `locales_points_of_interest` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Locales Quest ... "); + objmgr.LoadQuestLocales(); + SendGlobalGMSysMessage("DB table `locales_quest` reloaded."); + return true; +} + +bool ChatHandler::HandleLoadScriptsCommand(const char* args) +{ + if(!LoadScriptingModule(args)) return true; + + sWorld.SendGMText(LANG_SCRIPTS_RELOADED); + return true; +} + +bool ChatHandler::HandleReloadAuctionsCommand(const char* args) +{ + ///- Reload dynamic data tables from the database + sLog.outString( "Re-Loading Auctions..." ); + auctionmgr.LoadAuctionItems(); + auctionmgr.LoadAuctions(); + SendGlobalGMSysMessage("Auctions reloaded."); + return true; +} + +bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args) +{ + if(!*args) + return false; + + std::string targetAccountName; + uint32 targetAccountId = 0; + uint32 targetSecurity = 0; + uint32 gm = 0; + char* arg1 = strtok((char*)args, " "); + char* arg2 = strtok(NULL, " "); + + if(getSelectedPlayer() && arg1 && !arg2) + { + targetAccountId = getSelectedPlayer()->GetSession()->GetAccountId(); + accmgr.GetName(targetAccountId, targetAccountName); + Player* targetPlayer = getSelectedPlayer(); + gm = atoi(arg1); + + // Check for invalid specified GM level. + if ( (gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR) ) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + // Check if targets GM level and specified GM level is not higher than current gm level + targetSecurity = targetPlayer->GetSession()->GetSecurity(); + if(targetSecurity >= m_session->GetSecurity() || gm >= m_session->GetSecurity() ) + { + SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage(true); + return false; + } + + // Decide which string to show + if(m_session->GetPlayer()!=targetPlayer) + { + PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); + }else{ + PSendSysMessage(LANG_YOURS_SECURITY_CHANGED, m_session->GetPlayer()->GetName(), gm); + } + + LoginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId); + return true; + }else + { + // Check for second parameter + if(!arg2) + return false; + + // Check for account + targetAccountName = arg1; + if(!AccountMgr::normilizeString(targetAccountName)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str()); + SetSentErrorMessage(true); + return false; + } + + // Check for invalid specified GM level. + gm = atoi(arg2); + if ( (gm < SEC_PLAYER || gm > SEC_ADMINISTRATOR) ) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + targetAccountId = accmgr.GetId(arg1); + /// m_session==NULL only for console + uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE; + + /// can set security level only for target with less security and to less security that we have + /// This is also reject self apply in fact + targetSecurity = accmgr.GetSecurity(targetAccountId); + if(targetSecurity >= plSecurity || gm >= plSecurity ) + { + SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); + LoginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId); + return true; + } +} + +/// Set password for account +bool ChatHandler::HandleAccountSetPasswordCommand(const char* args) +{ + if(!*args) + return false; + + ///- Get the command line arguments + char *szAccount = strtok ((char*)args," "); + char *szPassword1 = strtok (NULL," "); + char *szPassword2 = strtok (NULL," "); + + if (!szAccount||!szPassword1 || !szPassword2) + return false; + + std::string account_name = szAccount; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = accmgr.GetId(account_name); + if (!targetAccountId) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + /// can set password only for target with less security + /// This is also reject self apply in fact + if(HasLowerSecurityAccount (NULL,targetAccountId,true)) + return false; + + if (strcmp(szPassword1,szPassword2)) + { + SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH); + SetSentErrorMessage (true); + return false; + } + + AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1); + + switch(result) + { + case AOR_OK: + SendSysMessage(LANG_COMMAND_PASSWORD); + break; + case AOR_NAME_NOT_EXIST: + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + case AOR_PASS_TOO_LONG: + SendSysMessage(LANG_PASSWORD_TOO_LONG); + SetSentErrorMessage(true); + return false; + default: + SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/) +{ + Player* SelectedPlayer = getSelectedPlayer(); + if(!SelectedPlayer) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // each skills that have max skill value dependent from level seted to current level max skill value + SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); + return true; +} + +bool ChatHandler::HandleSetSkillCommand(const char* args) +{ + // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r + char* skill_p = extractKeyFromLink((char*)args,"Hskill"); + if(!skill_p) + return false; + + char *level_p = strtok (NULL, " "); + + if( !level_p) + return false; + + char *max_p = strtok (NULL, " "); + + int32 skill = atoi(skill_p); + if (skill <= 0) + { + PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + SetSentErrorMessage(true); + return false; + } + + int32 level = atol (level_p); + + Player * target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill); + if(!sl) + { + PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + SetSentErrorMessage(true); + return false; + } + + std::string tNameLink = GetNameLink(target); + + if(!target->GetSkillValue(skill)) + { + PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[0]); + SetSentErrorMessage(true); + return false; + } + + int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill); + + if( level <= 0 || level > max || max <= 0 ) + return false; + + target->SetSkill(skill, level, max); + PSendSysMessage(LANG_SET_SKILL, skill, sl->name[0], tNameLink.c_str(), level, max); + + return true; +} + +bool ChatHandler::HandleUnLearnCommand(const char* args) +{ + if (!*args) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + uint32 spell_id = extractSpellIdFromLink((char*)args); + if(!spell_id) + return false; + + char const* allStr = strtok(NULL," "); + bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; + + Player* target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(allRanks) + spell_id = spellmgr.GetFirstSpellInChain (spell_id); + + if (target->HasSpell(spell_id)) + target->removeSpell(spell_id,false,!allRanks); + else + SendSysMessage(LANG_FORGET_SPELL); + + return true; +} + +bool ChatHandler::HandleCooldownCommand(const char* args) +{ + Player* target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + std::string tNameLink = GetNameLink(target); + + if (!*args) + { + target->RemoveAllSpellCooldown(); + PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str()); + } + else + { + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell_id = extractSpellIdFromLink((char*)args); + if(!spell_id) + return false; + + if(!sSpellStore.LookupEntry(spell_id)) + { + PSendSysMessage(LANG_UNKNOWN_SPELL, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); + SetSentErrorMessage(true); + return false; + } + + WorldPacket data( SMSG_CLEAR_COOLDOWN, (4+8) ); + data << uint32(spell_id); + data << uint64(target->GetGUID()); + target->GetSession()->SendPacket(&data); + target->RemoveSpellCooldown(spell_id); + PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target==m_session->GetPlayer() ? GetMangosString(LANG_YOU) : tNameLink.c_str()); + } + return true; +} + +bool ChatHandler::HandleLearnAllCommand(const char* /*args*/) +{ + static const char *allSpellList[] = + { + "3365", + "6233", + "6247", + "6246", + "6477", + "6478", + "22810", + "8386", + "21651", + "21652", + "522", + "7266", + "8597", + "2479", + "22027", + "6603", + "5019", + "133", + "168", + "227", + "5009", + "9078", + "668", + "203", + "20599", + "20600", + "81", + "20597", + "20598", + "20864", + "1459", + "5504", + "587", + "5143", + "118", + "5505", + "597", + "604", + "1449", + "1460", + "2855", + "1008", + "475", + "5506", + "1463", + "12824", + "8437", + "990", + "5145", + "8450", + "1461", + "759", + "8494", + "8455", + "8438", + "6127", + "8416", + "6129", + "8451", + "8495", + "8439", + "3552", + "8417", + "10138", + "12825", + "10169", + "10156", + "10144", + "10191", + "10201", + "10211", + "10053", + "10173", + "10139", + "10145", + "10192", + "10170", + "10202", + "10054", + "10174", + "10193", + "12826", + "2136", + "143", + "145", + "2137", + "2120", + "3140", + "543", + "2138", + "2948", + "8400", + "2121", + "8444", + "8412", + "8457", + "8401", + "8422", + "8445", + "8402", + "8413", + "8458", + "8423", + "8446", + "10148", + "10197", + "10205", + "10149", + "10215", + "10223", + "10206", + "10199", + "10150", + "10216", + "10207", + "10225", + "10151", + "116", + "205", + "7300", + "122", + "837", + "10", + "7301", + "7322", + "6143", + "120", + "865", + "8406", + "6141", + "7302", + "8461", + "8407", + "8492", + "8427", + "8408", + "6131", + "7320", + "10159", + "8462", + "10185", + "10179", + "10160", + "10180", + "10219", + "10186", + "10177", + "10230", + "10181", + "10161", + "10187", + "10220", + "2018", + "2663", + "12260", + "2660", + "3115", + "3326", + "2665", + "3116", + "2738", + "3293", + "2661", + "3319", + "2662", + "9983", + "8880", + "2737", + "2739", + "7408", + "3320", + "2666", + "3323", + "3324", + "3294", + "22723", + "23219", + "23220", + "23221", + "23228", + "23338", + "10788", + "10790", + "5611", + "5016", + "5609", + "2060", + "10963", + "10964", + "10965", + "22593", + "22594", + "596", + "996", + "499", + "768", + "17002", + "1448", + "1082", + "16979", + "1079", + "5215", + "20484", + "5221", + "15590", + "17007", + "6795", + "6807", + "5487", + "1446", + "1066", + "5421", + "3139", + "779", + "6811", + "6808", + "1445", + "5216", + "1737", + "5222", + "5217", + "1432", + "6812", + "9492", + "5210", + "3030", + "1441", + "783", + "6801", + "20739", + "8944", + "9491", + "22569", + "5226", + "6786", + "1433", + "8973", + "1828", + "9495", + "9006", + "6794", + "8993", + "5203", + "16914", + "6784", + "9635", + "22830", + "20722", + "9748", + "6790", + "9753", + "9493", + "9752", + "9831", + "9825", + "9822", + "5204", + "5401", + "22831", + "6793", + "9845", + "17401", + "9882", + "9868", + "20749", + "9893", + "9899", + "9895", + "9832", + "9902", + "9909", + "22832", + "9828", + "9851", + "9883", + "9869", + "17406", + "17402", + "9914", + "20750", + "9897", + "9848", + "3127", + "107", + "204", + "9116", + "2457", + "78", + "18848", + "331", + "403", + "2098", + "1752", + "11278", + "11288", + "11284", + "6461", + "2344", + "2345", + "6463", + "2346", + "2352", + "775", + "1434", + "1612", + "71", + "2468", + "2458", + "2467", + "7164", + "7178", + "7367", + "7376", + "7381", + "21156", + "5209", + "3029", + "5201", + "9849", + "9850", + "20719", + "22568", + "22827", + "22828", + "22829", + "6809", + "8972", + "9005", + "9823", + "9827", + "6783", + "9913", + "6785", + "6787", + "9866", + "9867", + "9894", + "9896", + "6800", + "8992", + "9829", + "9830", + "780", + "769", + "6749", + "6750", + "9755", + "9754", + "9908", + "20745", + "20742", + "20747", + "20748", + "9746", + "9745", + "9880", + "9881", + "5391", + "842", + "3025", + "3031", + "3287", + "3329", + "1945", + "3559", + "4933", + "4934", + "4935", + "4936", + "5142", + "5390", + "5392", + "5404", + "5420", + "6405", + "7293", + "7965", + "8041", + "8153", + "9033", + "9034", + //"9036", problems with ghost state + "16421", + "21653", + "22660", + "5225", + "9846", + "2426", + "5916", + "6634", + //"6718", phasing stealth, annoying for learn all case. + "6719", + "8822", + "9591", + "9590", + "10032", + "17746", + "17747", + "8203", + "11392", + "12495", + "16380", + "23452", + "4079", + "4996", + "4997", + "4998", + "4999", + "5000", + "6348", + "6349", + "6481", + "6482", + "6483", + "6484", + "11362", + "11410", + "11409", + "12510", + "12509", + "12885", + "13142", + "21463", + "23460", + "11421", + "11416", + "11418", + "1851", + "10059", + "11423", + "11417", + "11422", + "11419", + "11424", + "11420", + "27", + "31", + "33", + "34", + "35", + "15125", + "21127", + "22950", + "1180", + "201", + "12593", + "12842", + "16770", + "6057", + "12051", + "18468", + "12606", + "12605", + "18466", + "12502", + "12043", + "15060", + "12042", + "12341", + "12848", + "12344", + "12353", + "18460", + "11366", + "12350", + "12352", + "13043", + "11368", + "11113", + "12400", + "11129", + "16766", + "12573", + "15053", + "12580", + "12475", + "12472", + "12953", + "12488", + "11189", + "12985", + "12519", + "16758", + "11958", + "12490", + "11426", + "3565", + "3562", + "18960", + "3567", + "3561", + "3566", + "3563", + "1953", + "2139", + "12505", + "13018", + "12522", + "12523", + "5146", + "5144", + "5148", + "8419", + "8418", + "10213", + "10212", + "10157", + "12524", + "13019", + "12525", + "13020", + "12526", + "13021", + "18809", + "13031", + "13032", + "13033", + "4036", + "3920", + "3919", + "3918", + "7430", + "3922", + "3923", + "7411", + "7418", + "7421", + "13262", + "7412", + "7415", + "7413", + "7416", + "13920", + "13921", + "7745", + "7779", + "7428", + "7457", + "7857", + "7748", + "7426", + "13421", + "7454", + "13378", + "7788", + "14807", + "14293", + "7795", + "6296", + "20608", + "755", + "444", + "427", + "428", + "442", + "447", + "3578", + "3581", + "19027", + "3580", + "665", + "3579", + "3577", + "6755", + "3576", + "2575", + "2577", + "2578", + "2579", + "2580", + "2656", + "2657", + "2576", + "3564", + "10248", + "8388", + "2659", + "14891", + "3308", + "3307", + "10097", + "2658", + "3569", + "16153", + "3304", + "10098", + "4037", + "3929", + "3931", + "3926", + "3924", + "3930", + "3977", + "3925", + "136", + "228", + "5487", + "43", + "202", + "0" + }; + + int loop = 0; + while(strcmp(allSpellList[loop], "0")) + { + uint32 spell = atol((char*)allSpellList[loop++]); + + if (m_session->GetPlayer()->HasSpell(spell)) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + continue; + } + + m_session->GetPlayer()->learnSpell(spell,false); + } + + SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS); + + return true; +} + +bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/) +{ + static const char *gmSpellList[] = + { + "24347", // Become A Fish, No Breath Bar + "35132", // Visual Boom + "38488", // Attack 4000-8000 AOE + "38795", // Attack 2000 AOE + Slow Down 90% + "15712", // Attack 200 + "1852", // GM Spell Silence + "31899", // Kill + "31924", // Kill + "29878", // Kill My Self + "26644", // More Kill + + "28550", //Invisible 24 + "23452", //Invisible + Target + "0" + }; + + uint16 gmSpellIter = 0; + while( strcmp(gmSpellList[gmSpellIter], "0") ) + { + uint32 spell = atol((char*)gmSpellList[gmSpellIter++]); + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + continue; + } + + m_session->GetPlayer()->learnSpell(spell,false); + } + + SendSysMessage(LANG_LEARNING_GM_SKILLS); + return true; +} + +bool ChatHandler::HandleLearnAllMyClassCommand(const char* /*args*/) +{ + HandleLearnAllMySpellsCommand(""); + HandleLearnAllMyTalentsCommand(""); + return true; +} + +bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/) +{ + ChrClassesEntry const* clsEntry = sChrClassesStore.LookupEntry(m_session->GetPlayer()->getClass()); + if(!clsEntry) + return true; + uint32 family = clsEntry->spellfamily; + + for (uint32 i = 0; i < sSpellStore.GetNumRows(); i++) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(i); + if(!spellInfo) + continue; + + // skip server-side/triggered spells + if(spellInfo->spellLevel==0) + continue; + + // skip wrong class/race skills + if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id)) + continue; + + // skip other spell families + if( spellInfo->SpellFamilyName != family) + continue; + + // skip spells with first rank learned as talent (and all talents then also) + uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id); + if(GetTalentSpellCost(first_rank) > 0 ) + continue; + + // skip broken spells + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + m_session->GetPlayer()->learnSpell(i,false); + } + + SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); + return true; +} + +bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/) +{ + Player* player = m_session->GetPlayer(); + uint32 classMask = player->getClassMask(); + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if(!talentInfo) + continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + if(!talentTabInfo) + continue; + + if( (classMask & talentTabInfo->ClassMask) == 0 ) + continue; + + // search highest talent rank + uint32 spellid = 0; + + for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank) + { + if(talentInfo->RankID[rank]!=0) + { + spellid = talentInfo->RankID[rank]; + break; + } + } + + if(!spellid) // ??? none spells in talent + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) + player->learnSpellHighRank(spellid); + } + + SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS); + return true; +} + +bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/) +{ + Player* player = m_session->GetPlayer(); + + Pet* pet = player->GetPet(); + if(!pet) + { + SendSysMessage(LANG_NO_PET_FOUND); + SetSentErrorMessage(true); + return false; + } + + CreatureInfo const *ci = pet->GetCreatureInfo(); + if(!ci) + { + SendSysMessage(LANG_WRONG_PET_TYPE); + SetSentErrorMessage(true); + return false; + } + + CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); + if(!pet_family) + { + SendSysMessage(LANG_WRONG_PET_TYPE); + SetSentErrorMessage(true); + return false; + } + + if(pet_family->petTalentType < 0) // not hunter pet + { + SendSysMessage(LANG_WRONG_PET_TYPE); + SetSentErrorMessage(true); + return false; + } + + for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if(!talentInfo) + continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + if(!talentTabInfo) + continue; + + // prevent learn talent for different family (cheating) + if(((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)==0) + continue; + + // search highest talent rank + uint32 spellid = 0; + + for(int rank = MAX_TALENT_RANK-1; rank >= 0; --rank) + { + if(talentInfo->RankID[rank]!=0) + { + spellid = talentInfo->RankID[rank]; + break; + } + } + + if(!spellid) // ??? none spells in talent + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) + continue; + + // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) + pet->learnSpellHighRank(spellid); + } + + SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); + return true; +} + +bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/) +{ + // skipping UNIVERSAL language (0) + for(int i = 1; i < LANGUAGES_COUNT; ++i) + m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false); + + SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); + return true; +} + +bool ChatHandler::HandleLearnAllDefaultCommand(const char* args) +{ + Player *player = NULL; + if (*args) + { + std::string name = extractPlayerNameFromLink((char*)args); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(name.c_str()); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + player->learnDefaultSpells(); + player->learnQuestRewardedSpells(); + + PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(player).c_str()); + return true; +} + +bool ChatHandler::HandleLearnCommand(const char* args) +{ + Player* targetPlayer = getSelectedPlayer(); + + if(!targetPlayer) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell || !sSpellStore.LookupEntry(spell)) + return false; + + char const* allStr = strtok(NULL," "); + bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + if (!allRanks && targetPlayer->HasSpell(spell)) + { + if(targetPlayer == m_session->GetPlayer()) + SendSysMessage(LANG_YOU_KNOWN_SPELL); + else + PSendSysMessage(LANG_TARGET_KNOWN_SPELL,GetNameLink(targetPlayer).c_str()); + SetSentErrorMessage(true); + return false; + } + + if(allRanks) + targetPlayer->learnSpellHighRank(spell); + else + targetPlayer->learnSpell(spell,false); + + return true; +} + +bool ChatHandler::HandleAddItemCommand(const char* args) +{ + if (!*args) + return false; + + uint32 itemId = 0; + + if(args[0]=='[') // [name] manual form + { + char* citemName = citemName = strtok((char*)args, "]"); + + if(citemName && citemName[0]) + { + std::string itemName = citemName+1; + WorldDatabase.escape_string(itemName); + QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str()); + if (!result) + { + PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1); + SetSentErrorMessage(true); + return false; + } + itemId = result->Fetch()->GetUInt16(); + delete result; + } + else + return false; + } + else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r + { + char* cId = extractKeyFromLink((char*)args,"Hitem"); + if(!cId) + return false; + itemId = atol(cId); + } + + char* ccount = strtok(NULL, " "); + + int32 count = 1; + + if (ccount) + count = strtol(ccount, NULL, 10); + + if (count == 0) + count = 1; + + Player* pl = m_session->GetPlayer(); + Player* plTarget = getSelectedPlayer(); + if(!plTarget) + plTarget = pl; + + sLog.outDetail(GetTrinityString(LANG_ADDITEM), itemId, count); + + ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId); + if(!pProto) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + SetSentErrorMessage(true); + return false; + } + + //Subtract + if (count < 0) + { + plTarget->DestroyItemCount(itemId, -count, true, false); + PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str()); + return true; + } + + //Adding items + uint32 noSpaceForCount = 0; + + // check space and find places + ItemPosCountVec dest; + uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount ); + if( msg != EQUIP_ERR_OK ) // convert to possible store amount + count -= noSpaceForCount; + + if( count == 0 || dest.empty()) // can't add any + { + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount ); + SetSentErrorMessage(true); + return false; + } + + Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + + // remove binding (let GM give it to another player later) + if(pl==plTarget) + for(ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) + if(Item* item1 = pl->GetItemByPos(itr->pos)) + item1->SetBinding( false ); + + if(count > 0 && item) + { + pl->SendNewItem(item,count,false,true); + if(pl!=plTarget) + plTarget->SendNewItem(item,count,true,false); + } + + if(noSpaceForCount > 0) + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + + return true; +} + +bool ChatHandler::HandleAddItemSetCommand(const char* args) +{ + if (!*args) + return false; + + char* cId = extractKeyFromLink((char*)args,"Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r + if (!cId) + return false; + + uint32 itemsetId = atol(cId); + + // prevent generation all items with itemset field value '0' + if (itemsetId == 0) + { + PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); + SetSentErrorMessage(true); + return false; + } + + Player* pl = m_session->GetPlayer(); + Player* plTarget = getSelectedPlayer(); + if(!plTarget) + plTarget = pl; + + sLog.outDetail(GetTrinityString(LANG_ADDITEMSET), itemsetId); + + bool found = false; + for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) + { + ItemPrototype const *pProto = sItemStorage.LookupEntry(id); + if (!pProto) + continue; + + if (pProto->ItemSet == itemsetId) + { + found = true; + ItemPosCountVec dest; + uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 ); + if (msg == EQUIP_ERR_OK) + { + Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true); + + // remove binding (let GM give it to another player later) + if (pl==plTarget) + item->SetBinding( false ); + + pl->SendNewItem(item,1,false,true); + if (pl!=plTarget) + plTarget->SendNewItem(item,1,true,false); + } + else + { + pl->SendEquipError( msg, NULL, NULL ); + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1); + } + } + } + + if (!found) + { + PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); + + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleListItemCommand(const char* args) +{ + if(!*args) + return false; + + char* cId = extractKeyFromLink((char*)args,"Hitem"); + if(!cId) + return false; + + uint32 item_id = atol(cId); + if(!item_id) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); + SetSentErrorMessage(true); + return false; + } + + ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_id); + if(!itemProto) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); + SetSentErrorMessage(true); + return false; + } + + char* c_count = strtok(NULL, " "); + int count = c_count ? atol(c_count) : 10; + + if(count < 0) + return false; + + QueryResult *result; + + // inventory case + uint32 inv_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM character_inventory WHERE item_template='%u'",item_id); + if(result) + { + inv_count = (*result)[0].GetUInt32(); + delete result; + } + + result=CharacterDatabase.PQuery( + // 0 1 2 3 4 5 + "SELECT ci.item, cibag.slot AS bag, ci.slot, ci.guid, characters.account,characters.name " + "FROM character_inventory AS ci LEFT JOIN character_inventory AS cibag ON (cibag.item=ci.bag),characters " + "WHERE ci.item_template='%u' AND ci.guid = characters.guid LIMIT %u ", + item_id,uint32(count)); + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 item_bag = fields[1].GetUInt32(); + uint32 item_slot = fields[2].GetUInt32(); + uint32 owner_guid = fields[3].GetUInt32(); + uint32 owner_acc = fields[4].GetUInt32(); + std::string owner_name = fields[5].GetCppString(); + + char const* item_pos = 0; + if(Player::IsEquipmentPos(item_bag,item_slot)) + item_pos = "[equipped]"; + else if(Player::IsInventoryPos(item_bag,item_slot)) + item_pos = "[in inventory]"; + else if(Player::IsBankPos(item_bag,item_slot)) + item_pos = "[in bank]"; + else + item_pos = ""; + + PSendSysMessage(LANG_ITEMLIST_SLOT, + item_guid,owner_name.c_str(),owner_guid,owner_acc,item_pos); + } while (result->NextRow()); + + int64 res_count = result->GetRowCount(); + + delete result; + + if(count > res_count) + count-=res_count; + else if(count) + count = 0; + } + + // mail case + uint32 mail_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM mail_items WHERE item_template='%u'", item_id); + if(result) + { + mail_count = (*result)[0].GetUInt32(); + delete result; + } + + if(count > 0) + { + result=CharacterDatabase.PQuery( + // 0 1 2 3 4 5 6 + "SELECT mail_items.item_guid, mail.sender, mail.receiver, char_s.account, char_s.name, char_r.account, char_r.name " + "FROM mail,mail_items,characters as char_s,characters as char_r " + "WHERE mail_items.item_template='%u' AND char_s.guid = mail.sender AND char_r.guid = mail.receiver AND mail.id=mail_items.mail_id LIMIT %u", + item_id,uint32(count)); + } + else + result = NULL; + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 item_s = fields[1].GetUInt32(); + uint32 item_r = fields[2].GetUInt32(); + uint32 item_s_acc = fields[3].GetUInt32(); + std::string item_s_name = fields[4].GetCppString(); + uint32 item_r_acc = fields[5].GetUInt32(); + std::string item_r_name = fields[6].GetCppString(); + + char const* item_pos = "[in mail]"; + + PSendSysMessage(LANG_ITEMLIST_MAIL, + item_guid,item_s_name.c_str(),item_s,item_s_acc,item_r_name.c_str(),item_r,item_r_acc,item_pos); + } while (result->NextRow()); + + int64 res_count = result->GetRowCount(); + + delete result; + + if(count > res_count) + count-=res_count; + else if(count) + count = 0; + } + + // auction case + uint32 auc_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_template) FROM auctionhouse WHERE item_template='%u'",item_id); + if(result) + { + auc_count = (*result)[0].GetUInt32(); + delete result; + } + + if(count > 0) + { + result=CharacterDatabase.PQuery( + // 0 1 2 3 + "SELECT auctionhouse.itemguid, auctionhouse.itemowner, characters.account, characters.name " + "FROM auctionhouse,characters WHERE auctionhouse.item_template='%u' AND characters.guid = auctionhouse.itemowner LIMIT %u", + item_id,uint32(count)); + } + else + result = NULL; + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 owner = fields[1].GetUInt32(); + uint32 owner_acc = fields[2].GetUInt32(); + std::string owner_name = fields[3].GetCppString(); + + char const* item_pos = "[in auction]"; + + PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc,item_pos); + } while (result->NextRow()); + + delete result; + } + + // guild bank case + uint32 guild_count = 0; + result=CharacterDatabase.PQuery("SELECT COUNT(item_entry) FROM guild_bank_item WHERE item_entry='%u'",item_id); + if(result) + { + guild_count = (*result)[0].GetUInt32(); + delete result; + } + + result=CharacterDatabase.PQuery( + // 0 1 2 + "SELECT gi.item_guid, gi.guildid, guild.name " + "FROM guild_bank_item AS gi, guild WHERE gi.item_entry='%u' AND gi.guildid = guild.guildid LIMIT %u ", + item_id,uint32(count)); + + if(result) + { + do + { + Field *fields = result->Fetch(); + uint32 item_guid = fields[0].GetUInt32(); + uint32 guild_guid = fields[1].GetUInt32(); + std::string guild_name = fields[2].GetCppString(); + + char const* item_pos = "[in guild bank]"; + + PSendSysMessage(LANG_ITEMLIST_GUILD,item_guid,guild_name.c_str(),guild_guid,item_pos); + } while (result->NextRow()); + + int64 res_count = result->GetRowCount(); + + delete result; + + if(count > res_count) + count-=res_count; + else if(count) + count = 0; + } + + if(inv_count+mail_count+auc_count+guild_count == 0) + { + SendSysMessage(LANG_COMMAND_NOITEMFOUND); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE,item_id,inv_count+mail_count+auc_count+guild_count,inv_count,mail_count,auc_count,guild_count); + + return true; +} + +bool ChatHandler::HandleListObjectCommand(const char* args) +{ + if(!*args) + return false; + + // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry"); + if(!cId) + return false; + + uint32 go_id = atol(cId); + if(!go_id) + { + PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); + SetSentErrorMessage(true); + return false; + } + + GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(go_id); + if(!gInfo) + { + PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); + SetSentErrorMessage(true); + return false; + } + + char* c_count = strtok(NULL, " "); + int count = c_count ? atol(c_count) : 10; + + if(count < 0) + return false; + + QueryResult *result; + + uint32 obj_count = 0; + result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'",go_id); + if(result) + { + obj_count = (*result)[0].GetUInt32(); + delete result; + } + + if(m_session) + { + Player* pl = m_session->GetPlayer(); + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),go_id,uint32(count)); + } + else + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM gameobject WHERE id = '%u' LIMIT %u", + go_id,uint32(count)); + + if (result) + { + do + { + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + float x = fields[1].GetFloat(); + float y = fields[2].GetFloat(); + float z = fields[3].GetFloat(); + int mapid = fields[4].GetUInt16(); + + if (m_session) + PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid); + else + PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name, x, y, z, mapid); + } while (result->NextRow()); + + delete result; + } + + PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE,go_id,obj_count); + return true; +} + +bool ChatHandler::HandleGameObjectStateCommand(const char* args) +{ + // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args, "Hgameobject"); + if(!cId) + return false; + + uint32 lowguid = atoi(cId); + if(!lowguid) + return false; + + GameObject* gobj = NULL; + + if(GameObjectData const* goData = objmgr.GetGOData(lowguid)) + gobj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid, goData->id); + + if(!gobj) + { + PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); + SetSentErrorMessage(true); + return false; + } + + char* cstate = strtok(NULL, " "); + if(!cstate) + return false; + + int32 state = atoi(cstate); + if(state < 0) + gobj->SendObjectDeSpawnAnim(gobj->GetGUID()); + else + gobj->SetGoState(state); + + return true; +} + +bool ChatHandler::HandleListCreatureCommand(const char* args) +{ + if(!*args) + return false; + + // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hcreature_entry"); + if(!cId) + return false; + + uint32 cr_id = atol(cId); + if(!cr_id) + { + PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); + SetSentErrorMessage(true); + return false; + } + + CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(cr_id); + if(!cInfo) + { + PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); + SetSentErrorMessage(true); + return false; + } + + char* c_count = strtok(NULL, " "); + int count = c_count ? atol(c_count) : 10; + + if(count < 0) + return false; + + QueryResult *result; + + uint32 cr_count = 0; + result=WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'",cr_id); + if(result) + { + cr_count = (*result)[0].GetUInt32(); + delete result; + } + + if(m_session) + { + Player* pl = m_session->GetPlayer(); + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", + pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), cr_id,uint32(count)); + } + else + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", + cr_id,uint32(count)); + + if (result) + { + do + { + Field *fields = result->Fetch(); + uint32 guid = fields[0].GetUInt32(); + float x = fields[1].GetFloat(); + float y = fields[2].GetFloat(); + float z = fields[3].GetFloat(); + int mapid = fields[4].GetUInt16(); + + if (m_session) + PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name, x, y, z, mapid); + else + PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name, x, y, z, mapid); + } while (result->NextRow()); + + delete result; + } + + PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE,cr_id,cr_count); + return true; +} + +bool ChatHandler::HandleLookupItemCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0; + + // Search in `item_template` + for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) + { + ItemPrototype const *pProto = sItemStorage.LookupEntry(id); + if(!pProto) + continue; + + int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + if ( loc_idx >= 0 ) + { + ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); + if (il) + { + if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + { + std::string name = il->Name[loc_idx]; + + if (Utf8FitTo(name, wnamepart)) + { + if (m_session) + PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str()); + else + PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str()); + ++counter; + continue; + } + } + } + } + + std::string name = pProto->Name1; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + { + if (m_session) + PSendSysMessage(LANG_ITEM_LIST_CHAT, id, id, name.c_str()); + else + PSendSysMessage(LANG_ITEM_LIST_CONSOLE, id, name.c_str()); + ++counter; + } + } + + if (counter==0) + SendSysMessage(LANG_COMMAND_NOITEMFOUND); + + return true; +} + +bool ChatHandler::HandleLookupItemSetCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in ItemSet.dbc + for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++) + { + ItemSetEntry const *set = sItemSetStore.LookupEntry(id); + if(set) + { + int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + std::string name = set->name[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(m_session && loc==m_session->GetSessionDbcLocale()) + continue; + + name = set->name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + // send item set in "id - [namedlink locale]" format + if (m_session) + PSendSysMessage(LANG_ITEMSET_LIST_CHAT,id,id,name.c_str(),localeNames[loc]); + else + PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE,id,name.c_str(),localeNames[loc]); + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOITEMSETFOUND); + return true; +} + +bool ChatHandler::HandleLookupSkillCommand(const char* args) +{ + if(!*args) + return false; + + // can be NULL in console call + Player* target = getSelectedPlayer(); + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in SkillLine.dbc + for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++) + { + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id); + if(skillInfo) + { + int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + std::string name = skillInfo->name[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(m_session && loc==m_session->GetSessionDbcLocale()) + continue; + + name = skillInfo->name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + char valStr[50] = ""; + char const* knownStr = ""; + if(target && target->HasSkill(id)) + { + knownStr = GetTrinityString(LANG_KNOWN); + uint32 curValue = target->GetPureSkillValue(id); + uint32 maxValue = target->GetPureMaxSkillValue(id); + uint32 permValue = target->GetSkillPermBonusValue(id); + uint32 tempValue = target->GetSkillTempBonusValue(id); + + char const* valFormat = GetTrinityString(LANG_SKILL_VALUES); + snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue); + } + + // send skill in "id - [namedlink locale]" format + if (m_session) + PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr); + else + PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr); + + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOSKILLFOUND); + return true; +} + +bool ChatHandler::HandleLookupSpellCommand(const char* args) +{ + if(!*args) + return false; + + // can be NULL at console call + Player* target = getSelectedPlayer(); + + std::string namepart = args; + std::wstring wnamepart; + + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + // converting string that we try to find to lower case + wstrToLower( wnamepart ); + + uint32 counter = 0; // Counter for figure out that we found smth. + + // Search in Spell.dbc + for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++) + { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(id); + if(spellInfo) + { + int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + std::string name = spellInfo->SpellName[loc]; + if(name.empty()) + continue; + + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(m_session && loc==m_session->GetSessionDbcLocale()) + continue; + + name = spellInfo->SpellName[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) + { + bool known = target && target->HasSpell(id); + bool learn = (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL); + + uint32 talentCost = GetTalentSpellCost(id); + + bool talent = (talentCost > 0); + bool passive = IsPassiveSpell(id); + bool active = target && target->HasAura(id); + + // unit32 used to prevent interpreting uint8 as char at output + // find rank of learned spell for learning spell, or talent rank + uint32 rank = talentCost ? talentCost : spellmgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[0] : id); + + // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format + std::ostringstream ss; + if (m_session) + ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; + else + ss << id << " - " << name; + + // include rank in link name + if(rank) + ss << GetTrinityString(LANG_SPELL_RANK) << rank; + + if (m_session) + ss << " " << localeNames[loc] << "]|h|r"; + else + ss << " " << localeNames[loc]; + + if(talent) + ss << GetTrinityString(LANG_TALENT); + if(passive) + ss << GetTrinityString(LANG_PASSIVE); + if(learn) + ss << GetTrinityString(LANG_LEARN); + if(known) + ss << GetTrinityString(LANG_KNOWN); + if(active) + ss << GetTrinityString(LANG_ACTIVE); + + SendSysMessage(ss.str().c_str()); + + ++counter; + } + } + } + if (counter == 0) // if counter == 0 then we found nth + SendSysMessage(LANG_COMMAND_NOSPELLFOUND); + return true; +} + +bool ChatHandler::HandleLookupQuestCommand(const char* args) +{ + if(!*args) + return false; + + // can be NULL at console call + Player* target = getSelectedPlayer(); + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0 ; + + ObjectMgr::QuestMap const& qTemplates = objmgr.GetQuestTemplates(); + for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter) + { + Quest * qinfo = iter->second; + + int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + if ( loc_idx >= 0 ) + { + QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId()); + if (il) + { + if (il->Title.size() > loc_idx && !il->Title[loc_idx].empty()) + { + std::string title = il->Title[loc_idx]; + + if (Utf8FitTo(title, wnamepart)) + { + char const* statusStr = ""; + + if(target) + { + QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); + + if(status == QUEST_STATUS_COMPLETE) + { + if(target->GetQuestRewardStatus(qinfo->GetQuestId())) + statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); + else + statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); + } + else if(status == QUEST_STATUS_INCOMPLETE) + statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); + } + + if (m_session) + PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr); + else + PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr); + ++counter; + continue; + } + } + } + } + + std::string title = qinfo->GetTitle(); + if(title.empty()) + continue; + + if (Utf8FitTo(title, wnamepart)) + { + char const* statusStr = ""; + + if(target) + { + QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); + + if(status == QUEST_STATUS_COMPLETE) + { + if(target->GetQuestRewardStatus(qinfo->GetQuestId())) + statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); + else + statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); + } + else if(status == QUEST_STATUS_INCOMPLETE) + statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); + } + + if (m_session) + PSendSysMessage(LANG_QUEST_LIST_CHAT,qinfo->GetQuestId(),qinfo->GetQuestId(),title.c_str(),statusStr); + else + PSendSysMessage(LANG_QUEST_LIST_CONSOLE,qinfo->GetQuestId(),title.c_str(),statusStr); + + ++counter; + } + } + + if (counter==0) + SendSysMessage(LANG_COMMAND_NOQUESTFOUND); + + return true; +} + +bool ChatHandler::HandleLookupCreatureCommand(const char* args) +{ + if (!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if (!Utf8toWStr (namepart,wnamepart)) + return false; + + wstrToLower (wnamepart); + + uint32 counter = 0; + + for (uint32 id = 0; id< sCreatureStorage.MaxEntry; ++id) + { + CreatureInfo const* cInfo = sCreatureStorage.LookupEntry (id); + if(!cInfo) + continue; + + int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + if (loc_idx >= 0) + { + CreatureLocale const *cl = objmgr.GetCreatureLocale (id); + if (cl) + { + if (cl->Name.size() > loc_idx && !cl->Name[loc_idx].empty ()) + { + std::string name = cl->Name[loc_idx]; + + if (Utf8FitTo (name, wnamepart)) + { + if (m_session) + PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ()); + else + PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ()); + ++counter; + continue; + } + } + } + } + + std::string name = cInfo->Name; + if (name.empty ()) + continue; + + if (Utf8FitTo(name, wnamepart)) + { + if (m_session) + PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str ()); + else + PSendSysMessage (LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str ()); + ++counter; + } + } + + if (counter==0) + SendSysMessage (LANG_COMMAND_NOCREATUREFOUND); + + return true; +} + +bool ChatHandler::HandleLookupObjectCommand(const char* args) +{ + if(!*args) + return false; + + std::string namepart = args; + std::wstring wnamepart; + + // converting string that we try to find to lower case + if(!Utf8toWStr(namepart,wnamepart)) + return false; + + wstrToLower(wnamepart); + + uint32 counter = 0; + + for (uint32 id = 0; id< sGOStorage.MaxEntry; id++ ) + { + GameObjectInfo const* gInfo = sGOStorage.LookupEntry(id); + if(!gInfo) + continue; + + int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + if ( loc_idx >= 0 ) + { + GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id); + if (gl) + { + if (gl->Name.size() > loc_idx && !gl->Name[loc_idx].empty()) + { + std::string name = gl->Name[loc_idx]; + + if (Utf8FitTo(name, wnamepart)) + { + if (m_session) + PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str()); + else + PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str()); + ++counter; + continue; + } + } + } + } + + std::string name = gInfo->name; + if(name.empty()) + continue; + + if(Utf8FitTo(name, wnamepart)) + { + if (m_session) + PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, id, id, name.c_str()); + else + PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, id, name.c_str()); + ++counter; + } + } + + if(counter==0) + SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND); + + return true; +} + +/** \brief GM command level 3 - Create a guild. + * + * This command allows a GM (level 3) to create a guild. + * + * The "args" parameter contains the name of the guild leader + * and then the name of the guild. + * + */ +bool ChatHandler::HandleGuildCreateCommand(const char* args) +{ + + if (!*args) + return false; + + char *lname = strtok ((char*)args, " "); + char *gname = strtok (NULL, ""); + + if (!lname) + return false; + + if (!gname) + { + SendSysMessage (LANG_INSERT_GUILD_NAME); + SetSentErrorMessage (true); + return false; + } + + std::string guildname = gname; + + Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname); + if (!player) + { + SendSysMessage (LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage (true); + return false; + } + + if (player->GetGuildId()) + { + SendSysMessage (LANG_PLAYER_IN_GUILD); + return true; + } + + Guild *guild = new Guild; + if (!guild->create (player,guildname)) + { + delete guild; + SendSysMessage (LANG_GUILD_NOT_CREATED); + SetSentErrorMessage (true); + return false; + } + + objmgr.AddGuild (guild); + return true; +} + +bool ChatHandler::HandleGuildInviteCommand(const char *args) +{ + if (!*args) + return false; + + char* par1 = strtok ((char*)args, " "); + char* par2 = strtok (NULL, ""); + if(!par1 || !par2) + return false; + + std::string glName = par2; + Guild* targetGuild = objmgr.GetGuildByName (glName); + if (!targetGuild) + return false; + + std::string plName = extractPlayerNameFromLink(par1); + if(plName.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 plGuid = 0; + if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) + plGuid = targetPlayer->GetGUID (); + else + plGuid = objmgr.GetPlayerGUIDByName (plName); + + if (!plGuid) + return false; + + // player's guild membership checked in AddMember before add + if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ())) + return false; + + return true; +} + +bool ChatHandler::HandleGuildUninviteCommand(const char *args) +{ + if (!*args) + return false; + + char* par1 = strtok ((char*)args, " "); + if(!par1) + return false; + + std::string plName = extractPlayerNameFromLink(par1); + if(plName.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 plGuid = 0; + uint32 glId = 0; + if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) + { + plGuid = targetPlayer->GetGUID (); + glId = targetPlayer->GetGuildId (); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName (plName); + glId = Player::GetGuildIdFromDB (plGuid); + } + + if (!plGuid || !glId) + return false; + + Guild* targetGuild = objmgr.GetGuildById (glId); + if (!targetGuild) + return false; + + targetGuild->DelMember (plGuid); + + return true; +} + +bool ChatHandler::HandleGuildRankCommand(const char *args) +{ + if (!*args) + return false; + + char* par1 = strtok ((char*)args, " "); + char* par2 = strtok (NULL, " "); + if (!par1 || !par2) + return false; + + std::string plName = extractPlayerNameFromLink(par1); + if(plName.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + + uint64 plGuid = 0; + uint32 glId = 0; + if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) + { + plGuid = targetPlayer->GetGUID (); + glId = targetPlayer->GetGuildId (); + } + else + { + plGuid = objmgr.GetPlayerGUIDByName (plName); + glId = Player::GetGuildIdFromDB (plGuid); + } + + if (!plGuid || !glId) + return false; + + Guild* targetGuild = objmgr.GetGuildById (glId); + if (!targetGuild) + return false; + + uint32 newrank = uint32 (atoi (par2)); + if (newrank > targetGuild->GetLowestRank ()) + return false; + + targetGuild->ChangeRank (plGuid,newrank); + + return true; +} + +bool ChatHandler::HandleGuildDeleteCommand(const char* args) +{ + if (!*args) + return false; + + char* par1 = strtok ((char*)args, " "); + if (!par1) + return false; + + std::string gld = par1; + + Guild* targetGuild = objmgr.GetGuildByName (gld); + if (!targetGuild) + return false; + + targetGuild->Disband (); + + return true; +} + +bool ChatHandler::HandleGetDistanceCommand(const char* args) +{ + WorldObject* obj = NULL; + + if (*args) + { + uint64 guid = extractGuidFromLink((char*)args); + if(guid) + obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + + if(!obj) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + } + else + { + obj = getSelectedUnit(); + + if(!obj) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + } + + PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj)); + + return true; +} + +bool ChatHandler::HandleDieCommand(const char* /*args*/) +{ + Unit* target = getSelectedUnit(); + + if(!target || !m_session->GetPlayer()->GetSelection()) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(target->GetTypeId()==TYPEID_PLAYER) + { + if(HasLowerSecurity((Player*)target,0,false)) + return false; + } + + if( target->isAlive() ) + { + //m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_session->GetPlayer()->Kill(target); + } + + return true; +} + +bool ChatHandler::HandleDamageCommand(const char * args) +{ + if (!*args) + return false; + + Unit* target = getSelectedUnit(); + + if(!target || !m_session->GetPlayer()->GetSelection()) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if( !target->isAlive() ) + return true; + + char* damageStr = strtok((char*)args, " "); + if(!damageStr) + return false; + + int32 damage = atoi((char*)damageStr); + if(damage <=0) + return true; + + char* schoolStr = strtok((char*)NULL, " "); + + // flat melee damage without resistence/etc reduction + if(!schoolStr) + { + m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_NORMAL, 0); + return true; + } + + uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL; + if(school >= MAX_SPELL_SCHOOL) + return false; + + SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); + + if ( schoolmask & SPELL_SCHOOL_MASK_NORMAL ) + damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK); + + char* spellStr = strtok((char*)NULL, " "); + + // melee damage by specific school + if(!spellStr) + { + uint32 absorb = 0; + uint32 resist = 0; + + m_session->GetPlayer()->CalcAbsorbResist(target,schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); + + if (damage <= absorb + resist) + return true; + + damage -= absorb + resist; + + m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); + m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_NORMALSWING2, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_NORMAL, 0); + return true; + } + + // non-melee damage + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellid = extractSpellIdFromLink((char*)args); + if(!spellid || !sSpellStore.LookupEntry(spellid)) + return false; + + m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage, false); + return true; +} + +bool ChatHandler::HandleModifyArenaCommand(const char * args) +{ + if (!*args) + return false; + + Player *target = getSelectedPlayer(); + if(!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + int32 amount = (uint32)atoi(args); + + target->ModifyArenaPoints(amount); + + PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, GetNameLink(target).c_str(), target->GetArenaPoints()); + + return true; +} + +bool ChatHandler::HandleReviveCommand(const char* args) +{ + Player* SelectedPlayer = NULL; + + if (*args) + { + std::string name = extractPlayerNameFromLink((char*)args); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + SelectedPlayer = objmgr.GetPlayer(name.c_str()); + } + else + SelectedPlayer = getSelectedPlayer(); + + if(!SelectedPlayer) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + SelectedPlayer->ResurrectPlayer(0.5f); + SelectedPlayer->SpawnCorpseBones(); + SelectedPlayer->SaveToDB(); + return true; +} + +bool ChatHandler::HandleAuraCommand(const char* args) +{ + Unit *target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellID = extractSpellIdFromLink((char*)args); + + SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID ); + uint8 eff_mask=0; + if(spellInfo) + { + for(uint32 i = 0;i<3;i++) + { + uint8 eff = spellInfo->Effect[i]; + if (eff>=TOTAL_SPELL_EFFECTS) + continue; + if( IsAreaAuraEffect(eff) || + eff == SPELL_EFFECT_APPLY_AURA || + eff == SPELL_EFFECT_PERSISTENT_AREA_AURA ) + { + eff_mask|=1<AddAura(Aur); + + return true; +} + +bool ChatHandler::HandleUnAuraCommand(const char* args) +{ + Unit *target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + std::string argstr = args; + if (argstr == "all") + { + target->RemoveAllAuras(); + return true; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellID = extractSpellIdFromLink((char*)args); + if(!spellID) + return false; + + target->RemoveAurasDueToSpell(spellID); + + return true; +} + +bool ChatHandler::HandleLinkGraveCommand(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + if (!px) + return false; + + uint32 g_id = (uint32)atoi(px); + + uint32 g_team; + + char* px2 = strtok(NULL, " "); + + if (!px2) + g_team = 0; + else if (strncmp(px2,"horde",6)==0) + g_team = HORDE; + else if (strncmp(px2,"alliance",9)==0) + g_team = ALLIANCE; + else + return false; + + WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id); + + if(!graveyard ) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id); + SetSentErrorMessage(true); + return false; + } + + Player* player = m_session->GetPlayer(); + + uint32 zoneId = player->GetZoneId(); + + AreaTableEntry const *areaEntry = GetAreaEntryByAreaID(zoneId); + if(!areaEntry || areaEntry->zone !=0 ) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id,zoneId); + SetSentErrorMessage(true); + return false; + } + + if(objmgr.AddGraveYardLink(g_id,zoneId,g_team)) + PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id,zoneId); + else + PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id,zoneId); + + return true; +} + +bool ChatHandler::HandleNearGraveCommand(const char* args) +{ + uint32 g_team; + + size_t argslen = strlen(args); + + if(!*args) + g_team = 0; + else if (strncmp((char*)args,"horde",argslen)==0) + g_team = HORDE; + else if (strncmp((char*)args,"alliance",argslen)==0) + g_team = ALLIANCE; + else + return false; + + Player* player = m_session->GetPlayer(); + uint32 zone_id = player->GetZoneId(); + + WorldSafeLocsEntry const* graveyard = objmgr.GetClosestGraveYard( + player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(),g_team); + + if(graveyard) + { + uint32 g_id = graveyard->ID; + + GraveYardData const* data = objmgr.FindGraveYardData(g_id,zone_id); + if (!data) + { + PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR,g_id); + SetSentErrorMessage(true); + return false; + } + + g_team = data->team; + + std::string team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); + + if(g_team == 0) + team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if(g_team == HORDE) + team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if(g_team == ALLIANCE) + team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id,team_name.c_str(),zone_id); + } + else + { + std::string team_name; + + if(g_team == 0) + team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if(g_team == HORDE) + team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if(g_team == ALLIANCE) + team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + if(g_team == ~uint32(0)) + PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); + else + PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id,team_name.c_str()); + } + + return true; +} + +//-----------------------Npc Commands----------------------- +bool ChatHandler::HandleNpcAllowMovementCommand(const char* /*args*/) +{ + if(sWorld.getAllowMovement()) + { + sWorld.SetAllowMovement(false); + SendSysMessage(LANG_CREATURE_MOVE_DISABLED); + } + else + { + sWorld.SetAllowMovement(true); + SendSysMessage(LANG_CREATURE_MOVE_ENABLED); + } + return true; +} + +bool ChatHandler::HandleNpcChangeEntryCommand(const char *args) +{ + if (!*args) + return false; + + uint32 newEntryNum = atoi(args); + if(!newEntryNum) + return false; + + Unit* unit = getSelectedUnit(); + if(!unit || unit->GetTypeId() != TYPEID_UNIT) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + Creature* creature = (Creature*)unit; + if(creature->UpdateEntry(newEntryNum)) + SendSysMessage(LANG_DONE); + else + SendSysMessage(LANG_ERROR); + return true; +} + +bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/) +{ + Creature* target = getSelectedCreature(); + + if(!target) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint32 faction = target->getFaction(); + uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS); + uint32 displayid = target->GetDisplayId(); + uint32 nativeid = target->GetNativeDisplayId(); + uint32 Entry = target->GetEntry(); + CreatureInfo const* cInfo = target->GetCreatureInfo(); + + int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); + if(curRespawnDelay < 0) + curRespawnDelay = 0; + std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); + std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); + + PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid); + PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); + PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); + PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); + PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); + PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId); + PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); + PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); + + if ((npcflags & UNIT_NPC_FLAG_VENDOR) ) + { + SendSysMessage(LANG_NPCINFO_VENDOR); + } + if ((npcflags & UNIT_NPC_FLAG_TRAINER) ) + { + SendSysMessage(LANG_NPCINFO_TRAINER); + } + + return true; +} + +//play npc emote +bool ChatHandler::HandleNpcPlayEmoteCommand(const char* args) +{ + uint32 emote = atoi((char*)args); + + Creature* target = getSelectedCreature(); + if(!target) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote); + + return true; +} + +//TODO: NpcCommands that needs to be fixed : + +bool ChatHandler::HandleNpcAddWeaponCommand(const char* /*args*/) +{ + /*if (!*args) + return false; + + uint64 guid = m_session->GetPlayer()->GetSelection(); + if (guid == 0) + { + SendSysMessage(LANG_NO_SELECTION); + return true; + } + + Creature *pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); + + if(!pCreature) + { + SendSysMessage(LANG_SELECT_CREATURE); + return true; + } + + char* pSlotID = strtok((char*)args, " "); + if (!pSlotID) + return false; + + char* pItemID = strtok(NULL, " "); + if (!pItemID) + return false; + + uint32 ItemID = atoi(pItemID); + uint32 SlotID = atoi(pSlotID); + + ItemPrototype* tmpItem = objmgr.GetItemPrototype(ItemID); + + bool added = false; + if(tmpItem) + { + switch(SlotID) + { + case 1: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID); + added = true; + break; + case 2: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID); + added = true; + break; + case 3: + pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID); + added = true; + break; + default: + PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); + added = false; + break; + } + + if(added) + PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); + } + else + { + PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); + return true; + } + */ + return true; +} +//---------------------------------------------------------- + +bool ChatHandler::HandleExploreCheatCommand(const char* args) +{ + if (!*args) + return false; + + int flag = atoi((char*)args); + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str()); + if (needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL,GetNameLink().c_str()); + } + else + { + PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str()); + if (needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str()); + } + + for (uint8 i=0; i<128; i++) + { + if (flag != 0) + { + m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF); + } + else + { + m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0); + } + } + + return true; +} + +bool ChatHandler::HandleHoverCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + uint32 flag; + if (!px) + flag = 1; + else + flag = atoi(px); + + m_session->GetPlayer()->SetHover(flag); + + if (flag) + SendSysMessage(LANG_HOVER_ENABLED); + else + SendSysMessage(LANG_HOVER_DISABLED); + + return true; +} + +bool ChatHandler::HandleLevelUpCommand(const char* args) +{ + char* px = strtok((char*)args, " "); + char* py = strtok((char*)NULL, " "); + + // command format parsing + char* pname = (char*)NULL; + int addlevel = 1; + + if(px && py) // .levelup name level + { + addlevel = atoi(py); + pname = px; + } + else if(px && !py) // .levelup name OR .levelup level + { + if(isalpha(px[0])) // .levelup name + pname = px; + else // .levelup level + addlevel = atoi(px); + } + // else .levelup - nothing do for preparing + + // player + Player *chr = NULL; + uint64 chr_guid = 0; + + std::string name; + + if(pname) // player by name + { + name = extractPlayerNameFromLink(pname); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + chr = objmgr.GetPlayer(name.c_str()); + if(!chr) // not in game + { + chr_guid = objmgr.GetPlayerGUIDByName(name); + if (chr_guid == 0) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + } + } + else // player by selection + { + chr = getSelectedPlayer(); + + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + name = chr->GetName(); + } + + assert(chr || chr_guid); + + int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid); + int32 newlevel = oldlevel + addlevel; + if(newlevel < 1) + newlevel = 1; + if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level + newlevel = STRONG_MAX_LEVEL; + + if(chr) + { + chr->GiveLevel(newlevel); + chr->InitTalentForLevel(); + chr->SetUInt32Value(PLAYER_XP,0); + + if(oldlevel == newlevel) + ChatHandler(chr).SendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET); + else + if(oldlevel < newlevel) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_UP,newlevel-oldlevel); + else + if(oldlevel > newlevel) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_LEVEL_DOWN,newlevel-oldlevel); + } + else + { + // update level and XP at level, all other will be updated at loading + Tokens values; + Player::LoadValuesArrayFromDB(values,chr_guid); + Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel); + Player::SetUInt32ValueInArray(values,PLAYER_XP,0); + Player::SaveValuesArrayInDB(values,chr_guid); + } + + if(m_session->GetPlayer() != chr) // including chr==NULL + { + std::string nameLink = playerLink(name); + PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel); + } + return true; +} + +bool ChatHandler::HandleShowAreaCommand(const char* args) +{ + if (!*args) + return false; + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + int area = GetAreaFlagByAreaID(atoi((char*)args)); + int offset = area / 32; + uint32 val = (uint32)(1 << (area % 32)); + + if(area<0 || offset >= 128) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); + + SendSysMessage(LANG_EXPLORE_AREA); + return true; +} + +bool ChatHandler::HandleHideAreaCommand(const char* args) +{ + if (!*args) + return false; + + Player *chr = getSelectedPlayer(); + if (chr == NULL) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + int area = GetAreaFlagByAreaID(atoi((char*)args)); + int offset = area / 32; + uint32 val = (uint32)(1 << (area % 32)); + + if(area<0 || offset >= 128) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val)); + + SendSysMessage(LANG_UNEXPLORE_AREA); + return true; +} + +bool ChatHandler::HandleDebugUpdate(const char* args) +{ + if(!*args) + return false; + + uint32 updateIndex; + uint32 value; + + char* pUpdateIndex = strtok((char*)args, " "); + + Unit* chr = getSelectedUnit(); + if (chr == NULL) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(!pUpdateIndex) + { + return true; + } + updateIndex = atoi(pUpdateIndex); + //check updateIndex + if(chr->GetTypeId() == TYPEID_PLAYER) + { + if (updateIndex>=PLAYER_END) return true; + } + else + { + if (updateIndex>=UNIT_END) return true; + } + + char* pvalue = strtok(NULL, " "); + if (!pvalue) + { + value=chr->GetUInt32Value(updateIndex); + + PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value); + return true; + } + + value=atoi(pvalue); + + PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value); + + chr->SetUInt32Value(updateIndex,value); + + return true; +} + +bool ChatHandler::HandleBankCommand(const char* /*args*/) +{ + m_session->SendShowBank( m_session->GetPlayer()->GetGUID() ); + + return true; +} + +bool ChatHandler::HandleChangeWeather(const char* args) +{ + if(!*args) + return false; + + //Weather is OFF + if (!sWorld.getConfig(CONFIG_WEATHER)) + { + SendSysMessage(LANG_WEATHER_DISABLED); + SetSentErrorMessage(true); + return false; + } + + //*Change the weather of a cell + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand + float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather + + Player *player = m_session->GetPlayer(); + uint32 zoneid = player->GetZoneId(); + + Weather* wth = sWorld.FindWeather(zoneid); + + if(!wth) + wth = sWorld.AddWeather(zoneid); + if(!wth) + { + SendSysMessage(LANG_NO_WEATHER); + SetSentErrorMessage(true); + return false; + } + + wth->SetWeather(WeatherType(type), grade); + + return true; +} + +bool ChatHandler::HandleDebugSetValue(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + char* pz = strtok(NULL, " "); + + if (!px || !py) + return false; + + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = target->GetGUID(); + + uint32 Opcode = (uint32)atoi(px); + if(Opcode >= target->GetValuesCount()) + { + PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); + return false; + } + uint32 iValue; + float fValue; + bool isint32 = true; + if(pz) + isint32 = (bool)atoi(pz); + if(isint32) + { + iValue = (uint32)atoi(py); + sLog.outDebug(GetTrinityString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue); + target->SetUInt32Value( Opcode , iValue ); + PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue); + } + else + { + fValue = (float)atof(py); + sLog.outDebug(GetTrinityString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue); + target->SetFloatValue( Opcode , fValue ); + PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue); + } + + return true; +} + +bool ChatHandler::HandleDebugGetValue(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* pz = strtok(NULL, " "); + + if (!px) + return false; + + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = target->GetGUID(); + + uint32 Opcode = (uint32)atoi(px); + if(Opcode >= target->GetValuesCount()) + { + PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount()); + return false; + } + uint32 iValue; + float fValue; + bool isint32 = true; + if(pz) + isint32 = (bool)atoi(pz); + + if(isint32) + { + iValue = target->GetUInt32Value( Opcode ); + sLog.outDebug(GetTrinityString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue); + PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue); + } + else + { + fValue = target->GetFloatValue( Opcode ); + sLog.outDebug(GetTrinityString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue); + PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue); + } + + return true; +} + +bool ChatHandler::HandleDebugSet32Bit(const char* args) +{ + if(!*args) + return false; + + Unit* target = getSelectedUnit(); + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 Opcode = (uint32)atoi(px); + uint32 Value = (uint32)atoi(py); + if (Value > 32) //uint32 = 32 bits + return false; + + sLog.outDebug(GetTrinityString(LANG_SET_32BIT), Opcode, Value); + + uint32 iValue = Value ? 1 << (Value - 1) : 0; + target->SetUInt32Value( Opcode , iValue); + + PSendSysMessage(LANG_SET_32BIT_FIELD, Opcode, iValue); + return true; +} + +bool ChatHandler::HandleDebugMod32Value(const char* args) +{ + if(!*args) + return false; + + char* px = strtok((char*)args, " "); + char* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 Opcode = (uint32)atoi(px); + int Value = atoi(py); + + if(Opcode >= m_session->GetPlayer()->GetValuesCount()) + { + PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount()); + return false; + } + + sLog.outDebug(GetTrinityString(LANG_CHANGE_32BIT), Opcode, Value); + + int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode ); + + CurrentValue += Value; + m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue ); + + PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue); + + return true; +} + +bool ChatHandler::HandleTeleAddCommand(const char * args) +{ + if(!*args) + return false; + + Player *player=m_session->GetPlayer(); + if (!player) + return false; + + std::string name = args; + + if(objmgr.GetGameTele(name)) + { + SendSysMessage(LANG_COMMAND_TP_ALREADYEXIST); + SetSentErrorMessage(true); + return false; + } + + GameTele tele; + tele.position_x = player->GetPositionX(); + tele.position_y = player->GetPositionY(); + tele.position_z = player->GetPositionZ(); + tele.orientation = player->GetOrientation(); + tele.mapId = player->GetMapId(); + tele.name = name; + + if(objmgr.AddGameTele(tele)) + { + SendSysMessage(LANG_COMMAND_TP_ADDED); + } + else + { + SendSysMessage(LANG_COMMAND_TP_ADDEDERR); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleTeleDelCommand(const char * args) +{ + if(!*args) + return false; + + std::string name = args; + + if(!objmgr.DeleteGameTele(name)) + { + SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); + SetSentErrorMessage(true); + return false; + } + + SendSysMessage(LANG_COMMAND_TP_DELETED); + return true; +} + +bool ChatHandler::HandleListAurasCommand (const char * /*args*/) +{ + Unit *unit = getSelectedUnit(); + if(!unit) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + char const* talentStr = GetTrinityString(LANG_TALENT); + char const* passiveStr = GetTrinityString(LANG_PASSIVE); + + Unit::AuraMap const& uAuras = unit->GetAuras(); + PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); + for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) + { + bool talent = GetTalentSpellCost(itr->second->GetId()) > 0; + + char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()]; + + if (m_session) + { + std::ostringstream ss_name; + ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r"; + + PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(), + itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(), + itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), + ss_name.str().c_str(), + (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); + } + else + { + PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(), + itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(), + itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), + name, + (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); + } + } + for (int i = 0; i < TOTAL_AURAS; i++) + { + Unit::AuraEffectList const& uAuraList = unit->GetAurasByType(AuraType(i)); + if (uAuraList.empty()) continue; + PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i); + for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr) + { + char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()]; + + std::ostringstream ss_name; + ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r"; + + PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), + (*itr)->GetAmount()); + } + } + return true; +} + +bool ChatHandler::HandleResetAchievementsCommand (const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + uint64 guid = 0; + if (pName) + { + std::string name = extractPlayerNameFromLink(pName); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + guid = objmgr.GetPlayerGUIDByName(name); + player = objmgr.GetPlayer(guid); + } + else + { + player = getSelectedPlayer(); + if(player) + guid = player->GetGUID(); + } + + if(!player && !guid) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + return true; + } + + if(player) + player->GetAchievementMgr().Reset(); + else if(guid) + AchievementMgr::DeleteFromDB(GUID_LOPART(guid)); + + return true; +} + +bool ChatHandler::HandleResetHonorCommand (const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = extractPlayerNameFromLink(pName); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + player = objmgr.GetPlayer(guid); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + return true; + } + + player->SetUInt32Value(PLAYER_FIELD_KILLS, 0); + player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); + player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0); + player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); + player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); + + return true; +} + +static bool HandleResetStatsOrLevelHelper(Player* player) +{ + PlayerInfo const *info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); + if(!info) return false; + + ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass()); + if(!cEntry) + { + sLog.outError("Class %u not found in DBC (Wrong DBC files?)",player->getClass()); + return false; + } + + uint8 powertype = cEntry->powerType; + + // reset m_form if no aura + if(!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) + player->m_form = FORM_NONE; + + player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); + player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH ); + + player->setFactionForRace(player->getRace()); + + player->SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( player->getRace() ) | ( player->getClass() << 8 ) | ( player->getGender() << 16 ) | ( powertype << 24 ) ) ); + + // reset only if player not in some form; + if(player->m_form==FORM_NONE) + { + switch(player->getGender()) + { + case GENDER_FEMALE: + player->SetDisplayId(info->displayId_f); + player->SetNativeDisplayId(info->displayId_f); + break; + case GENDER_MALE: + player->SetDisplayId(info->displayId_m); + player->SetNativeDisplayId(info->displayId_m); + break; + default: + break; + } + } + + player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP ); + player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form); + + player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + + //-1 is default value + player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); + + //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000 ); + return true; +} + +bool ChatHandler::HandleResetLevelCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = extractPlayerNameFromLink(pName); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + player = objmgr.GetPlayer(guid); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(!HandleResetStatsOrLevelHelper(player)) + return false; + + // set starting level + uint32 start_level = player->getClass() != CLASS_DEATH_KNIGHT + ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) + : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); + + player->SetLevel(start_level); + player->InitRunes(); + player->InitStatsForLevel(true); + player->InitTaxiNodesForLevel(); + player->InitGlyphsForLevel(); + player->InitTalentForLevel(); + player->SetUInt32Value(PLAYER_XP,0); + + // reset level to summoned pet + Guardian* pet = player->GetGuardianPet(); + if(pet) + { + pet->InitStatsForLevel(1); + if(pet->isPet()) + ((Pet*)pet)->InitTalentForLevel(); + } + return true; +} + +bool ChatHandler::HandleResetStatsCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + if (pName) + { + std::string name = extractPlayerNameFromLink(pName); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint64 guid = objmgr.GetPlayerGUIDByName(name); + player = objmgr.GetPlayer(guid); + } + else + player = getSelectedPlayer(); + + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(!HandleResetStatsOrLevelHelper(player)) + return false; + + player->InitRunes(); + player->InitStatsForLevel(true); + player->InitTaxiNodesForLevel(); + player->InitGlyphsForLevel(); + player->InitTalentForLevel(); + + return true; +} + +bool ChatHandler::HandleResetSpellsCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + uint64 playerGUID = 0; + if (pName) + { + std::string name = extractPlayerNameFromLink(pName); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(name.c_str()); + if(!player) + playerGUID = objmgr.GetPlayerGUIDByName(name); + } + else + player = getSelectedPlayer(); + + if(!player && !playerGUID) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if(player) + { + player->resetSpells(); + + ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS); + if(m_session->GetPlayer()!=player) + PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(player).c_str()); + } + else + { + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID)); + PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName); + } + + return true; +} + +bool ChatHandler::HandleResetTalentsCommand(const char * args) +{ + char* pName = strtok((char*)args, ""); + Player *player = NULL; + uint64 playerGUID = 0; + if (pName) + { + std::string name = extractPlayerNameFromLink(pName); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + player = objmgr.GetPlayer(name.c_str()); + if(!player) + playerGUID = objmgr.GetPlayerGUIDByName(name); + } + else + player = getSelectedPlayer(); + + if(player) + { + player->resetTalents(true); + + ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS); + if(m_session->GetPlayer()!=player) + PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str()); + + return true; + } + else if (playerGUID) + { + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) ); + std::string nameLink = playerLink(pName); + PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str()); + return true; + } + // Try reset talenents as Hunter Pet + Creature* creature = getSelectedCreature(); + if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET) + { + ((Pet *)creature)->resetTalents(true); + Unit *owner = creature->GetOwner(); + if (owner && owner->GetTypeId() == TYPEID_PLAYER) + { + player = (Player *)owner; + ChatHandler(player).SendSysMessage(LANG_RESET_PET_TALENTS); + if(m_session->GetPlayer()!=player) + PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(player).c_str()); + } + return true; + } + + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; +} + +bool ChatHandler::HandleResetAllCommand(const char * args) +{ + if(!*args) + return false; + + std::string casename = args; + + AtLoginFlags atLogin; + + // Command specially created as single command to prevent using short case names + if(casename=="spells") + { + atLogin = AT_LOGIN_RESET_SPELLS; + sWorld.SendWorldText(LANG_RESETALL_SPELLS); + } + else if(casename=="talents") + { + atLogin = AT_LOGIN_RESET_TALENTS; + sWorld.SendWorldText(LANG_RESETALL_TALENTS); + } + else + { + PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args); + SetSentErrorMessage(true); + return false; + } + + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin); + HashMapHolder::MapType const& plist = ObjectAccessor::Instance().GetPlayers(); + for(HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) + itr->second->SetAtLoginFlag(atLogin); + + return true; +} + +bool ChatHandler::HandleServerShutDownCancelCommand(const char* args) +{ + sWorld.ShutdownCancel(); + return true; +} + +bool ChatHandler::HandleServerShutDownCommand(const char* args) +{ + if(!*args) + return false; + + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) + { + int32 exitcode = atoi (exitcode_str); + + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) + return false; + + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) + return false; + + sWorld.ShutdownServ (time, 0, exitcode); + } + else + sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE); + return true; +} + +bool ChatHandler::HandleServerRestartCommand(const char* args) +{ + if(!*args) + return false; + + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) + { + int32 exitcode = atoi (exitcode_str); + + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) + return false; + + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) + return false; + + sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode); + } + else + sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); + return true; +} + +bool ChatHandler::HandleServerIdleRestartCommand(const char* args) +{ + if(!*args) + return false; + + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) + { + int32 exitcode = atoi (exitcode_str); + + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) + return false; + + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) + return false; + + sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode); + } + else + sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE); + return true; +} + +bool ChatHandler::HandleServerIdleShutDownCommand(const char* args) +{ + if(!*args) + return false; + + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) + { + int32 exitcode = atoi (exitcode_str); + + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) + return false; + + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) + return false; + + sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode); + } + else + sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE); + return true; +} + +bool ChatHandler::HandleQuestAdd(const char* args) +{ + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // .addquest #entry' + // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hquest"); + if(!cId) + return false; + + uint32 entry = atol(cId); + + Quest const* pQuest = objmgr.GetQuestTemplate(entry); + + if(!pQuest) + { + PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND,entry); + SetSentErrorMessage(true); + return false; + } + + // check item starting quest (it can work incorrectly if added without item in inventory) + for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) + { + ItemPrototype const *pProto = sItemStorage.LookupEntry(id); + if (!pProto) + continue; + + if (pProto->StartQuest == entry) + { + PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId); + SetSentErrorMessage(true); + return false; + } + } + + // ok, normal (creature/GO starting) quest + if( player->CanAddQuest( pQuest, true ) ) + { + player->AddQuest( pQuest, NULL ); + + if ( player->CanCompleteQuest( entry ) ) + player->CompleteQuest( entry ); + } + + return true; +} + +bool ChatHandler::HandleQuestRemove(const char* args) +{ + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // .removequest #entry' + // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hquest"); + if(!cId) + return false; + + uint32 entry = atol(cId); + + Quest const* pQuest = objmgr.GetQuestTemplate(entry); + + if(!pQuest) + { + PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); + SetSentErrorMessage(true); + return false; + } + + // remove all quest entries for 'entry' from quest log + for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot ) + { + uint32 quest = player->GetQuestSlotQuestId(slot); + if(quest==entry) + { + player->SetQuestSlot(slot,0); + + // we ignore unequippable quest items in this case, its' still be equipped + player->TakeQuestSourceItem( quest, false ); + } + } + + // set quest status to not started (will updated in DB at next save) + player->SetQuestStatus( entry, QUEST_STATUS_NONE); + + // reset rewarded for restart repeatable quest + player->getQuestStatusMap()[entry].m_rewarded = false; + + SendSysMessage(LANG_COMMAND_QUEST_REMOVED); + return true; +} + +bool ChatHandler::HandleQuestComplete(const char* args) +{ + Player* player = getSelectedPlayer(); + if(!player) + { + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + // .quest complete #entry + // number or [name] Shift-click form |color|Hquest:quest_id|h[name]|h|r + char* cId = extractKeyFromLink((char*)args,"Hquest"); + if(!cId) + return false; + + uint32 entry = atol(cId); + + Quest const* pQuest = objmgr.GetQuestTemplate(entry); + + // If player doesn't have the quest + if(!pQuest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) + { + PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); + SetSentErrorMessage(true); + return false; + } + + // Add quest items for quests that require items + for(uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x) + { + uint32 id = pQuest->ReqItemId[x]; + uint32 count = pQuest->ReqItemCount[x]; + if(!id || !count) + continue; + + uint32 curItemCount = player->GetItemCount(id,true); + + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, id, count-curItemCount ); + if( msg == EQUIP_ERR_OK ) + { + Item* item = player->StoreNewItem( dest, id, true); + player->SendNewItem(item,count-curItemCount,true,false); + } + } + + // All creature/GO slain/casted (not required, but otherwise it will display "Creature slain 0/10") + for(uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++) + { + uint32 creature = pQuest->ReqCreatureOrGOId[i]; + uint32 creaturecount = pQuest->ReqCreatureOrGOCount[i]; + + if(uint32 spell_id = pQuest->ReqSpell[i]) + { + for(uint16 z = 0; z < creaturecount; ++z) + player->CastedCreatureOrGO(creature,0,spell_id); + } + else if(creature > 0) + { + for(uint16 z = 0; z < creaturecount; ++z) + player->KilledMonster(creature,0); + } + else if(creature < 0) + { + for(uint16 z = 0; z < creaturecount; ++z) + player->CastedCreatureOrGO(creature,0,0); + } + } + + // If the quest requires reputation to complete + if(uint32 repFaction = pQuest->GetRepObjectiveFaction()) + { + uint32 repValue = pQuest->GetRepObjectiveValue(); + uint32 curRep = player->GetReputationMgr().GetReputation(repFaction); + if(curRep < repValue) + if(FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction)) + player->GetReputationMgr().SetReputation(factionEntry,repValue); + } + + // If the quest requires money + int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney(); + if(ReqOrRewMoney < 0) + player->ModifyMoney(-ReqOrRewMoney); + + player->CompleteQuest(entry); + return true; +} + +bool ChatHandler::HandleBanAccountCommand(const char* args) +{ + return HandleBanHelper(BAN_ACCOUNT,args); +} + +bool ChatHandler::HandleBanCharacterCommand(const char* args) +{ + return HandleBanHelper(BAN_CHARACTER,args); +} + +bool ChatHandler::HandleBanIPCommand(const char* args) +{ + return HandleBanHelper(BAN_IP,args); +} + +bool ChatHandler::HandleBanHelper(BanMode mode, const char* args) +{ + if (!*args) + return false; + + char* cnameOrIP = strtok ((char*)args, " "); + if (!cnameOrIP) + return false; + + std::string nameOrIP = cnameOrIP; + + char* duration = strtok (NULL," "); + if(!duration || !atoi(duration)) + return false; + + char* reason = strtok (NULL,""); + if(!reason) + return false; + + switch(mode) + { + case BAN_ACCOUNT: + if(!AccountMgr::normilizeString(nameOrIP)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str()); + SetSentErrorMessage(true); + return false; + } + break; + case BAN_CHARACTER: + if(!normalizePlayerName(nameOrIP)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + break; + case BAN_IP: + if(!IsIPAddress(nameOrIP.c_str())) + return false; + break; + } + + switch(sWorld.BanAccount(mode, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : "")) + { + case BAN_SUCCESS: + if(atoi(duration)>0) + PSendSysMessage(LANG_BAN_YOUBANNED,nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration),true).c_str(),reason); + else + PSendSysMessage(LANG_BAN_YOUPERMBANNED,nameOrIP.c_str(),reason); + break; + case BAN_SYNTAX_ERROR: + return false; + case BAN_NOTFOUND: + switch(mode) + { + default: + PSendSysMessage(LANG_BAN_NOTFOUND,"account",nameOrIP.c_str()); + break; + case BAN_CHARACTER: + PSendSysMessage(LANG_BAN_NOTFOUND,"character",nameOrIP.c_str()); + break; + case BAN_IP: + PSendSysMessage(LANG_BAN_NOTFOUND,"ip",nameOrIP.c_str()); + break; + } + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleUnBanAccountCommand(const char* args) +{ + return HandleUnBanHelper(BAN_ACCOUNT,args); +} + +bool ChatHandler::HandleUnBanCharacterCommand(const char* args) +{ + return HandleUnBanHelper(BAN_CHARACTER,args); +} + +bool ChatHandler::HandleUnBanIPCommand(const char* args) +{ + return HandleUnBanHelper(BAN_IP,args); +} + +bool ChatHandler::HandleUnBanHelper(BanMode mode, const char* args) +{ + if (!*args) + return false; + + char* cnameOrIP = strtok ((char*)args, " "); + if(!cnameOrIP) + return false; + + std::string nameOrIP = cnameOrIP; + + switch(mode) + { + case BAN_ACCOUNT: + if(!AccountMgr::normilizeString(nameOrIP)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,nameOrIP.c_str()); + SetSentErrorMessage(true); + return false; + } + break; + case BAN_CHARACTER: + if(!normalizePlayerName(nameOrIP)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + break; + case BAN_IP: + if(!IsIPAddress(nameOrIP.c_str())) + return false; + break; + } + + if(sWorld.RemoveBanAccount(mode,nameOrIP)) + PSendSysMessage(LANG_UNBAN_UNBANNED,nameOrIP.c_str()); + else + PSendSysMessage(LANG_UNBAN_ERROR,nameOrIP.c_str()); + + return true; +} + +bool ChatHandler::HandleBanInfoAccountCommand(const char* args) +{ + if (!*args) + return false; + + char* cname = strtok((char*)args, ""); + if(!cname) + return false; + + std::string account_name = cname; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 accountid = accmgr.GetId(account_name); + if(!accountid) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + return true; + } + + return HandleBanInfoHelper(accountid,account_name.c_str()); +} + +bool ChatHandler::HandleBanInfoCharacterCommand(const char* args) +{ + if (!*args) + return false; + + std::string name = extractPlayerNameFromLink((char*)args); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name); + if(!accountid) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + std::string accountname; + if(!accmgr.GetName(accountid,accountname)) + { + PSendSysMessage(LANG_BANINFO_NOCHARACTER); + return true; + } + + return HandleBanInfoHelper(accountid,accountname.c_str()); +} + +bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname) +{ + QueryResult *result = LoginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid); + if(!result) + { + PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname); + return true; + } + + PSendSysMessage(LANG_BANINFO_BANHISTORY,accountname); + do + { + Field* fields = result->Fetch(); + + time_t unbandate = time_t(fields[3].GetUInt64()); + bool active = false; + if(fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)) ) + active = true; + bool permanent = (fields[1].GetUInt64() == (uint64)0); + std::string bantime = permanent?GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[1].GetUInt64(), true); + PSendSysMessage(LANG_BANINFO_HISTORYENTRY, + fields[0].GetString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES):GetTrinityString(LANG_BANINFO_NO), fields[4].GetString(), fields[5].GetString()); + }while (result->NextRow()); + + delete result; + return true; +} + +bool ChatHandler::HandleBanInfoIPCommand(const char* args) +{ + if (!*args) + return false; + + char* cIP = strtok ((char*)args, ""); + if(!cIP) + return false; + + if (!IsIPAddress(cIP)) + return false; + + std::string IP = cIP; + + LoginDatabase.escape_string(IP); + QueryResult *result = LoginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str()); + if(!result) + { + PSendSysMessage(LANG_BANINFO_NOIP); + return true; + } + + Field *fields = result->Fetch(); + bool permanent = !fields[6].GetUInt64(); + PSendSysMessage(LANG_BANINFO_IPENTRY, + fields[0].GetString(), fields[1].GetString(), permanent ? GetTrinityString(LANG_BANINFO_NEVER):fields[2].GetString(), + permanent ? GetTrinityString(LANG_BANINFO_INFINITE):secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetString(), fields[5].GetString()); + delete result; + return true; +} + +bool ChatHandler::HandleBanListCharacterCommand(const char* args) +{ + LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + char* cFilter = strtok ((char*)args, " "); + if(!cFilter) + return false; + + std::string filter = cFilter; + LoginDatabase.escape_string(filter); + QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str()); + if (!result) + { + PSendSysMessage(LANG_BANLIST_NOCHARACTER); + return true; + } + + return HandleBanListHelper(result); +} + +bool ChatHandler::HandleBanListAccountCommand(const char* args) +{ + LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + char* cFilter = strtok((char*)args, " "); + std::string filter = cFilter ? cFilter : ""; + LoginDatabase.escape_string(filter); + + QueryResult* result; + + if(filter.empty()) + { + result = LoginDatabase.Query("SELECT account.id, username FROM account, account_banned" + " WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id"); + } + else + { + result = LoginDatabase.PQuery("SELECT account.id, username FROM account, account_banned" + " WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id", + filter.c_str()); + } + + if (!result) + { + PSendSysMessage(LANG_BANLIST_NOACCOUNT); + return true; + } + + return HandleBanListHelper(result); +} + +bool ChatHandler::HandleBanListHelper(QueryResult* result) +{ + PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); + + // Chat short output + if(m_session) + { + do + { + Field* fields = result->Fetch(); + uint32 accountid = fields[0].GetUInt32(); + + QueryResult* banresult = LoginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid); + if(banresult) + { + Field* fields2 = banresult->Fetch(); + PSendSysMessage("%s",fields2[0].GetString()); + delete banresult; + } + } while (result->NextRow()); + } + // Console wide output + else + { + SendSysMessage(LANG_BANLIST_ACCOUNTS); + SendSysMessage("==============================================================================="); + SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER); + do + { + SendSysMessage("-------------------------------------------------------------------------------"); + Field *fields = result->Fetch(); + uint32 account_id = fields[0].GetUInt32 (); + + std::string account_name; + + // "account" case, name can be get in same query + if(result->GetFieldCount() > 1) + account_name = fields[1].GetCppString(); + // "character" case, name need extract from another DB + else + accmgr.GetName (account_id,account_name); + + // No SQL injection. id is uint32. + QueryResult *banInfo = LoginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id); + if (banInfo) + { + Field *fields2 = banInfo->Fetch(); + do + { + time_t t_ban = fields2[0].GetUInt64(); + tm* aTm_ban = localtime(&t_ban); + + if (fields2[0].GetUInt64() == fields2[1].GetUInt64()) + { + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + fields2[2].GetString(),fields2[3].GetString()); + } + else + { + time_t t_unban = fields2[1].GetUInt64(); + tm* aTm_unban = localtime(&t_unban); + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, + fields2[2].GetString(),fields2[3].GetString()); + } + }while ( banInfo->NextRow() ); + delete banInfo; + } + }while( result->NextRow() ); + SendSysMessage("==============================================================================="); + } + + delete result; + return true; +} + +bool ChatHandler::HandleBanListIPCommand(const char* args) +{ + LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + char* cFilter = strtok((char*)args, " "); + std::string filter = cFilter ? cFilter : ""; + LoginDatabase.escape_string(filter); + + QueryResult* result; + + if(filter.empty()) + { + result = LoginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned" + " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())" + " ORDER BY unbandate" ); + } + else + { + result = LoginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned" + " WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'") + " ORDER BY unbandate",filter.c_str() ); + } + + if(!result) + { + PSendSysMessage(LANG_BANLIST_NOIP); + return true; + } + + PSendSysMessage(LANG_BANLIST_MATCHINGIP); + // Chat short output + if(m_session) + { + do + { + Field* fields = result->Fetch(); + PSendSysMessage("%s",fields[0].GetString()); + } while (result->NextRow()); + } + // Console wide output + else + { + SendSysMessage(LANG_BANLIST_IPS); + SendSysMessage("==============================================================================="); + SendSysMessage(LANG_BANLIST_IPS_HEADER); + do + { + SendSysMessage("-------------------------------------------------------------------------------"); + Field *fields = result->Fetch(); + time_t t_ban = fields[1].GetUInt64(); + tm* aTm_ban = localtime(&t_ban); + if ( fields[1].GetUInt64() == fields[2].GetUInt64() ) + { + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + fields[3].GetString(), fields[4].GetString()); + } + else + { + time_t t_unban = fields[2].GetUInt64(); + tm* aTm_unban = localtime(&t_unban); + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, + fields[3].GetString(), fields[4].GetString()); + } + }while( result->NextRow() ); + SendSysMessage("==============================================================================="); + } + + delete result; + return true; +} + +bool ChatHandler::HandleRespawnCommand(const char* /*args*/) +{ + Player* pl = m_session->GetPlayer(); + + // accept only explicitly selected target (not implicitly self targeting case) + Unit* target = getSelectedUnit(); + if(pl->GetSelection() && target) + { + if(target->GetTypeId()!=TYPEID_UNIT) + { + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(target->isDead()) + ((Creature*)target)->Respawn(); + return true; + } + + CellPair p(Trinity::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY())); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::RespawnDo u_do; + MaNGOS::WorldObjectWorker worker(pl,u_do); + + TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, obj_worker, *MapManager::Instance().GetMap(pl->GetMapId(), pl)); + + return true; +} + +bool ChatHandler::HandleGMFlyCommand(const char* args) +{ + if (!*args) + return false; + + Player *target = getSelectedPlayer(); + if (!target) + target = m_session->GetPlayer(); + + WorldPacket data(12); + if (strncmp(args, "on", 3) == 0) + data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + else if (strncmp(args, "off", 4) == 0) + data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + else + { + SendSysMessage(LANG_USE_BOL); + return false; + } + data.append(target->GetPackGUID()); + data << uint32(0); // unknown + target->SendMessageToSet(&data, true); + PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args); + return true; +} + +bool ChatHandler::HandlePDumpLoadCommand(const char *args) +{ + if (!*args) + return false; + + char * file = strtok((char*)args, " "); + if(!file) + return false; + + char * account = strtok(NULL, " "); + if(!account) + return false; + + std::string account_name = account; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 account_id = accmgr.GetId(account_name); + if(!account_id) + { + account_id = atoi(account); // use original string + if(!account_id) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + } + + if(!accmgr.GetName(account_id,account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + char* guid_str = NULL; + char* name_str = strtok(NULL, " "); + + std::string name; + if(name_str) + { + name = name_str; + // normalize the name if specified and check if it exists + if(!normalizePlayerName(name)) + { + PSendSysMessage(LANG_INVALID_CHARACTER_NAME); + SetSentErrorMessage(true); + return false; + } + + if(!ObjectMgr::IsValidName(name,true)) + { + PSendSysMessage(LANG_INVALID_CHARACTER_NAME); + SetSentErrorMessage(true); + return false; + } + + guid_str = strtok(NULL, " "); + } + + uint32 guid = 0; + + if(guid_str) + { + guid = atoi(guid_str); + if(!guid) + { + PSendSysMessage(LANG_INVALID_CHARACTER_GUID); + SetSentErrorMessage(true); + return false; + } + + if(objmgr.GetPlayerAccountIdByGUID(guid)) + { + PSendSysMessage(LANG_CHARACTER_GUID_IN_USE,guid); + SetSentErrorMessage(true); + return false; + } + } + + switch(PlayerDumpReader().LoadDump(file, account_id, name, guid)) + { + case DUMP_SUCCESS: + PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS); + break; + case DUMP_FILE_OPEN_ERROR: + PSendSysMessage(LANG_FILE_OPEN_FAIL,file); + SetSentErrorMessage(true); + return false; + case DUMP_FILE_BROKEN: + PSendSysMessage(LANG_DUMP_BROKEN,file); + SetSentErrorMessage(true); + return false; + case DUMP_TOO_MANY_CHARS: + PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id); + SetSentErrorMessage(true); + return false; + default: + PSendSysMessage(LANG_COMMAND_IMPORT_FAILED); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandlePDumpWriteCommand(const char *args) +{ + if (!*args) + return false; + + char* file = strtok((char*)args, " "); + char* p2 = strtok(NULL, " "); + + if(!file || !p2) + return false; + + uint32 guid; + // character name can't start from number + if (isNumeric(p2[0])) + guid = atoi(p2); + else + { + std::string name = extractPlayerNameFromLink(p2); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + guid = objmgr.GetPlayerGUIDByName(name); + } + + if(!objmgr.GetPlayerAccountIdByGUID(guid)) + { + PSendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + switch(PlayerDumpWriter().WriteDump(file, guid)) + { + case DUMP_SUCCESS: + PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS); + break; + case DUMP_FILE_OPEN_ERROR: + PSendSysMessage(LANG_FILE_OPEN_FAIL,file); + SetSentErrorMessage(true); + return false; + default: + PSendSysMessage(LANG_COMMAND_EXPORT_FAILED); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleMovegensCommand(const char* /*args*/) +{ + Unit* unit = getSelectedUnit(); + if(!unit) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_MOVEGENS_LIST,(unit->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature" ),unit->GetGUIDLow()); + + MotionMaster* mm = unit->GetMotionMaster(); + for(int i = 0; i < MAX_MOTION_SLOT; ++i) + { + MovementGenerator* mg = mm->GetMotionSlot(i); + if(!mg) + { + SendSysMessage("Empty"); + continue; + } + switch(mg->GetMovementGeneratorType()) + { + case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break; + case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break; + case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break; + case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break; + case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break; + case TARGETED_MOTION_TYPE: + { + if(unit->GetTypeId()==TYPEID_PLAYER) + { + TargetedMovementGenerator const* mgen = static_cast const*>(mg); + Unit* target = mgen->GetTarget(); + if(target) + PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER,target->GetName(),target->GetGUIDLow()); + else + SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); + } + else + { + TargetedMovementGenerator const* mgen = static_cast const*>(mg); + Unit* target = mgen->GetTarget(); + if(target) + PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE,target->GetName(),target->GetGUIDLow()); + else + SendSysMessage(LANG_MOVEGENS_TARGETED_NULL); + } + break; + } + case HOME_MOTION_TYPE: + if(unit->GetTypeId()==TYPEID_UNIT) + { + float x,y,z; + mg->GetDestination(x,y,z); + PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE,x,y,z); + } + else + SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); + break; + case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break; + case POINT_MOTION_TYPE: + { + float x,y,z; + mg->GetDestination(x,y,z); + PSendSysMessage(LANG_MOVEGENS_POINT,x,y,z); + break; + } + case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break; + case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break; + default: + PSendSysMessage(LANG_MOVEGENS_UNKNOWN,mg->GetMovementGeneratorType()); + break; + } + } + return true; +} + +bool ChatHandler::HandlePLimitCommand(const char *args) +{ + if(*args) + { + char* param = strtok((char*)args, " "); + if(!param) + return false; + + int l = strlen(param); + + if( strncmp(param,"player",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_PLAYER); + else if(strncmp(param,"moderator",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_MODERATOR); + else if(strncmp(param,"gamemaster",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_GAMEMASTER); + else if(strncmp(param,"administrator",l) == 0 ) + sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); + else if(strncmp(param,"reset",l) == 0 ) + sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) ); + else + { + int val = atoi(param); + if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR; + + sWorld.SetPlayerLimit(val); + } + + // kick all low security level players + if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER) + sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); + } + + uint32 pLimit = sWorld.GetPlayerAmountLimit(); + AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); + char const* secName = ""; + switch(allowedAccountType) + { + case SEC_PLAYER: secName = "Player"; break; + case SEC_MODERATOR: secName = "Moderator"; break; + case SEC_GAMEMASTER: secName = "Gamemaster"; break; + case SEC_ADMINISTRATOR: secName = "Administrator"; break; + default: secName = ""; break; + } + + PSendSysMessage("Player limits: amount %u, min. security level %s.",pLimit,secName); + + return true; +} + +bool ChatHandler::HandleCastCommand(const char* args) +{ + if(!*args) + return false; + + Unit* target = getSelectedUnit(); + + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell) + return false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo) + return false; + + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + m_session->GetPlayer()->CastSpell(target,spell,triggered); + + return true; +} + +bool ChatHandler::HandleCastBackCommand(const char* args) +{ + Creature* caster = getSelectedCreature(); + + if(!caster) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell || !sSpellStore.LookupEntry(spell)) + return false; + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + // update orientation at server + caster->SetOrientation(caster->GetAngle(m_session->GetPlayer())); + + // and client + WorldPacket data; + caster->BuildHeartBeatMsg(&data); + caster->SendMessageToSet(&data,true); + + caster->CastSpell(m_session->GetPlayer(),spell,triggered); + + return true; +} + +bool ChatHandler::HandleCastDistCommand(const char* args) +{ + if(!*args) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell) + return false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo) + return false; + + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + char *distStr = strtok(NULL, " "); + + float dist = 0; + + if(distStr) + sscanf(distStr, "%f", &dist); + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + float x,y,z; + m_session->GetPlayer()->GetClosePoint(x,y,z,dist); + + m_session->GetPlayer()->CastSpell(x,y,z,spell,triggered); + return true; +} + +bool ChatHandler::HandleCastTargetCommand(const char* args) +{ + Creature* caster = getSelectedCreature(); + + if(!caster) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + if(!caster->getVictim()) + { + SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell || !sSpellStore.LookupEntry(spell)) + return false; + + char* trig_str = strtok(NULL, " "); + if(trig_str) + { + int l = strlen(trig_str); + if(strncmp(trig_str,"triggered",l) != 0 ) + return false; + } + + bool triggered = (trig_str != NULL); + + // update orientation at server + caster->SetOrientation(caster->GetAngle(m_session->GetPlayer())); + + // and client + WorldPacket data; + caster->BuildHeartBeatMsg(&data); + caster->SendMessageToSet(&data,true); + + caster->CastSpell(caster->getVictim(),spell,triggered); + + return true; +} + +/* +ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator +Without this function 3rd party scripting library will get linking errors (unresolved external) +when attempting to use the PointMovementGenerator +*/ +bool ChatHandler::HandleComeToMeCommand(const char *args) +{ + char* newFlagStr = strtok((char*)args, " "); + + if(!newFlagStr) + return false; + + uint32 newFlags = (uint32)strtoul(newFlagStr, NULL, 0); + + Creature* caster = getSelectedCreature(); + if(!caster) + { + m_session->GetPlayer()->SetUnitMovementFlags(newFlags); + SendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } + + caster->SetUnitMovementFlags(newFlags); + + Player* pl = m_session->GetPlayer(); + + caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ()); + return true; +} + +bool ChatHandler::HandleCastSelfCommand(const char* args) +{ + if(!*args) + return false; + + Unit* target = getSelectedUnit(); + + if(!target) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spell = extractSpellIdFromLink((char*)args); + if(!spell) + return false; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); + if(!spellInfo) + return false; + + if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer())) + { + PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spell); + SetSentErrorMessage(true); + return false; + } + + target->CastSpell(target,spell,false); + + return true; +} + +std::string GetTimeString(uint32 time) +{ + uint16 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE; + std::ostringstream ss; + if(days) ss << days << "d "; + if(hours) ss << hours << "h "; + ss << minute << "m"; + return ss.str(); +} + +bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) +{ + Player* player = getSelectedPlayer(); + if (!player) player = m_session->GetPlayer(); + uint32 counter = 0; + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr) + { + InstanceSave *save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + counter++; + } + } + PSendSysMessage("player binds: %d", counter); + counter = 0; + Group *group = player->GetGroup(); + if(group) + { + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + Group::BoundInstancesMap &binds = group->GetBoundInstances(i); + for(Group::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end(); ++itr) + { + InstanceSave *save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + counter++; + } + } + } + PSendSysMessage("group binds: %d", counter); + + return true; +} + +bool ChatHandler::HandleInstanceUnbindCommand(const char* args) +{ + if(!*args) + return false; + + std::string cmd = args; + if(cmd == "all") + { + Player* player = getSelectedPlayer(); + if (!player) player = m_session->GetPlayer(); + uint32 counter = 0; + for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) + { + Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) + { + if(itr->first != player->GetMapId()) + { + InstanceSave *save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + player->UnbindInstance(itr, i); + counter++; + } + else + ++itr; + } + } + PSendSysMessage("instances unbound: %d", counter); + } + return true; +} + +bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/) +{ + PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances()); + PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances()); + PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves()); + PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal()); + PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal()); + return true; +} + +bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) +{ + Player* pl = m_session->GetPlayer(); + + Map* map = pl->GetMap(); + if (!map->IsDungeon()) + { + PSendSysMessage("Map is not a dungeon."); + SetSentErrorMessage(true); + return false; + } + + if (!((InstanceMap*)map)->GetInstanceData()) + { + PSendSysMessage("Map has no instance data."); + SetSentErrorMessage(true); + return false; + } + + ((InstanceMap*)map)->GetInstanceData()->SaveToDB(); + return true; +} + +/// Display the list of GMs +bool ChatHandler::HandleGMListFullCommand(const char* /*args*/) +{ + ///- Get the accounts with GM Level >0 + QueryResult *result = LoginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" ); + if(result) + { + SendSysMessage(LANG_GMLIST); + SendSysMessage("========================"); + SendSysMessage(LANG_GMLIST_HEADER); + SendSysMessage("========================"); + + ///- Circle through them. Display username and GM level + do + { + Field *fields = result->Fetch(); + PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString()); + }while( result->NextRow() ); + + PSendSysMessage("========================"); + delete result; + } + else + PSendSysMessage(LANG_GMLIST_EMPTY); + return true; +} + +/// Define the 'Message of the day' for the realm +bool ChatHandler::HandleServerSetMotdCommand(const char* args) +{ + sWorld.SetMotd(args); + PSendSysMessage(LANG_MOTD_NEW, args); + return true; +} + +/// Set whether we accept new clients +bool ChatHandler::HandleServerSetClosedCommand(const char* args) +{ + std::string arg = args; + + if(args == "on") + { + SendSysMessage(LANG_WORLD_CLOSED); + sWorld.SetClosed(true); + return true; + } + if(args == "off") + { + SendSysMessage(LANG_WORLD_OPENED); + sWorld.SetClosed(false); + return true; + } + + SendSysMessage(LANG_USE_BOL); + SetSentErrorMessage(true); + return false; +} + +/// Set/Unset the expansion level for an account +bool ChatHandler::HandleAccountSetAddonCommand(const char* args) +{ + ///- Get the command line arguments + char *szAcc = strtok((char*)args," "); + char *szExp = strtok(NULL," "); + + if(!szAcc) + return false; + + std::string account_name; + uint32 account_id; + + if(!szExp) + { + Player* player = getSelectedPlayer(); + if(!player) + return false; + + account_id = player->GetSession()->GetAccountId(); + accmgr.GetName(account_id,account_name); + szExp = szAcc; + } + else + { + ///- Convert Account name to Upper Format + account_name = szAcc; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + account_id = accmgr.GetId(account_name); + if(!account_id) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + } + + // Let set addon state only for lesser (strong) security level + // or to self account + if (m_session && m_session->GetAccountId () != account_id && + HasLowerSecurityAccount (NULL,account_id,true)) + return false; + + int lev=atoi(szExp); //get int anyway (0 if error) + if(lev < 0) + return false; + + // No SQL injection + LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id); + PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev); + return true; +} + +//Send items by mail +bool ChatHandler::HandleSendItemsCommand(const char* args) +{ + if(!*args) + return false; + + // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] + + std::string name = extractPlayerNameFromLink((char*)args); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + char* tail1 = strtok(NULL, ""); + if(!tail1) + return false; + + char* msgSubject; + if(*tail1=='"') + msgSubject = strtok(tail1+1, "\""); + else + { + char* space = strtok(tail1, "\""); + if(!space) + return false; + msgSubject = strtok(NULL, "\""); + } + + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if(!tail2) + return false; + + char* msgText; + if(*tail2=='"') + msgText = strtok(tail2+1, "\""); + else + { + char* space = strtok(tail2, "\""); + if(!space) + return false; + msgText = strtok(NULL, "\""); + } + + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // extract items + typedef std::pair ItemPair; + typedef std::list< ItemPair > ItemPairs; + ItemPairs items; + + // get all tail string + char* tail = strtok(NULL, ""); + + // get from tail next item str + while(char* itemStr = strtok(tail, " ")) + { + // and get new tail + tail = strtok(NULL, ""); + + // parse item str + char* itemIdStr = strtok(itemStr, ":"); + char* itemCountStr = strtok(NULL, " "); + + uint32 item_id = atoi(itemIdStr); + if(!item_id) + return false; + + ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id); + if(!item_proto) + { + PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); + SetSentErrorMessage(true); + return false; + } + + uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1; + if(item_count < 1 || item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)) + { + PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id); + SetSentErrorMessage(true); + return false; + } + + while(item_count > item_proto->GetMaxStackSize()) + { + items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize())); + item_count -= item_proto->GetMaxStackSize(); + } + + items.push_back(ItemPair(item_id,item_count)); + + if(items.size() > MAX_MAIL_ITEMS) + { + PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); + SetSentErrorMessage(true); + return false; + } + } + + uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); + if(!receiver_guid) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + // from console show not existed sender + uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; + + uint32 messagetype = MAIL_NORMAL; + uint32 stationery = MAIL_STATIONERY_GM; + uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; + + Player *receiver = objmgr.GetPlayer(receiver_guid); + + // fill mail + MailItemsInfo mi; // item list preparing + + for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) + { + if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0)) + { + item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + } + } + + WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE); + + std::string nameLink = playerLink(name); + PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; +} + +///Send money by mail +bool ChatHandler::HandleSendMoneyCommand(const char* args) +{ + if (!*args) + return false; + + /// format: name "subject text" "mail text" money + + std::string name = extractPlayerNameFromLink((char*)args); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char* msgSubject; + if (*tail1=='"') + msgSubject = strtok(tail1+1, "\""); + else + { + char* space = strtok(tail1, "\""); + if (!space) + return false; + msgSubject = strtok(NULL, "\""); + } + + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char* msgText; + if (*tail2=='"') + msgText = strtok(tail2+1, "\""); + else + { + char* space = strtok(tail2, "\""); + if (!space) + return false; + msgText = strtok(NULL, "\""); + } + + if (!msgText) + return false; + + char* money_str = strtok(NULL, ""); + int32 money = money_str ? atoi(money_str) : 0; + if (money <= 0) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); + if (!receiver_guid) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + // from console show not existed sender + uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; + + uint32 messagetype = MAIL_NORMAL; + uint32 stationery = MAIL_STATIONERY_GM; + uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; + + Player *receiver = objmgr.GetPlayer(receiver_guid); + + WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE); + + std::string nameLink = playerLink(name); + PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; +} + +/// Send a message to a player in game +bool ChatHandler::HandleSendMessageCommand(const char* args) +{ + ///- Get the command line arguments + std::string name = extractPlayerNameFromLink((char*)args); + if(name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + char* msg_str = strtok(NULL, ""); + if(!msg_str) + return false; + + ///- Find the player and check that he is not logging out. + Player *rPlayer = objmgr.GetPlayer(name.c_str()); + if(!rPlayer) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(rPlayer->GetSession()->isLogingOut()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + ///- Send the message + //Use SendAreaTriggerMessage for fastest delivery. + rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str); + rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); + + //Confirmation message + std::string nameLink = playerLink(name); + PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str); + return true; +} + +bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/) +{ + sBattleGroundMgr.DistributeArenaPoints(); + return true; +} + +bool ChatHandler::HandleModifyGenderCommand(const char *args) +{ + if(!*args) + return false; + + Player *player = getSelectedPlayer(); + + if(!player) + { + PSendSysMessage(LANG_NO_PLAYER); + SetSentErrorMessage(true); + return false; + } + + PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); + if(!info) + return false; + + char const* gender_str = (char*)args; + int gender_len = strlen(gender_str); + + Gender gender; + + if(!strncmp(gender_str, "male", gender_len)) // MALE + { + if(player->getGender() == GENDER_MALE) + return true; + + gender = GENDER_MALE; + } + else if (!strncmp(gender_str, "female", gender_len)) // FEMALE + { + if(player->getGender() == GENDER_FEMALE) + return true; + + gender = GENDER_FEMALE; + } + else + { + SendSysMessage(LANG_MUST_MALE_OR_FEMALE); + SetSentErrorMessage(true); + return false; + } + + // Set gender + player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); + player->SetByteValue(PLAYER_BYTES_3, 0, gender); + + // Change display ID + player->SetDisplayId(gender ? info->displayId_f : info->displayId_m); + player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m); + + char const* gender_full = gender ? "female" : "male"; + + PSendSysMessage(LANG_YOU_CHANGE_GENDER, GetNameLink(player).c_str(), gender_full); + + if (needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetNameLink().c_str()); + + return true; +} + +/*------------------------------------------ + *-------------TRINITY---------------------- + *-------------------------------------*/ + +bool ChatHandler::HandlePlayAllCommand(const char* args) +{ + if(!*args) + return false; + + uint32 soundId = atoi((char*)args); + + if(!sSoundEntriesStore.LookupEntry(soundId)) + { + PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); + SetSentErrorMessage(true); + return false; + } + + WorldPacket data(SMSG_PLAY_SOUND, 4); + data << uint32(soundId) << m_session->GetPlayer()->GetGUID(); + sWorld.SendGlobalMessage(&data); + + PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); + return true; +} + +bool ChatHandler::HandleFreezeCommand(const char *args) +{ + std::string name; + Player* player; + char* TargetName = strtok((char*)args, " "); //get entered name + if (!TargetName) //if no name entered use target + { + player = getSelectedPlayer(); + if (player) //prevent crash with creature as target + { + name = player->GetName(); + normalizePlayerName(name); + } + } + else // if name entered + { + name = TargetName; + normalizePlayerName(name); + player = objmgr.GetPlayer(name.c_str()); //get player by name + } + + if (!player) + { + SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + if (player==m_session->GetPlayer()) + { + SendSysMessage(LANG_COMMAND_FREEZE_ERROR); + return true; + } + + //effect + if ((player) && (!(player==m_session->GetPlayer()))) + { + PSendSysMessage(LANG_COMMAND_FREEZE,name.c_str()); + + //stop combat + make player unattackable + duel stop + stop some spells + player->setFaction(35); + player->CombatStop(); + if(player->IsNonMeleeSpellCasted(true)) + player->InterruptNonMeleeSpells(true); + player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + player->SetUInt32Value(PLAYER_DUEL_TEAM, 1); + + //if player class = hunter || warlock remove pet if alive + if((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) + { + if(Pet* pet = player->GetPet()) + { + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + // not let dismiss dead pet + if(pet && pet->isAlive()) + player->RemovePet(pet,PET_SAVE_NOT_IN_SLOT); + } + } + + //m_session->GetPlayer()->CastSpell(player,spellID,false); + SpellEntry const *spellInfo = sSpellStore.LookupEntry( 9454 ); + Aura *Aur = new Aura(spellInfo, 1, NULL, player); + player->AddAura(Aur); + + //save player + player->SaveToDB(); + } + return true; +} + +bool ChatHandler::HandleUnFreezeCommand(const char *args) +{ + std::string name; + Player* player; + char* TargetName = strtok((char*)args, " "); //get entered name + if (!TargetName) //if no name entered use target + { + player = getSelectedPlayer(); + if (player) //prevent crash with creature as target + { + name = player->GetName(); + } + } + + else // if name entered + { + name = TargetName; + normalizePlayerName(name); + player = objmgr.GetPlayer(name.c_str()); //get player by name + } + + //effect + if (player) + { + PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str()); + + //Reset player faction + allow combat + allow duels + player->setFactionForRace(player->getRace()); + player->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + //allow movement and spells + player->RemoveAurasDueToSpell(9454); + + //save player + player->SaveToDB(); + } + + if (!player) + { + if (TargetName) + { + //check for offline players + QueryResult *result = CharacterDatabase.PQuery("SELECT characters.guid FROM `characters` WHERE characters.name = '%s'",name.c_str()); + if(!result) + { + SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + //if player found: delete his freeze aura + Field *fields=result->Fetch(); + uint64 pguid = fields[0].GetUInt64(); + delete result; + CharacterDatabase.PQuery("DELETE FROM `character_aura` WHERE character_aura.spell = 9454 AND character_aura.guid = '%u'",pguid); + PSendSysMessage(LANG_COMMAND_UNFREEZE,name.c_str()); + return true; + } + else + { + SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + } + + return true; +} + +bool ChatHandler::HandleListFreezeCommand(const char* args) +{ + //Get names from DB + QueryResult *result = CharacterDatabase.PQuery("SELECT characters.name FROM `characters` LEFT JOIN `character_aura` ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454"); + if(!result) + { + SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); + return true; + } + //Header of the names + PSendSysMessage(LANG_COMMAND_LIST_FREEZE); + + //Output of the results + do + { + Field *fields = result->Fetch(); + std::string fplayers = fields[0].GetCppString(); + PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS,fplayers.c_str()); + } while (result->NextRow()); + + delete result; + return true; +} + +bool ChatHandler::HandleGroupLeaderCommand(const char* args) +{ + Player* plr = NULL; + Group* group = NULL; + uint64 guid = 0; + char* cname = strtok((char*)args, " "); + + if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid)) + if(group && group->GetLeaderGUID() != guid) + group->ChangeLeader(guid); + + return true; +} + +bool ChatHandler::HandleGroupDisbandCommand(const char* args) +{ + Player* plr = NULL; + Group* group = NULL; + uint64 guid = 0; + char* cname = strtok((char*)args, " "); + + if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid)) + if(group) + group->Disband(); + + return true; +} + +bool ChatHandler::HandleGroupRemoveCommand(const char* args) +{ + Player* plr = NULL; + Group* group = NULL; + uint64 guid = 0; + char* cname = strtok((char*)args, " "); + + if(GetPlayerGroupAndGUIDByName(cname, plr, group, guid, true)) + if(group) + group->RemoveMember(guid, 0); + + return true; +} + +bool ChatHandler::HandlePossessCommand(const char* args) +{ + Unit* pUnit = getSelectedUnit(); + if(!pUnit) + return false; + + m_session->GetPlayer()->CastSpell(pUnit, 530, true); + return true; +} + +bool ChatHandler::HandleUnPossessCommand(const char* args) +{ + Unit* pUnit = getSelectedUnit(); + if(!pUnit) pUnit = m_session->GetPlayer(); + + pUnit->RemoveAurasByType(SPELL_AURA_MOD_CHARM); + pUnit->RemoveAurasByType(SPELL_AURA_MOD_POSSESS_PET); + pUnit->RemoveAurasByType(SPELL_AURA_MOD_POSSESS); + + return true; +} + +bool ChatHandler::HandleBindSightCommand(const char* args) +{ + Unit* pUnit = getSelectedUnit(); + if (!pUnit) + return false; + + m_session->GetPlayer()->CastSpell(pUnit, 6277, true); + return true; +} + +bool ChatHandler::HandleUnbindSightCommand(const char* args) +{ + if (m_session->GetPlayer()->isPossessing()) + return false; + + m_session->GetPlayer()->StopCastingBindSight(); + return true; +} + diff --git a/src/game/Unit.h b/src/game/Unit.h index 9c90b32c90d..2ab00f23407 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1,1646 +1,1646 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2009 Trinity - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __UNIT_H -#define __UNIT_H - -#include "Common.h" -#include "Object.h" -#include "Opcodes.h" -#include "SpellAuraDefines.h" -#include "UpdateFields.h" -#include "SharedDefines.h" -#include "ThreatManager.h" -#include "HostilRefManager.h" -#include "FollowerReference.h" -#include "FollowerRefManager.h" -#include "Utilities/EventProcessor.h" -#include "MotionMaster.h" -#include "DBCStructure.h" -#include - -#define WORLD_TRIGGER 12999 - -enum SpellInterruptFlags -{ - SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, // why need this for instant? - SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back - SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, // interrupt - SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, // no - SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage - //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph" -}; - -enum SpellChannelInterruptFlags -{ - CHANNEL_FLAG_DAMAGE = 0x0002, - CHANNEL_FLAG_MOVEMENT = 0x0008, - CHANNEL_FLAG_TURNING = 0x0010, - CHANNEL_FLAG_DAMAGE2 = 0x0080, - CHANNEL_FLAG_DELAY = 0x4000 -}; - -enum SpellAuraInterruptFlags -{ - AURA_INTERRUPT_FLAG_HITBYSPELL = 0x00000001, // 0 removed when getting hit by a negative spell? - AURA_INTERRUPT_FLAG_DAMAGE = 0x00000002, // 1 removed by any damage - AURA_INTERRUPT_FLAG_CC = 0x00000004, // 2 crowd control - AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement - AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning - AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat - AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by unmounting - AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water - AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water - AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing - AURA_INTERRUPT_FLAG_TALK = 0x00000400, // 10 talk to npc / loot? action on creature - AURA_INTERRUPT_FLAG_USE = 0x00000800, // 11 mine/use/open action on gameobject - AURA_INTERRUPT_FLAG_ATTACK = 0x00001000, // 12 removed by attacking - AURA_INTERRUPT_FLAG_CAST = 0x00002000, // 13 ??? - AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14 - AURA_INTERRUPT_FLAG_TRANSFORM = 0x00008000, // 15 removed by transform? - AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16 - AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed - AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up - AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported - AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to loose selection on you - AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21 - AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22 - AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat - AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000 // 24 removed by any direct damage -}; - -enum SpellModOp -{ - SPELLMOD_DAMAGE = 0, - SPELLMOD_DURATION = 1, - SPELLMOD_THREAT = 2, - SPELLMOD_EFFECT1 = 3, - SPELLMOD_CHARGES = 4, - SPELLMOD_RANGE = 5, - SPELLMOD_RADIUS = 6, - SPELLMOD_CRITICAL_CHANCE = 7, - SPELLMOD_ALL_EFFECTS = 8, - SPELLMOD_NOT_LOSE_CASTING_TIME = 9, - SPELLMOD_CASTING_TIME = 10, - SPELLMOD_COOLDOWN = 11, - SPELLMOD_EFFECT2 = 12, - SPELLMOD_IGNORE_ARMOR = 13, - SPELLMOD_COST = 14, - SPELLMOD_CRIT_DAMAGE_BONUS = 15, - SPELLMOD_RESIST_MISS_CHANCE = 16, - SPELLMOD_JUMP_TARGETS = 17, - SPELLMOD_CHANCE_OF_SUCCESS = 18, - SPELLMOD_ACTIVATION_TIME = 19, - SPELLMOD_EFFECT_PAST_FIRST = 20, - SPELLMOD_GLOBAL_COOLDOWN = 21, //TODO: GCD is not checked by server currently - SPELLMOD_DOT = 22, - SPELLMOD_EFFECT3 = 23, - SPELLMOD_SPELL_BONUS_DAMAGE = 24, - // spellmod 25 - SPELLMOD_PROC_PER_MINUTE = 26, - SPELLMOD_MULTIPLE_VALUE = 27, - SPELLMOD_RESIST_DISPEL_CHANCE = 28, - SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell - SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30 -}; - -#define MAX_SPELLMOD 32 - -enum SpellFacingFlags -{ - SPELL_FACING_FLAG_INFRONT = 0x0001 -}; - -#define BASE_MINDAMAGE 1.0f -#define BASE_MAXDAMAGE 2.0f -#define BASE_ATTACK_TIME 2000 - -// byte value (UNIT_FIELD_BYTES_1,0) -enum UnitStandStateType -{ - UNIT_STAND_STATE_STAND = 0, - UNIT_STAND_STATE_SIT = 1, - UNIT_STAND_STATE_SIT_CHAIR = 2, - UNIT_STAND_STATE_SLEEP = 3, - UNIT_STAND_STATE_SIT_LOW_CHAIR = 4, - UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5, - UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6, - UNIT_STAND_STATE_DEAD = 7, - UNIT_STAND_STATE_KNEEL = 8 -}; - -// byte flag value (UNIT_FIELD_BYTES_1,2) -enum UnitStandFlags -{ - UNIT_STAND_FLAGS_CREEP = 0x02, - UNIT_STAND_FLAGS_ALL = 0xFF -}; - -// byte flags value (UNIT_FIELD_BYTES_1,3) -enum UnitBytes1_Flags -{ - UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, - UNIT_BYTE1_FLAG_UNTRACKABLE = 0x04, - UNIT_BYTE1_FLAG_ALL = 0xFF -}; - -// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2 -enum ShapeshiftForm -{ - FORM_NONE = 0x00, - FORM_CAT = 0x01, - FORM_TREE = 0x02, - FORM_TRAVEL = 0x03, - FORM_AQUA = 0x04, - FORM_BEAR = 0x05, - FORM_AMBIENT = 0x06, - FORM_GHOUL = 0x07, - FORM_DIREBEAR = 0x08, - FORM_CREATUREBEAR = 0x0E, - FORM_CREATURECAT = 0x0F, - FORM_GHOSTWOLF = 0x10, - FORM_BATTLESTANCE = 0x11, - FORM_DEFENSIVESTANCE = 0x12, - FORM_BERSERKERSTANCE = 0x13, - FORM_TEST = 0x14, - FORM_ZOMBIE = 0x15, - FORM_METAMORPHOSIS = 0x16, - FORM_FLIGHT_EPIC = 0x1B, - FORM_SHADOW = 0x1C, - FORM_FLIGHT = 0x1D, - FORM_STEALTH = 0x1E, - FORM_MOONKIN = 0x1F, - FORM_SPIRITOFREDEMPTION = 0x20 -}; - -// low byte ( 0 from 0..3 ) of UNIT_FIELD_BYTES_2 -enum SheathState -{ - SHEATH_STATE_UNARMED = 0, // non prepared weapon - SHEATH_STATE_MELEE = 1, // prepared melee weapon - SHEATH_STATE_RANGED = 2 // prepared ranged weapon -}; - -// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitBytes2_Flags -{ - UNIT_BYTE2_FLAG_PVP = 0x01, - UNIT_BYTE2_FLAG_UNK1 = 0x02, - UNIT_BYTE2_FLAG_FFA_PVP = 0x04, - UNIT_BYTE2_FLAG_SANCTUARY = 0x08, - UNIT_BYTE2_FLAG_UNK4 = 0x10, - UNIT_BYTE2_FLAG_UNK5 = 0x20, - UNIT_BYTE2_FLAG_UNK6 = 0x40, - UNIT_BYTE2_FLAG_UNK7 = 0x80 -}; - -// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitRename -{ - UNIT_RENAME_NOT_ALLOWED = 0x02, - UNIT_RENAME_ALLOWED = 0x03 -}; - -#define CREATURE_MAX_SPELLS 8 -#define MAX_SPELL_CHARM 4 -#define MAX_SPELL_VEHICLE 6 -#define MAX_SPELL_POSSESS 8 -#define MAX_SPELL_CONTROL_BAR 10 - -enum Swing -{ - NOSWING = 0, - SINGLEHANDEDSWING = 1, - TWOHANDEDSWING = 2 -}; - -enum VictimState -{ - VICTIMSTATE_UNKNOWN1 = 0, - VICTIMSTATE_NORMAL = 1, - VICTIMSTATE_DODGE = 2, - VICTIMSTATE_PARRY = 3, - VICTIMSTATE_INTERRUPT = 4, - VICTIMSTATE_BLOCKS = 5, - VICTIMSTATE_EVADES = 6, - VICTIMSTATE_IS_IMMUNE = 7, - VICTIMSTATE_DEFLECTS = 8 -}; - -enum HitInfo -{ - HITINFO_NORMALSWING = 0x00000000, - HITINFO_UNK1 = 0x00000001, // req correct packet structure - HITINFO_NORMALSWING2 = 0x00000002, - HITINFO_LEFTSWING = 0x00000004, - HITINFO_UNK2 = 0x00000008, - HITINFO_MISS = 0x00000010, - HITINFO_ABSORB = 0x00000020, // absorbed damage - HITINFO_ABSORB2 = 0x00000040, // absorbed damage - HITINFO_RESIST = 0x00000080, // resisted atleast some damage - HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage - HITINFO_CRITICALHIT = 0x00000200, // critical hit - // 0x00000400 - // 0x00000800 - // 0x00001000 - HITINFO_BLOCK = 0x00002000, // blocked damage - // 0x00004000 - // 0x00008000 - HITINFO_GLANCING = 0x00010000, - HITINFO_CRUSHING = 0x00020000, - HITINFO_NOACTION = 0x00040000, // guessed - // 0x00080000 - // 0x00100000 - HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed - // 0x00400000 - HITINFO_UNK3 = 0x00800000 -}; - -//i would like to remove this: (it is defined in item.h -enum InventorySlot -{ - NULL_BAG = 0, - NULL_SLOT = 255 -}; - -struct FactionTemplateEntry; -struct SpellEntry; -struct SpellEntryExt; - -class Aura; -class AuraEffect; -class Creature; -class Spell; -class DynamicObject; -class GameObject; -class Item; -class Pet; -class Path; -class PetAura; -class Guardian; - -struct SpellImmune -{ - uint32 type; - uint32 spellId; -}; - -typedef std::list SpellImmuneList; - -enum UnitModifierType -{ - BASE_VALUE = 0, - BASE_PCT = 1, - TOTAL_VALUE = 2, - TOTAL_PCT = 3, - MODIFIER_TYPE_END = 4 -}; - -enum WeaponDamageRange -{ - MINDAMAGE, - MAXDAMAGE -}; - -enum DamageTypeToSchool -{ - RESISTANCE, - DAMAGE_DEALT, - DAMAGE_TAKEN -}; - -enum AuraRemoveMode -{ - AURA_NO_REMOVE_MODE = 0, - AURA_REMOVE_BY_DEFAULT, - AURA_REMOVE_BY_STACK, // change stack, single aura remove, - AURA_REMOVE_BY_CANCEL, - AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy - AURA_REMOVE_BY_EXPIRE, // dispel and absorb aura destroy - AURA_REMOVE_BY_DEATH -}; - -enum UnitMods -{ - UNIT_MOD_STAT_STRENGTH, // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_SPIRIT must be in existed order, it's accessed by index values of Stats enum. - UNIT_MOD_STAT_AGILITY, - UNIT_MOD_STAT_STAMINA, - UNIT_MOD_STAT_INTELLECT, - UNIT_MOD_STAT_SPIRIT, - UNIT_MOD_HEALTH, - UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum. - UNIT_MOD_RAGE, - UNIT_MOD_FOCUS, - UNIT_MOD_ENERGY, - UNIT_MOD_HAPPINESS, - UNIT_MOD_RUNE, - UNIT_MOD_RUNIC_POWER, - UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum. - UNIT_MOD_RESISTANCE_HOLY, - UNIT_MOD_RESISTANCE_FIRE, - UNIT_MOD_RESISTANCE_NATURE, - UNIT_MOD_RESISTANCE_FROST, - UNIT_MOD_RESISTANCE_SHADOW, - UNIT_MOD_RESISTANCE_ARCANE, - UNIT_MOD_ATTACK_POWER, - UNIT_MOD_ATTACK_POWER_RANGED, - UNIT_MOD_DAMAGE_MAINHAND, - UNIT_MOD_DAMAGE_OFFHAND, - UNIT_MOD_DAMAGE_RANGED, - UNIT_MOD_END, - // synonyms - UNIT_MOD_STAT_START = UNIT_MOD_STAT_STRENGTH, - UNIT_MOD_STAT_END = UNIT_MOD_STAT_SPIRIT + 1, - UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR, - UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1, - UNIT_MOD_POWER_START = UNIT_MOD_MANA, - UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1 -}; - -enum BaseModGroup -{ - CRIT_PERCENTAGE, - RANGED_CRIT_PERCENTAGE, - OFFHAND_CRIT_PERCENTAGE, - SHIELD_BLOCK_VALUE, - BASEMOD_END -}; - -enum BaseModType -{ - FLAT_MOD, - PCT_MOD -}; - -#define MOD_END (PCT_MOD+1) - -enum DeathState -{ - ALIVE = 0, - JUST_DIED = 1, - CORPSE = 2, - DEAD = 3, - JUST_ALIVED = 4, - DEAD_FALLING= 5 -}; - -enum UnitState -{ - UNIT_STAT_DIED = 0x00000001, - UNIT_STAT_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone - //UNIT_STAT_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone - UNIT_STAT_STUNNED = 0x00000008, - UNIT_STAT_ROAMING = 0x00000010, - UNIT_STAT_CHASE = 0x00000020, - //UNIT_STAT_SEARCHING = 0x00000040, - UNIT_STAT_FLEEING = 0x00000080, - UNIT_STAT_IN_FLIGHT = 0x00000100, // player is in flight mode - UNIT_STAT_FOLLOW = 0x00000200, - UNIT_STAT_ROOT = 0x00000400, - UNIT_STAT_CONFUSED = 0x00000800, - UNIT_STAT_DISTRACTED = 0x00001000, - UNIT_STAT_ISOLATED = 0x00002000, // area auras do not affect other players - UNIT_STAT_ATTACK_PLAYER = 0x00004000, - UNIT_STAT_CASTING = 0x00008000, - UNIT_STAT_POSSESSED = 0x00010000, - UNIT_STAT_CHARGING = 0x00020000, - UNIT_STAT_JUMPING = 0x00040000, - UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE), - UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING), - UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING), - UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE), - UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING), - UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) -}; - -enum UnitMoveType -{ - MOVE_WALK = 0, - MOVE_RUN = 1, - MOVE_RUN_BACK = 2, - MOVE_SWIM = 3, - MOVE_SWIM_BACK = 4, - MOVE_TURN_RATE = 5, - MOVE_FLIGHT = 6, - MOVE_FLIGHT_BACK = 7, - MOVE_PITCH_RATE = 8 -}; - -#define MAX_MOVE_TYPE 9 - -extern float baseMoveSpeed[MAX_MOVE_TYPE]; - -enum WeaponAttackType -{ - BASE_ATTACK = 0, - OFF_ATTACK = 1, - RANGED_ATTACK = 2, - MAX_ATTACK -}; - -enum CombatRating -{ - CR_WEAPON_SKILL = 0, - CR_DEFENSE_SKILL = 1, - CR_DODGE = 2, - CR_PARRY = 3, - CR_BLOCK = 4, - CR_HIT_MELEE = 5, - CR_HIT_RANGED = 6, - CR_HIT_SPELL = 7, - CR_CRIT_MELEE = 8, - CR_CRIT_RANGED = 9, - CR_CRIT_SPELL = 10, - CR_HIT_TAKEN_MELEE = 11, - CR_HIT_TAKEN_RANGED = 12, - CR_HIT_TAKEN_SPELL = 13, - CR_CRIT_TAKEN_MELEE = 14, - CR_CRIT_TAKEN_RANGED = 15, - CR_CRIT_TAKEN_SPELL = 16, - CR_HASTE_MELEE = 17, - CR_HASTE_RANGED = 18, - CR_HASTE_SPELL = 19, - CR_WEAPON_SKILL_MAINHAND = 20, - CR_WEAPON_SKILL_OFFHAND = 21, - CR_WEAPON_SKILL_RANGED = 22, - CR_EXPERTISE = 23, - CR_ARMOR_PENETRATION = 24 -}; - -#define MAX_COMBAT_RATING 25 - -enum DamageEffectType -{ - DIRECT_DAMAGE = 0, // used for normal weapon damage (not for class abilities or spells) - SPELL_DIRECT_DAMAGE = 1, // spell/class abilities damage - DOT = 2, - HEAL = 3, - NODAMAGE = 4, // used also in case when damage applied to health but not applied to spell channelInterruptFlags/etc - SELF_DAMAGE = 5 -}; - -enum UnitVisibility -{ - VISIBILITY_OFF = 0, // absolute, not detectable, GM-like, can see all other - VISIBILITY_ON = 1, - VISIBILITY_GROUP_STEALTH = 2, // detect chance, seen and can see group members - //VISIBILITY_GROUP_INVISIBILITY = 3, // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) - //VISIBILITY_GROUP_NO_DETECT = 4, // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break - VISIBILITY_RESPAWN = 5 // special totally not detectable visibility for force delete object at respawn command -}; - -// Value masks for UNIT_FIELD_FLAGS -enum UnitFlags -{ - UNIT_FLAG_UNK_0 = 0x00000001, - UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable - UNIT_FLAG_DISABLE_MOVE = 0x00000004, - UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state - UNIT_FLAG_RENAME = 0x00000010, - UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP - UNIT_FLAG_UNK_6 = 0x00000040, - UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE - UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100, // 2.0.8 - UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything - UNIT_FLAG_LOOTING = 0x00000400, // loot animation - UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 - UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 - UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 - UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8 - UNIT_FLAG_UNK_15 = 0x00008000, - UNIT_FLAG_UNK_16 = 0x00010000, - UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok - UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok - UNIT_FLAG_IN_COMBAT = 0x00080000, - UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag - UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. - UNIT_FLAG_CONFUSED = 0x00400000, - UNIT_FLAG_FLEEING = 0x00800000, - UNIT_FLAG_UNK_24 = 0x01000000, // used in spell Eyes of the Beast for pet... - UNIT_FLAG_NOT_SELECTABLE = 0x02000000, - UNIT_FLAG_SKINNABLE = 0x04000000, - UNIT_FLAG_MOUNT = 0x08000000, - UNIT_FLAG_UNK_28 = 0x10000000, - UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell - UNIT_FLAG_SHEATHE = 0x40000000, - UNIT_FLAG_UNK_31 = 0x80000000 -}; - -// Value masks for UNIT_FIELD_FLAGS_2 -enum UnitFlags2 -{ - UNIT_FLAG2_FEIGN_DEATH = 0x00000001, - UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) - UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, - UNIT_FLAG2_FORCE_MOVE = 0x00000040, - UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, - UNIT_FLAG2_DISARM_RANGED = 0x00000400, //this does not disable ranged weapon display (maybe additional flag needed?) - UNIT_FLAG2_REGENERATE_POWER = 0x00000800 -}; - -/// Non Player Character flags -enum NPCFlags -{ - UNIT_NPC_FLAG_NONE = 0x00000000, - UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100% - UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok - UNIT_NPC_FLAG_UNK1 = 0x00000004, - UNIT_NPC_FLAG_UNK2 = 0x00000008, - UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100% - UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // 100% - UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // 100% - UNIT_NPC_FLAG_VENDOR = 0x00000080, // 100% - UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // 100%, general goods vendor - UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // 100% - UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // guessed - UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // 100% - UNIT_NPC_FLAG_REPAIR = 0x00001000, // 100% - UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // 100% - UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // guessed - UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // guessed - UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // 100% - UNIT_NPC_FLAG_BANKER = 0x00020000, // 100% - UNIT_NPC_FLAG_PETITIONER = 0x00040000, // 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions - UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // 100% - UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // 100% - UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // 100% - UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% - UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode - UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) - UNIT_NPC_FLAG_GUARD = 0x10000000, // custom flag for guards - UNIT_NPC_FLAG_OUTDOORPVP = 0x20000000, // custom flag for outdoor pvp creatures -}; - -enum MoveFlags -{ - MOVEFLAG_NONE = 0x00000000, - MOVEFLAG_SLIDE = 0x00000002, - MOVEFLAG_MARCH_ON_SPOT = 0x00000004, - MOVEFLAG_JUMP = 0x00000008, - MOVEFLAG_WALK = 0x00000100, - MOVEFLAG_FLY = 0x00000200, //For dragon (+walk = glide) - MOVEFLAG_ORIENTATION = 0x00000400, //Fix orientation -}; - -enum MovementFlags -{ - MOVEMENTFLAG_NONE = 0x00000000, - MOVEMENTFLAG_FORWARD = 0x00000001, - MOVEMENTFLAG_BACKWARD = 0x00000002, - MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, - MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, - MOVEMENTFLAG_LEFT = 0x00000010, - MOVEMENTFLAG_RIGHT = 0x00000020, - MOVEMENTFLAG_PITCH_UP = 0x00000040, - MOVEMENTFLAG_PITCH_DOWN = 0x00000080, - MOVEMENTFLAG_WALK_MODE = 0x00000100, - MOVEMENTFLAG_ONTRANSPORT = 0x00000200, - MOVEMENTFLAG_LEVITATING = 0x00000400, - MOVEMENTFLAG_FLY_UNK1 = 0x00000800, - MOVEMENTFLAG_JUMPING = 0x00001000, - MOVEMENTFLAG_UNK4 = 0x00002000, - MOVEMENTFLAG_FALLING = 0x00004000, - // 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000 - MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also - MOVEMENTFLAG_FLY_UP = 0x00400000, - MOVEMENTFLAG_CAN_FLY = 0x00800000, - MOVEMENTFLAG_FLYING = 0x01000000, - MOVEMENTFLAG_FLYING2 = 0x02000000, // Actual flying mode - MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths - MOVEMENTFLAG_SPLINE2 = 0x08000000, // used for flight paths - MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water - MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive) - MOVEMENTFLAG_UNK3 = 0x40000000 -}; - -enum DiminishingLevels -{ - DIMINISHING_LEVEL_1 = 0, - DIMINISHING_LEVEL_2 = 1, - DIMINISHING_LEVEL_3 = 2, - DIMINISHING_LEVEL_IMMUNE = 3 -}; - -struct DiminishingReturn -{ - DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count) - : DRGroup(group), stack(0), hitTime(t), hitCount(count) - {} - - DiminishingGroup DRGroup:16; - uint16 stack:16; - uint32 hitTime; - uint32 hitCount; -}; - -enum MeleeHitOutcome -{ - MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY, - MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL -}; - -struct CleanDamage -{ - CleanDamage(uint32 _damage, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) : - damage(_damage), attackType(_attackType), hitOutCome(_hitOutCome) {} - - uint32 damage; - WeaponAttackType attackType; - MeleeHitOutcome hitOutCome; -}; - -// Struct for use in Unit::CalculateMeleeDamage -// Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode -struct CalcDamageInfo -{ - Unit *attacker; // Attacker - Unit *target; // Target for damage - uint32 damageSchoolMask; - uint32 damage; - uint32 absorb; - uint32 resist; - uint32 blocked_amount; - uint32 HitInfo; - uint32 TargetState; -// Helper - WeaponAttackType attackType; // - uint32 procAttacker; - uint32 procVictim; - uint32 procEx; - uint32 cleanDamage; // Used only fo rage calcultion - MeleeHitOutcome hitOutCome; // TODO: remove this field (need use TargetState) -}; - -// Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode -struct SpellNonMeleeDamage{ - SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask) - : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), schoolMask(_schoolMask), - absorb(0), resist(0), phusicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) - {} - - Unit *target; - Unit *attacker; - uint32 SpellID; - uint32 damage; - uint32 schoolMask; - uint32 absorb; - uint32 resist; - bool phusicalLog; - bool unused; - uint32 blocked; - uint32 HitInfo; - // Used for help - uint32 cleanDamage; -}; - -uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition); - -struct UnitActionBarEntry -{ - UnitActionBarEntry() : Raw(0) {} - - union - { - struct - { - uint16 SpellOrAction; - uint16 Type; - }; - struct - { - uint32 Raw; - }; - }; -}; - -#define MAX_DECLINED_NAME_CASES 5 - -struct DeclinedName -{ - std::string name[MAX_DECLINED_NAME_CASES]; -}; - -enum CurrentSpellTypes -{ - CURRENT_MELEE_SPELL = 0, - CURRENT_FIRST_NON_MELEE_SPELL = 1, // just counter - CURRENT_GENERIC_SPELL = 1, - CURRENT_AUTOREPEAT_SPELL = 2, - CURRENT_CHANNELED_SPELL = 3, - CURRENT_MAX_SPELL = 4 // just counter -}; - -enum ActiveStates -{ - ACT_PASSIVE = 0x0100, // 0x0100 - passive - ACT_DISABLED = 0x8100, // 0x8000 - castable - ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable - ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400 - ACT_REACTION = 0x0600, // 0x0200 | 0x0400 - ACT_DECIDE = 0x0001 // what is it? -}; - -enum ReactStates -{ - REACT_PASSIVE = 0, - REACT_DEFENSIVE = 1, - REACT_AGGRESSIVE = 2 -}; - -enum CommandStates -{ - COMMAND_STAY = 0, - COMMAND_FOLLOW = 1, - COMMAND_ATTACK = 2, - COMMAND_ABANDON = 3 -}; - -struct CharmSpellEntry -{ - uint16 spellId; - uint16 active; -}; - -typedef std::list SharedVisionList; - -struct TRINITY_DLL_SPEC CharmInfo -{ - public: - explicit CharmInfo(Unit* unit); - ~CharmInfo(); - uint32 GetPetNumber() const { return m_petnumber; } - void SetPetNumber(uint32 petnumber, bool statwindow); - - void SetCommandState(CommandStates st) { m_CommandState = st; } - CommandStates GetCommandState() { return m_CommandState; } - bool HasCommandState(CommandStates state) { return (m_CommandState == state); } - //void SetReactState(ReactStates st) { m_reactState = st; } - //ReactStates GetReactState() { return m_reactState; } - //bool HasReactState(ReactStates state) { return (m_reactState == state); } - - void InitPossessCreateSpells(); - void InitCharmCreateSpells(); - void InitPetActionBar(); - void InitEmptyActionBar(bool withAttack = true); - //return true if successful - bool AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate = ACT_DECIDE); - void ToggleCreatureAutocast(uint32 spellid, bool apply); - - UnitActionBarEntry* GetActionBarEntry(uint8 index) { return &(PetActionBar[index]); } - CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); } - private: - Unit* m_unit; - UnitActionBarEntry PetActionBar[10]; - CharmSpellEntry m_charmspells[4]; - CommandStates m_CommandState; - //ReactStates m_reactState; - uint32 m_petnumber; - bool m_barInit; - - //for restoration after charmed - ReactStates m_oldReactState; -}; - -// for clearing special attacks -#define REACTIVE_TIMER_START 4000 - -enum ReactiveType -{ - REACTIVE_DEFENSE = 0, - REACTIVE_HUNTER_PARRY = 1, - REACTIVE_OVERPOWER = 2 -}; - -#define MAX_REACTIVE 3 -#define SUMMON_SLOT_PET 0 -#define SUMMON_SLOT_TOTEM 1 -#define MAX_TOTEM_SLOT 5 -#define SUMMON_SLOT_MINIPET 5 -#define SUMMON_SLOT_QUEST 6 -#define MAX_SUMMON_SLOT 7 - -// delay time next attack to prevent client attack animation problems -#define ATTACK_DISPLAY_DELAY 200 - -struct SpellProcEventEntry; // used only privately - -class TRINITY_DLL_SPEC Unit : public WorldObject -{ - public: - typedef std::set AttackerSet; - typedef std::set ControlList; - typedef std::pair spellEffectPair; - typedef std::multimap AuraMap; - typedef std::list AuraEffectList; - typedef std::list AuraList; - typedef std::list Diminishing; - typedef std::set ComboPointHolderSet; - - typedef std::map VisibleAuraMap; - - virtual ~Unit ( ); - - void RemoveFromWorld(); - - void CleanupsBeforeDelete(); // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units) - - DiminishingLevels GetDiminishing(DiminishingGroup group); - void IncrDiminishing(DiminishingGroup group); - void ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level); - void ApplyDiminishingAura(DiminishingGroup group, bool apply); - void ClearDiminishings() { m_Diminishing.clear(); } - - //target dependent range checks - uint32 GetSpellMaxRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry); - uint32 GetSpellMinRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry); - uint32 GetSpellRadiusForTarget(Unit* target,const SpellRadiusEntry * radiusEntry); - - virtual void Update( uint32 time ); - - void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; } - void resetAttackTimer(WeaponAttackType type = BASE_ATTACK); - uint32 getAttackTimer(WeaponAttackType type) const { return m_attackTimer[type]; } - bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; } - bool haveOffhandWeapon() const; - bool CanDualWield() const { return m_canDualWield; } - void SetCanDualWield(bool value) { m_canDualWield = value; } - float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } - float GetMeleeReach() const { float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; } - bool IsWithinCombatRange(Unit *obj, float dist2compare) const; - bool IsWithinMeleeRange(Unit *obj, float dist = MELEE_RANGE) const; - void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const; - uint32 m_extraAttacks; - bool m_canDualWield; - - void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*) - { - m_attackers.insert(pAttacker); - } - void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop() - { - m_attackers.erase(pAttacker); - } - Unit * getAttackerForHelper() // If someone wants to help, who to give them - { - if (getVictim() != NULL) - return getVictim(); - - if (!m_attackers.empty()) - return *(m_attackers.begin()); - - return NULL; - } - bool Attack(Unit *victim, bool meleeAttack); - void CastStop(uint32 except_spellid = 0); - bool AttackStop(); - void RemoveAllAttackers(); - AttackerSet const& getAttackers() const { return m_attackers; } - bool isAttackingPlayer() const; - Unit* getVictim() const { return m_attacking; } - void CombatStop(bool cast = false); - void CombatStopWithPets(bool cast = false); - Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const; - bool hasNegativeAuraWithInterruptFlag(uint32 flag); - - void addUnitState(uint32 f) { m_state |= f; } - bool hasUnitState(const uint32 f) const { return (m_state & f); } - void clearUnitState(uint32 f) { m_state &= ~f; } - bool CanFreeMove() const - { - return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT | - UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0; - } - - uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); } - virtual uint32 getLevelForTarget(Unit const* /*target*/) const { return getLevel(); } - void SetLevel(uint32 lvl); - uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); } - uint32 getRaceMask() const { return 1 << (getRace()-1); } - uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); } - uint32 getClassMask() const { return 1 << (getClass()-1); } - uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); } - - float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0+stat)); } - void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0+stat, val); } - uint32 GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; } - void SetArmor(int32 val) { SetResistance(SPELL_SCHOOL_NORMAL, val); } - - uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(UNIT_FIELD_RESISTANCES+school); } - void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES+school,val); } - - uint32 GetHealth() const { return GetUInt32Value(UNIT_FIELD_HEALTH); } - uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); } - void SetHealth( uint32 val); - void SetMaxHealth(uint32 val); - int32 ModifyHealth(int32 val); - - Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); } - void setPowerType(Powers power); - uint32 GetPower( Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); } - uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); } - void SetPower( Powers power, uint32 val); - void SetMaxPower(Powers power, uint32 val); - int32 ModifyPower(Powers power, int32 val); - void ApplyPowerMod(Powers power, uint32 val, bool apply); - void ApplyMaxPowerMod(Powers power, uint32 val, bool apply); - - uint32 GetAttackTime(WeaponAttackType att) const { return (uint32)(GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att)/m_modAttackSpeedPct[att]); } - void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME+att,val*m_modAttackSpeedPct[att]); } - void ApplyAttackTimePercentMod(WeaponAttackType att,float val, bool apply); - void ApplyCastTimePercentMod(float val, bool apply); - - // faction template id - uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); } - void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction ); } - FactionTemplateEntry const* getFactionTemplateEntry() const; - bool IsHostileTo(Unit const* unit) const; - bool IsHostileToPlayers() const; - bool IsFriendlyTo(Unit const* unit) const; - bool IsNeutralToAll() const; - bool IsInPartyWith(Unit const* unit) const; - bool IsInRaidWith(Unit const* unit) const; - void GetPartyMember(std::list &units, float dist); - void GetRaidMember(std::list &units, float dist); - bool IsContestedGuard() const - { - if(FactionTemplateEntry const* entry = getFactionTemplateEntry()) - return entry->IsContestedGuardFaction(); - - return false; - } - bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); } - void SetPvP(bool state) - { - if(state) - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - else - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - } - uint32 GetCreatureType() const; - uint32 GetCreatureTypeMask() const - { - uint32 creatureType = GetCreatureType(); - return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0; - } - - uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); } - bool IsSitState() const; - bool IsStandState() const; - void SetStandState(uint8 state); - - void SetStandFlags(uint8 flags) { SetByteFlag(UNIT_FIELD_BYTES_1, 2,flags); } - void RemoveStandFlags(uint8 flags) { RemoveByteFlag(UNIT_FIELD_BYTES_1, 2,flags); } - - bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); } - uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); } - void Mount(uint32 mount); - void Unmount(); - - uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } - void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell); - uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *spellProto = NULL, bool durabilityLoss = true); - void Kill(Unit *pVictim, bool durabilityLoss = true); - - void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL); - void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage ); - - void HandleEmoteCommand(uint32 anim_id); - void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false ); - - //float MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const; - - void CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType = BASE_ATTACK); - void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss); - - void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK); - int32 GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackType attackType); - void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss); - - float MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const; - SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell); - SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell); - SpellMissInfo SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool canReflect = false); - - float GetUnitDodgeChance() const; - float GetUnitParryChance() const; - float GetUnitBlockChance() const; - float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const; - bool CanUseAttackType( uint8 attacktype ) const - { - switch(attacktype) - { - case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED); - case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_OFFHAND); - case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_RANGED); - } - return true; - } - - virtual uint32 GetShieldBlockValue() const =0; - uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } - uint32 GetDefenseSkillValue(Unit const* target = NULL) const; - uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const; - float GetWeaponProcChance() const; - float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * spellProto) const; - - MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const; - MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const; - - bool isVendor() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ); } - bool isTrainer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER ); } - bool isQuestGiver() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER ); } - bool isGossip() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP ); } - bool isTaxi() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_FLIGHTMASTER ); } - bool isGuildMaster() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PETITIONER ); } - bool isBattleMaster() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BATTLEMASTER ); } - bool isBanker() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER ); } - bool isInnkeeper() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER ); } - bool isSpiritHealer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER ); } - bool isSpiritGuide() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE ); } - bool isTabardDesigner()const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER ); } - bool isAuctioner() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER ); } - bool isArmorer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR ); } - bool isServiceProvider() const - { - return HasFlag( UNIT_NPC_FLAGS, - UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER | - UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER | - UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_GUARD | UNIT_NPC_FLAG_SPIRITHEALER | - UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER ); - } - bool isSpiritService() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE ); } - - //Need fix or use this - bool isGuard() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GUARD); } - - bool isInFlight() const { return hasUnitState(UNIT_STAT_IN_FLIGHT); } - - bool isInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); } - void CombatStart(Unit* target); - void SetInCombatState(bool PvP); - void SetInCombatWith(Unit* enemy); - void ClearInCombat(); - uint32 GetCombatTimer() const { return m_CombatTimer; } - - bool virtual HasSpell(uint32 /*spellID*/) const { return false; } - - bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); } - bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); } - bool isFeared() const { return HasAuraType(SPELL_AURA_MOD_FEAR); } - bool isInRoots() const { return HasAuraType(SPELL_AURA_MOD_ROOT); } - bool IsPolymorphed() const; - - bool isFrozen() const; - - bool isTargetableForAttack() const; - bool isAttackableByAOE() const; - bool canAttack(Unit const* target, bool force = true) const; - virtual bool IsInWater() const; - virtual bool IsUnderWater() const; - bool isInAccessiblePlaceFor(Creature const* c) const; - - void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical = false); - void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype); - uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell = false, bool useSpellDamage = true); - void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastCustomSpell(Unit* Victim,SpellEntry const *spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); - void AddAura(uint32 spellId, Unit *target); - void HandleAuraEffect(AuraEffect * aureff, bool apply); - Aura *AddAuraEffect(uint32 spellId, uint8 effIndex, Unit* caster); - - bool IsDamageToThreatSpell(SpellEntry const * spellInfo) const; - - void DeMorph(); - - void SendAttackStart(Unit* pVictim); - void SendAttackStateUpdate(CalcDamageInfo *damageInfo); - void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount); - void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log); - void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false); - void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo); - - void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false); - - void SendMonsterStop(); - void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL); - void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL); - //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); - void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end); - void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); - void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); - - virtual void MoveOutOfRange(Player &) { }; - - bool isAlive() const { return (m_deathState == ALIVE); }; - bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); }; - DeathState getDeathState() { return m_deathState; }; - virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet - - uint64 GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); } - void SetOwnerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner); } - uint64 GetCreatorGUID() const { return GetUInt64Value(UNIT_FIELD_CREATEDBY); } - void SetCreatorGUID(uint64 creator) { SetUInt64Value(UNIT_FIELD_CREATEDBY, creator); } - uint64 GetGuardianGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); } - void SetGuardianGUID(uint64 guid) { SetUInt64Value(UNIT_FIELD_SUMMON, guid); } - uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); } - void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); } - uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); } - void SetPetGUID(uint64 guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; } - uint64 GetPetGUID() const { return m_SummonSlot[SUMMON_SLOT_PET]; } - - uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); } - uint64 GetCharmerOrOwnerOrOwnGUID() const - { - if(uint64 guid = GetCharmerOrOwnerGUID()) - return guid; - return GetGUID(); - } - bool isCharmedOwnedByPlayerOrPlayer() const { return IS_PLAYER_GUID(GetCharmerOrOwnerOrOwnGUID()); } - - Player* GetSpellModOwner() const; - - Unit* GetOwner() const; - Guardian *GetGuardianPet() const; - Unit* GetCharmer() const; - Unit* GetCharm() const; - Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); } - Unit* GetCharmerOrOwnerOrSelf() const - { - if(Unit *u = GetCharmerOrOwner()) - return u; - - return (Unit*)this; - } - Player* GetCharmerOrOwnerPlayerOrPlayerItself() const; - - void SetGuardian(Guardian* target, bool apply); - void SetCharm(Unit* target, bool apply); - Unit* GetNextRandomRaidMemberOrPet(float radius); - void SetCharmedOrPossessedBy(Unit* charmer, bool possess); - void RemoveCharmedOrPossessedBy(Unit* charmer); - void RestoreFaction(); - - ControlList m_Controlled; - Unit* GetFirstControlled() const; - void RemoveAllControlled(); - - bool isCharmed() const { return GetCharmerGUID() != 0; } - bool isPossessed() const { return hasUnitState(UNIT_STAT_POSSESSED); } - bool isPossessedByPlayer() const { return hasUnitState(UNIT_STAT_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); } - bool isPossessing() const - { - if(Unit *u = GetCharm()) - return u->isPossessed(); - else - return false; - } - bool isPossessing(Unit* u) const { return u->isPossessed() && GetCharmGUID() == u->GetGUID(); } - - CharmInfo* GetCharmInfo() { return m_charmInfo; } - CharmInfo* InitCharmInfo(); - void DeleteCharmInfo(); - void UpdateCharmAI(); - SharedVisionList const& GetSharedVisionList() { return m_sharedVision; } - void AddPlayerToVision(Player* plr); - void RemovePlayerFromVision(Player* plr); - bool HasSharedVision() const { return !m_sharedVision.empty(); } - void RemoveBindSightAuras(); - void RemoveCharmAuras(); - - Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); - - bool AddAura(Aura *aur); - - void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveAura(uint32 spellId, uint64 caster = 0 ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); - void RemoveAura(Aura * aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode= AURA_REMOVE_BY_DEFAULT); - void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); - inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode); - void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); - void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); - void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); - void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except=NULL); - void RemoveAurasByTypeWithDispel(AuraType auraType, Spell * spell = NULL); - void RemoveNotOwnSingleTargetAuras(); - bool RemoveNoStackAurasDueToAura(Aura *Aur); - void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = NULL); - void RemoveAllAuras(); - void RemoveArenaAuras(bool onleave = false); - void RemoveAllAurasOnDeath(); - void DelayAura(uint32 spellId, uint64 caster, int32 delaytime); - - float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); } - void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); } - void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModSignedFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } - void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } - void InitStatBuffMods() - { - for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_POSSTAT0+i, 0); - for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_NEGSTAT0+i, 0); - } - void ApplyStatBuffMod(Stats stat, float val, bool apply) { ApplyModSignedFloatValue((val > 0 ? UNIT_FIELD_POSSTAT0+stat : UNIT_FIELD_NEGSTAT0+stat), val, apply); } - void ApplyStatPercentBuffMod(Stats stat, float val, bool apply) - { - ApplyPercentModFloatValue(UNIT_FIELD_POSSTAT0+stat, val, apply); - ApplyPercentModFloatValue(UNIT_FIELD_NEGSTAT0+stat, val, apply); - } - void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; } - void SetCreateHealth(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_HEALTH, val); } - uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); } - void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); } - uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); } - uint32 GetCreatePowers(Powers power) const; - float GetPosStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_POSSTAT0+stat); } - float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); } - float GetCreateStat(Stats stat) const { return m_createStats[stat]; } - - void SetCurrentCastedSpell(Spell * pSpell); - virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } - void InterruptSpell(uint32 spellType, bool withDelayed = true); - - // set withDelayed to true to account delayed spells as casted - // delayed+channeled spells are always accounted as casted - // we can skip channeled or delayed checks using flags - bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false) const; - - // set withDelayed to true to interrupt delayed spells too - // delayed+channeled spells are always interrupted - void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0); - - Spell* FindCurrentSpellBySpellId(uint32 spell_id) const; - - Spell* m_currentSpells[CURRENT_MAX_SPELL]; - - uint32 m_addDmgOnce; - uint64 m_SummonSlot[MAX_SUMMON_SLOT]; - uint64 m_ObjectSlot[4]; - uint32 m_detectInvisibilityMask; - uint32 m_invisibilityMask; - - uint32 m_ShapeShiftFormSpellId; - ShapeshiftForm m_form; - bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; } - - float m_modMeleeHitChance; - float m_modRangedHitChance; - float m_modSpellHitChance; - int32 m_baseSpellCritChance; - - float m_threatModifier[MAX_SPELL_SCHOOL]; - float m_modAttackSpeedPct[3]; - - // Event handler - EventProcessor m_Events; - - // stat system - bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply); - void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; } - float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const; - float GetTotalStatValue(Stats stat) const; - float GetTotalAuraModValue(UnitMods unitMod) const; - SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const; - Stats GetStatByAuraGroup(UnitMods unitMod) const; - Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const; - bool CanModifyStats() const { return m_canModifyStats; } - void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; } - virtual bool UpdateStats(Stats stat) = 0; - virtual bool UpdateAllStats() = 0; - virtual void UpdateResistances(uint32 school) = 0; - virtual void UpdateArmor() = 0; - virtual void UpdateMaxHealth() = 0; - virtual void UpdateMaxPower(Powers power) = 0; - virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0; - virtual void UpdateDamagePhysical(WeaponAttackType attType) = 0; - float GetTotalAttackPowerValue(WeaponAttackType attType) const; - float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const; - void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } - - bool isInFront(Unit const* target,float distance, float arc = M_PI) const; - void SetInFront(Unit const* target); - bool isInBack(Unit const* target, float distance, float arc = M_PI) const; - bool isInLine(Unit const* target, float distance) const; - - // Visibility system - UnitVisibility GetVisibility() const { return m_Visibility; } - void SetVisibility(UnitVisibility x); - void DestroyForNearbyPlayers(); - - // common function for visibility checks for player/creatures with detection code - virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const = 0; - bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const; - bool canDetectInvisibilityOf(Unit const* u) const; - bool canDetectStealthOf(Unit const* u, float distance) const; - void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask - - // virtual functions for all world objects types - bool isVisibleForInState(Player const* u, bool inVisibleList) const; - // function for low level grid visibility checks in player/creature cases - virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0; - - AuraList & GetSingleCastAuras() { return m_scAuras; } - AuraList const& GetSingleCastAuras() const { return m_scAuras; } - SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; - - // Threat related methods - bool CanHaveThreatList() const; - void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); - float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL); - void DeleteThreatList(); - void TauntApply(Unit* pVictim); - void TauntFadeOut(Unit *taunter); - ThreatManager& getThreatManager() { return m_ThreatManager; } - void addHatedBy(HostilReference* pHostilReference) { m_HostilRefManager.insertFirst(pHostilReference); }; - void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ } - HostilRefManager& getHostilRefManager() { return m_HostilRefManager; } - - VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; } - Aura * GetVisibleAura(uint8 slot) - { - VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); - if(itr != m_visibleAuras.end()) - return itr->second; - return 0; - } - void SetVisibleAura(uint8 slot, Aura * aur){ m_visibleAuras[slot]=aur; } - void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); } - - AuraMap & GetAuras() { return m_Auras; } - AuraMap const& GetAuras() const { return m_Auras; } - AuraEffectList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; } - - AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const; - Aura * GetAura(uint32 spellId, uint64 casterGUID = 0) const; - AuraEffect* GetAura(AuraType type, uint32 family, uint32 familyFlag1 , uint32 familyFlag2=0, uint32 familyFlag3=0, uint64 casterGUID=0); - bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster = 0) const; - bool HasAura(uint32 spellId, uint64 caster = 0) const; - bool HasAuraType(AuraType auraType) const; - bool HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const; - - int32 GetTotalAuraModifier(AuraType auratype) const; - float GetTotalAuraMultiplier(AuraType auratype) const; - int32 GetMaxPositiveAuraModifier(AuraType auratype); - int32 GetMaxNegativeAuraModifier(AuraType auratype) const; - - int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; - float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const; - int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; - int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; - - int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; - float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const; - int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; - int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; - - AuraEffect* GetDummyAura(uint32 spell_id) const; - uint32 GetInterruptMask() const { return m_interruptMask; } - void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } - void UpdateInterruptMask(); - - uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } - void SetDisplayId(uint32 modelId); - uint32 GetNativeDisplayId() { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } - void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } - void setTransForm(uint32 spellid) { m_transform = spellid;} - uint32 getTransForm() const { return m_transform;} - void AddDynObject(DynamicObject* dynObj); - void RemoveDynObject(uint32 spellid); - void RemoveDynObjectWithGUID(uint64 guid) { m_dynObjGUIDs.remove(guid); } - void RemoveAllDynObjects(); - void AddGameObject(GameObject* gameObj); - void RemoveGameObject(GameObject* gameObj, bool del); - void RemoveGameObject(uint32 spellid, bool del); - void RemoveAllGameObjects(); - DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex); - DynamicObject *GetDynObject(uint32 spellId); - uint32 CalculateDamage(WeaponAttackType attType, bool normalized); - float GetAPMultiplier(WeaponAttackType attType, bool normalized); - void ModifyAuraState(AuraState flag, bool apply); - bool HasAuraState(AuraState flag, SpellEntry const *spellProto = NULL, Unit * Caster = NULL) const ; - void UnsummonAllTotems(); - int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask); - int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask); - int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); - int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); - uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1); - uint32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); - bool isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK); - bool isBlockCritical(); - bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK); - uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); - uint32 SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); - - void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; } - bool IsUnderLastManaUseEffect() const; - - void SetContestedPvP(Player *attackedPlayer = NULL); - - void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL); - uint32 GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime ); - - void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); - void ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType type, bool apply); - virtual bool IsImmunedToSpell(SpellEntry const* spellInfo); - // redefined in Creature - bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask); - virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const; - // redefined in Creature - - uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK); - void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL); - - void UpdateSpeed(UnitMoveType mtype, bool forced); - float GetSpeed( UnitMoveType mtype ) const; - float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; } - void SetSpeed(UnitMoveType mtype, float rate, bool forced = false); - float m_TempSpeed; - - void SetHover(bool on); - bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); } - - void _RemoveAllAuraMods(); - void _ApplyAllAuraMods(); - - int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target); - int32 CalcSpellDuration(SpellEntry const* spellProto); - int32 ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive); - void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell const * spell=NULL); - float CalculateLevelPenalty(SpellEntry const* spellProto) const; - - void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } - void removeFollower(FollowerReference* /*pRef*/ ) { /* nothing to do yet */ } - static Unit* GetUnit(WorldObject& object, uint64 guid); - - MotionMaster* GetMotionMaster() { return &i_motionMaster; } - - bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); } - void StopMoving(); - - void AddUnitMovementFlag(uint32 f) { m_unit_movement_flags |= f; } - void RemoveUnitMovementFlag(uint32 f) - { - uint32 oldval = m_unit_movement_flags; - m_unit_movement_flags = oldval & ~f; - } - uint32 HasUnitMovementFlag(uint32 f) const { return m_unit_movement_flags & f; } - uint32 GetUnitMovementFlags() const { return m_unit_movement_flags; } - void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; } - - void SetControlled(bool apply, UnitState state); - - void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); } - void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); } - void ClearComboPointHolders(); - - ///----------Pet responses methods----------------- - void SendPetCastFail(uint32 spellid, SpellCastResult msg); - void SendPetActionFeedback (uint8 msg); - void SendPetTalk (uint32 pettalk); - void SendPetSpellCooldown (uint32 spellid, time_t cooltime); - void SendPetClearCooldown (uint32 spellid); - void SendPetAIReaction(uint64 guid); - ///----------End of Pet responses methods---------- - - void propagateSpeedChange() { GetMotionMaster()->propagateSpeedChange(); } - - // reactive attacks - void ClearAllReactives(); - void StartReactiveTimer( ReactiveType reactive ) { m_reactiveTimer[reactive] = REACTIVE_TIMER_START;} - void UpdateReactives(uint32 p_time); - - // group updates - void UpdateAuraForGroup(uint8 slot); - - // pet auras - typedef std::set PetAuraSet; - PetAuraSet m_petAuras; - void AddPetAura(PetAura const* petSpell); - void RemovePetAura(PetAura const* petSpell); - - void SetToNotify(); - bool m_Notified, m_IsInNotifyList; - void SetReducedThreatPercent(uint32 pct, uint64 guid) - { - m_reducedThreatPercent = pct; - m_misdirectionTargetGUID = guid; - } - uint32 GetReducedThreatPercent() { return m_reducedThreatPercent; } - Unit *GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; } - - bool IsAIEnabled, NeedChangeAI; - protected: - explicit Unit (); - - UnitAI *i_AI, *i_disabledAI; - - void _UpdateSpells(uint32 time); - - void _UpdateAutoRepeatSpell(); - bool m_AutoRepeatFirstCast; - - uint32 m_attackTimer[MAX_ATTACK]; - - float m_createStats[MAX_STATS]; - - AttackerSet m_attackers; - Unit* m_attacking; - - DeathState m_deathState; - - AuraMap m_Auras; - - typedef std::list DynObjectGUIDs; - DynObjectGUIDs m_dynObjGUIDs; - - std::list m_gameObj; - bool m_isSorted; - uint32 m_transform; - uint32 m_removedAuras; - - AuraEffectList m_modAuras[TOTAL_AURAS]; - AuraList m_scAuras; // casted singlecast auras - AuraList m_interruptableAuras; - AuraList m_ccAuras; - uint32 m_interruptMask; - - float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]; - float m_weaponDamage[MAX_ATTACK][2]; - bool m_canModifyStats; - //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem - VisibleAuraMap m_visibleAuras; - - float m_speed_rate[MAX_MOVE_TYPE]; - - CharmInfo *m_charmInfo; - SharedVisionList m_sharedVision; - - virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; - - MotionMaster i_motionMaster; - uint32 m_unit_movement_flags; - - uint32 m_reactiveTimer[MAX_REACTIVE]; - uint32 m_regenTimer; - - ThreatManager m_ThreatManager; - - private: - void SendAttackStop(Unit* victim); // only from AttackStop(Unit*) - //void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*) - - bool IsTriggeredAtSpellProcEvent(Unit *pVictim, AuraEffect* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ); - bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleObsModEnergyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown); - bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura); - bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura); - - void SetFeared(bool apply); - void SetConfused(bool apply); - void SetStunned(bool apply); - void SetRooted(bool apply); - - uint32 m_state; // Even derived shouldn't modify - uint32 m_CombatTimer; - uint32 m_lastManaUse; // msecs - - UnitVisibility m_Visibility; - - Diminishing m_Diminishing; - // Manage all Units threatening us -// ThreatManager m_ThreatManager; - // Manage all Units that are threatened by us - HostilRefManager m_HostilRefManager; - - FollowerRefManager m_FollowingRefManager; - - ComboPointHolderSet m_ComboPointHolders; - - uint32 m_reducedThreatPercent; - uint64 m_misdirectionTargetGUID; -}; -#endif - +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __UNIT_H +#define __UNIT_H + +#include "Common.h" +#include "Object.h" +#include "Opcodes.h" +#include "SpellAuraDefines.h" +#include "UpdateFields.h" +#include "SharedDefines.h" +#include "ThreatManager.h" +#include "HostilRefManager.h" +#include "FollowerReference.h" +#include "FollowerRefManager.h" +#include "Utilities/EventProcessor.h" +#include "MotionMaster.h" +#include "DBCStructure.h" +#include + +#define WORLD_TRIGGER 12999 + +enum SpellInterruptFlags +{ + SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, // why need this for instant? + SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back + SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, // interrupt + SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, // no + SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage + //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph" +}; + +enum SpellChannelInterruptFlags +{ + CHANNEL_FLAG_DAMAGE = 0x0002, + CHANNEL_FLAG_MOVEMENT = 0x0008, + CHANNEL_FLAG_TURNING = 0x0010, + CHANNEL_FLAG_DAMAGE2 = 0x0080, + CHANNEL_FLAG_DELAY = 0x4000 +}; + +enum SpellAuraInterruptFlags +{ + AURA_INTERRUPT_FLAG_HITBYSPELL = 0x00000001, // 0 removed when getting hit by a negative spell? + AURA_INTERRUPT_FLAG_DAMAGE = 0x00000002, // 1 removed by any damage + AURA_INTERRUPT_FLAG_CC = 0x00000004, // 2 crowd control + AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement + AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning + AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat + AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by unmounting + AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water + AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water + AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing + AURA_INTERRUPT_FLAG_TALK = 0x00000400, // 10 talk to npc / loot? action on creature + AURA_INTERRUPT_FLAG_USE = 0x00000800, // 11 mine/use/open action on gameobject + AURA_INTERRUPT_FLAG_ATTACK = 0x00001000, // 12 removed by attacking + AURA_INTERRUPT_FLAG_CAST = 0x00002000, // 13 ??? + AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14 + AURA_INTERRUPT_FLAG_TRANSFORM = 0x00008000, // 15 removed by transform? + AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16 + AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed + AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up + AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported + AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to loose selection on you + AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21 + AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22 + AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat + AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000 // 24 removed by any direct damage +}; + +enum SpellModOp +{ + SPELLMOD_DAMAGE = 0, + SPELLMOD_DURATION = 1, + SPELLMOD_THREAT = 2, + SPELLMOD_EFFECT1 = 3, + SPELLMOD_CHARGES = 4, + SPELLMOD_RANGE = 5, + SPELLMOD_RADIUS = 6, + SPELLMOD_CRITICAL_CHANCE = 7, + SPELLMOD_ALL_EFFECTS = 8, + SPELLMOD_NOT_LOSE_CASTING_TIME = 9, + SPELLMOD_CASTING_TIME = 10, + SPELLMOD_COOLDOWN = 11, + SPELLMOD_EFFECT2 = 12, + SPELLMOD_IGNORE_ARMOR = 13, + SPELLMOD_COST = 14, + SPELLMOD_CRIT_DAMAGE_BONUS = 15, + SPELLMOD_RESIST_MISS_CHANCE = 16, + SPELLMOD_JUMP_TARGETS = 17, + SPELLMOD_CHANCE_OF_SUCCESS = 18, + SPELLMOD_ACTIVATION_TIME = 19, + SPELLMOD_EFFECT_PAST_FIRST = 20, + SPELLMOD_GLOBAL_COOLDOWN = 21, //TODO: GCD is not checked by server currently + SPELLMOD_DOT = 22, + SPELLMOD_EFFECT3 = 23, + SPELLMOD_SPELL_BONUS_DAMAGE = 24, + // spellmod 25 + SPELLMOD_PROC_PER_MINUTE = 26, + SPELLMOD_MULTIPLE_VALUE = 27, + SPELLMOD_RESIST_DISPEL_CHANCE = 28, + SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell + SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30 +}; + +#define MAX_SPELLMOD 32 + +enum SpellFacingFlags +{ + SPELL_FACING_FLAG_INFRONT = 0x0001 +}; + +#define BASE_MINDAMAGE 1.0f +#define BASE_MAXDAMAGE 2.0f +#define BASE_ATTACK_TIME 2000 + +// byte value (UNIT_FIELD_BYTES_1,0) +enum UnitStandStateType +{ + UNIT_STAND_STATE_STAND = 0, + UNIT_STAND_STATE_SIT = 1, + UNIT_STAND_STATE_SIT_CHAIR = 2, + UNIT_STAND_STATE_SLEEP = 3, + UNIT_STAND_STATE_SIT_LOW_CHAIR = 4, + UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5, + UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6, + UNIT_STAND_STATE_DEAD = 7, + UNIT_STAND_STATE_KNEEL = 8 +}; + +// byte flag value (UNIT_FIELD_BYTES_1,2) +enum UnitStandFlags +{ + UNIT_STAND_FLAGS_CREEP = 0x02, + UNIT_STAND_FLAGS_ALL = 0xFF +}; + +// byte flags value (UNIT_FIELD_BYTES_1,3) +enum UnitBytes1_Flags +{ + UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, + UNIT_BYTE1_FLAG_UNTRACKABLE = 0x04, + UNIT_BYTE1_FLAG_ALL = 0xFF +}; + +// high byte (3 from 0..3) of UNIT_FIELD_BYTES_2 +enum ShapeshiftForm +{ + FORM_NONE = 0x00, + FORM_CAT = 0x01, + FORM_TREE = 0x02, + FORM_TRAVEL = 0x03, + FORM_AQUA = 0x04, + FORM_BEAR = 0x05, + FORM_AMBIENT = 0x06, + FORM_GHOUL = 0x07, + FORM_DIREBEAR = 0x08, + FORM_CREATUREBEAR = 0x0E, + FORM_CREATURECAT = 0x0F, + FORM_GHOSTWOLF = 0x10, + FORM_BATTLESTANCE = 0x11, + FORM_DEFENSIVESTANCE = 0x12, + FORM_BERSERKERSTANCE = 0x13, + FORM_TEST = 0x14, + FORM_ZOMBIE = 0x15, + FORM_METAMORPHOSIS = 0x16, + FORM_FLIGHT_EPIC = 0x1B, + FORM_SHADOW = 0x1C, + FORM_FLIGHT = 0x1D, + FORM_STEALTH = 0x1E, + FORM_MOONKIN = 0x1F, + FORM_SPIRITOFREDEMPTION = 0x20 +}; + +// low byte ( 0 from 0..3 ) of UNIT_FIELD_BYTES_2 +enum SheathState +{ + SHEATH_STATE_UNARMED = 0, // non prepared weapon + SHEATH_STATE_MELEE = 1, // prepared melee weapon + SHEATH_STATE_RANGED = 2 // prepared ranged weapon +}; + +// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitBytes2_Flags +{ + UNIT_BYTE2_FLAG_PVP = 0x01, + UNIT_BYTE2_FLAG_UNK1 = 0x02, + UNIT_BYTE2_FLAG_FFA_PVP = 0x04, + UNIT_BYTE2_FLAG_SANCTUARY = 0x08, + UNIT_BYTE2_FLAG_UNK4 = 0x10, + UNIT_BYTE2_FLAG_UNK5 = 0x20, + UNIT_BYTE2_FLAG_UNK6 = 0x40, + UNIT_BYTE2_FLAG_UNK7 = 0x80 +}; + +// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitRename +{ + UNIT_RENAME_NOT_ALLOWED = 0x02, + UNIT_RENAME_ALLOWED = 0x03 +}; + +#define CREATURE_MAX_SPELLS 8 +#define MAX_SPELL_CHARM 4 +#define MAX_SPELL_VEHICLE 6 +#define MAX_SPELL_POSSESS 8 +#define MAX_SPELL_CONTROL_BAR 10 + +enum Swing +{ + NOSWING = 0, + SINGLEHANDEDSWING = 1, + TWOHANDEDSWING = 2 +}; + +enum VictimState +{ + VICTIMSTATE_UNKNOWN1 = 0, + VICTIMSTATE_NORMAL = 1, + VICTIMSTATE_DODGE = 2, + VICTIMSTATE_PARRY = 3, + VICTIMSTATE_INTERRUPT = 4, + VICTIMSTATE_BLOCKS = 5, + VICTIMSTATE_EVADES = 6, + VICTIMSTATE_IS_IMMUNE = 7, + VICTIMSTATE_DEFLECTS = 8 +}; + +enum HitInfo +{ + HITINFO_NORMALSWING = 0x00000000, + HITINFO_UNK1 = 0x00000001, // req correct packet structure + HITINFO_NORMALSWING2 = 0x00000002, + HITINFO_LEFTSWING = 0x00000004, + HITINFO_UNK2 = 0x00000008, + HITINFO_MISS = 0x00000010, + HITINFO_ABSORB = 0x00000020, // absorbed damage + HITINFO_ABSORB2 = 0x00000040, // absorbed damage + HITINFO_RESIST = 0x00000080, // resisted atleast some damage + HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage + HITINFO_CRITICALHIT = 0x00000200, // critical hit + // 0x00000400 + // 0x00000800 + // 0x00001000 + HITINFO_BLOCK = 0x00002000, // blocked damage + // 0x00004000 + // 0x00008000 + HITINFO_GLANCING = 0x00010000, + HITINFO_CRUSHING = 0x00020000, + HITINFO_NOACTION = 0x00040000, // guessed + // 0x00080000 + // 0x00100000 + HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed + // 0x00400000 + HITINFO_UNK3 = 0x00800000 +}; + +//i would like to remove this: (it is defined in item.h +enum InventorySlot +{ + NULL_BAG = 0, + NULL_SLOT = 255 +}; + +struct FactionTemplateEntry; +struct SpellEntry; +struct SpellEntryExt; + +class Aura; +class AuraEffect; +class Creature; +class Spell; +class DynamicObject; +class GameObject; +class Item; +class Pet; +class Path; +class PetAura; +class Guardian; + +struct SpellImmune +{ + uint32 type; + uint32 spellId; +}; + +typedef std::list SpellImmuneList; + +enum UnitModifierType +{ + BASE_VALUE = 0, + BASE_PCT = 1, + TOTAL_VALUE = 2, + TOTAL_PCT = 3, + MODIFIER_TYPE_END = 4 +}; + +enum WeaponDamageRange +{ + MINDAMAGE, + MAXDAMAGE +}; + +enum DamageTypeToSchool +{ + RESISTANCE, + DAMAGE_DEALT, + DAMAGE_TAKEN +}; + +enum AuraRemoveMode +{ + AURA_NO_REMOVE_MODE = 0, + AURA_REMOVE_BY_DEFAULT, + AURA_REMOVE_BY_STACK, // change stack, single aura remove, + AURA_REMOVE_BY_CANCEL, + AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy + AURA_REMOVE_BY_EXPIRE, // dispel and absorb aura destroy + AURA_REMOVE_BY_DEATH +}; + +enum UnitMods +{ + UNIT_MOD_STAT_STRENGTH, // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_SPIRIT must be in existed order, it's accessed by index values of Stats enum. + UNIT_MOD_STAT_AGILITY, + UNIT_MOD_STAT_STAMINA, + UNIT_MOD_STAT_INTELLECT, + UNIT_MOD_STAT_SPIRIT, + UNIT_MOD_HEALTH, + UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum. + UNIT_MOD_RAGE, + UNIT_MOD_FOCUS, + UNIT_MOD_ENERGY, + UNIT_MOD_HAPPINESS, + UNIT_MOD_RUNE, + UNIT_MOD_RUNIC_POWER, + UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum. + UNIT_MOD_RESISTANCE_HOLY, + UNIT_MOD_RESISTANCE_FIRE, + UNIT_MOD_RESISTANCE_NATURE, + UNIT_MOD_RESISTANCE_FROST, + UNIT_MOD_RESISTANCE_SHADOW, + UNIT_MOD_RESISTANCE_ARCANE, + UNIT_MOD_ATTACK_POWER, + UNIT_MOD_ATTACK_POWER_RANGED, + UNIT_MOD_DAMAGE_MAINHAND, + UNIT_MOD_DAMAGE_OFFHAND, + UNIT_MOD_DAMAGE_RANGED, + UNIT_MOD_END, + // synonyms + UNIT_MOD_STAT_START = UNIT_MOD_STAT_STRENGTH, + UNIT_MOD_STAT_END = UNIT_MOD_STAT_SPIRIT + 1, + UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR, + UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1, + UNIT_MOD_POWER_START = UNIT_MOD_MANA, + UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1 +}; + +enum BaseModGroup +{ + CRIT_PERCENTAGE, + RANGED_CRIT_PERCENTAGE, + OFFHAND_CRIT_PERCENTAGE, + SHIELD_BLOCK_VALUE, + BASEMOD_END +}; + +enum BaseModType +{ + FLAT_MOD, + PCT_MOD +}; + +#define MOD_END (PCT_MOD+1) + +enum DeathState +{ + ALIVE = 0, + JUST_DIED = 1, + CORPSE = 2, + DEAD = 3, + JUST_ALIVED = 4, + DEAD_FALLING= 5 +}; + +enum UnitState +{ + UNIT_STAT_DIED = 0x00000001, + UNIT_STAT_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone + //UNIT_STAT_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone + UNIT_STAT_STUNNED = 0x00000008, + UNIT_STAT_ROAMING = 0x00000010, + UNIT_STAT_CHASE = 0x00000020, + //UNIT_STAT_SEARCHING = 0x00000040, + UNIT_STAT_FLEEING = 0x00000080, + UNIT_STAT_IN_FLIGHT = 0x00000100, // player is in flight mode + UNIT_STAT_FOLLOW = 0x00000200, + UNIT_STAT_ROOT = 0x00000400, + UNIT_STAT_CONFUSED = 0x00000800, + UNIT_STAT_DISTRACTED = 0x00001000, + UNIT_STAT_ISOLATED = 0x00002000, // area auras do not affect other players + UNIT_STAT_ATTACK_PLAYER = 0x00004000, + UNIT_STAT_CASTING = 0x00008000, + UNIT_STAT_POSSESSED = 0x00010000, + UNIT_STAT_CHARGING = 0x00020000, + UNIT_STAT_JUMPING = 0x00040000, + UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE), + UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING), + UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING), + UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE), + UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING), + UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) +}; + +enum UnitMoveType +{ + MOVE_WALK = 0, + MOVE_RUN = 1, + MOVE_RUN_BACK = 2, + MOVE_SWIM = 3, + MOVE_SWIM_BACK = 4, + MOVE_TURN_RATE = 5, + MOVE_FLIGHT = 6, + MOVE_FLIGHT_BACK = 7, + MOVE_PITCH_RATE = 8 +}; + +#define MAX_MOVE_TYPE 9 + +extern float baseMoveSpeed[MAX_MOVE_TYPE]; + +enum WeaponAttackType +{ + BASE_ATTACK = 0, + OFF_ATTACK = 1, + RANGED_ATTACK = 2, + MAX_ATTACK +}; + +enum CombatRating +{ + CR_WEAPON_SKILL = 0, + CR_DEFENSE_SKILL = 1, + CR_DODGE = 2, + CR_PARRY = 3, + CR_BLOCK = 4, + CR_HIT_MELEE = 5, + CR_HIT_RANGED = 6, + CR_HIT_SPELL = 7, + CR_CRIT_MELEE = 8, + CR_CRIT_RANGED = 9, + CR_CRIT_SPELL = 10, + CR_HIT_TAKEN_MELEE = 11, + CR_HIT_TAKEN_RANGED = 12, + CR_HIT_TAKEN_SPELL = 13, + CR_CRIT_TAKEN_MELEE = 14, + CR_CRIT_TAKEN_RANGED = 15, + CR_CRIT_TAKEN_SPELL = 16, + CR_HASTE_MELEE = 17, + CR_HASTE_RANGED = 18, + CR_HASTE_SPELL = 19, + CR_WEAPON_SKILL_MAINHAND = 20, + CR_WEAPON_SKILL_OFFHAND = 21, + CR_WEAPON_SKILL_RANGED = 22, + CR_EXPERTISE = 23, + CR_ARMOR_PENETRATION = 24 +}; + +#define MAX_COMBAT_RATING 25 + +enum DamageEffectType +{ + DIRECT_DAMAGE = 0, // used for normal weapon damage (not for class abilities or spells) + SPELL_DIRECT_DAMAGE = 1, // spell/class abilities damage + DOT = 2, + HEAL = 3, + NODAMAGE = 4, // used also in case when damage applied to health but not applied to spell channelInterruptFlags/etc + SELF_DAMAGE = 5 +}; + +enum UnitVisibility +{ + VISIBILITY_OFF = 0, // absolute, not detectable, GM-like, can see all other + VISIBILITY_ON = 1, + VISIBILITY_GROUP_STEALTH = 2, // detect chance, seen and can see group members + //VISIBILITY_GROUP_INVISIBILITY = 3, // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) + //VISIBILITY_GROUP_NO_DETECT = 4, // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break + VISIBILITY_RESPAWN = 5 // special totally not detectable visibility for force delete object at respawn command +}; + +// Value masks for UNIT_FIELD_FLAGS +enum UnitFlags +{ + UNIT_FLAG_UNK_0 = 0x00000001, + UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable + UNIT_FLAG_DISABLE_MOVE = 0x00000004, + UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state + UNIT_FLAG_RENAME = 0x00000010, + UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP + UNIT_FLAG_UNK_6 = 0x00000040, + UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE + UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100, // 2.0.8 + UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything + UNIT_FLAG_LOOTING = 0x00000400, // loot animation + UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 + UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 + UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 + UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8 + UNIT_FLAG_UNK_15 = 0x00008000, + UNIT_FLAG_UNK_16 = 0x00010000, + UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok + UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok + UNIT_FLAG_IN_COMBAT = 0x00080000, + UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag + UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. + UNIT_FLAG_CONFUSED = 0x00400000, + UNIT_FLAG_FLEEING = 0x00800000, + UNIT_FLAG_UNK_24 = 0x01000000, // used in spell Eyes of the Beast for pet... + UNIT_FLAG_NOT_SELECTABLE = 0x02000000, + UNIT_FLAG_SKINNABLE = 0x04000000, + UNIT_FLAG_MOUNT = 0x08000000, + UNIT_FLAG_UNK_28 = 0x10000000, + UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell + UNIT_FLAG_SHEATHE = 0x40000000, + UNIT_FLAG_UNK_31 = 0x80000000 +}; + +// Value masks for UNIT_FIELD_FLAGS_2 +enum UnitFlags2 +{ + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) + UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, + UNIT_FLAG2_FORCE_MOVE = 0x00000040, + UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, + UNIT_FLAG2_DISARM_RANGED = 0x00000400, //this does not disable ranged weapon display (maybe additional flag needed?) + UNIT_FLAG2_REGENERATE_POWER = 0x00000800 +}; + +/// Non Player Character flags +enum NPCFlags +{ + UNIT_NPC_FLAG_NONE = 0x00000000, + UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100% + UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok + UNIT_NPC_FLAG_UNK1 = 0x00000004, + UNIT_NPC_FLAG_UNK2 = 0x00000008, + UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100% + UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // 100% + UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // 100% + UNIT_NPC_FLAG_VENDOR = 0x00000080, // 100% + UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // 100%, general goods vendor + UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // 100% + UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // guessed + UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // 100% + UNIT_NPC_FLAG_REPAIR = 0x00001000, // 100% + UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // 100% + UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // guessed + UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // guessed + UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // 100% + UNIT_NPC_FLAG_BANKER = 0x00020000, // 100% + UNIT_NPC_FLAG_PETITIONER = 0x00040000, // 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions + UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // 100% + UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // 100% + UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // 100% + UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% + UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode + UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) + UNIT_NPC_FLAG_GUARD = 0x10000000, // custom flag for guards + UNIT_NPC_FLAG_OUTDOORPVP = 0x20000000, // custom flag for outdoor pvp creatures +}; + +enum MoveFlags +{ + MOVEFLAG_NONE = 0x00000000, + MOVEFLAG_SLIDE = 0x00000002, + MOVEFLAG_MARCH_ON_SPOT = 0x00000004, + MOVEFLAG_JUMP = 0x00000008, + MOVEFLAG_WALK = 0x00000100, + MOVEFLAG_FLY = 0x00000200, //For dragon (+walk = glide) + MOVEFLAG_ORIENTATION = 0x00000400, //Fix orientation +}; + +enum MovementFlags +{ + MOVEMENTFLAG_NONE = 0x00000000, + MOVEMENTFLAG_FORWARD = 0x00000001, + MOVEMENTFLAG_BACKWARD = 0x00000002, + MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, + MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, + MOVEMENTFLAG_LEFT = 0x00000010, + MOVEMENTFLAG_RIGHT = 0x00000020, + MOVEMENTFLAG_PITCH_UP = 0x00000040, + MOVEMENTFLAG_PITCH_DOWN = 0x00000080, + MOVEMENTFLAG_WALK_MODE = 0x00000100, + MOVEMENTFLAG_ONTRANSPORT = 0x00000200, + MOVEMENTFLAG_LEVITATING = 0x00000400, + MOVEMENTFLAG_FLY_UNK1 = 0x00000800, + MOVEMENTFLAG_JUMPING = 0x00001000, + MOVEMENTFLAG_UNK4 = 0x00002000, + MOVEMENTFLAG_FALLING = 0x00004000, + // 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000 + MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also + MOVEMENTFLAG_FLY_UP = 0x00400000, + MOVEMENTFLAG_CAN_FLY = 0x00800000, + MOVEMENTFLAG_FLYING = 0x01000000, + MOVEMENTFLAG_FLYING2 = 0x02000000, // Actual flying mode + MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths + MOVEMENTFLAG_SPLINE2 = 0x08000000, // used for flight paths + MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water + MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive) + MOVEMENTFLAG_UNK3 = 0x40000000 +}; + +enum DiminishingLevels +{ + DIMINISHING_LEVEL_1 = 0, + DIMINISHING_LEVEL_2 = 1, + DIMINISHING_LEVEL_3 = 2, + DIMINISHING_LEVEL_IMMUNE = 3 +}; + +struct DiminishingReturn +{ + DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count) + : DRGroup(group), stack(0), hitTime(t), hitCount(count) + {} + + DiminishingGroup DRGroup:16; + uint16 stack:16; + uint32 hitTime; + uint32 hitCount; +}; + +enum MeleeHitOutcome +{ + MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY, + MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL +}; + +struct CleanDamage +{ + CleanDamage(uint32 _damage, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) : + damage(_damage), attackType(_attackType), hitOutCome(_hitOutCome) {} + + uint32 damage; + WeaponAttackType attackType; + MeleeHitOutcome hitOutCome; +}; + +// Struct for use in Unit::CalculateMeleeDamage +// Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode +struct CalcDamageInfo +{ + Unit *attacker; // Attacker + Unit *target; // Target for damage + uint32 damageSchoolMask; + uint32 damage; + uint32 absorb; + uint32 resist; + uint32 blocked_amount; + uint32 HitInfo; + uint32 TargetState; +// Helper + WeaponAttackType attackType; // + uint32 procAttacker; + uint32 procVictim; + uint32 procEx; + uint32 cleanDamage; // Used only fo rage calcultion + MeleeHitOutcome hitOutCome; // TODO: remove this field (need use TargetState) +}; + +// Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode +struct SpellNonMeleeDamage{ + SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask) + : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), schoolMask(_schoolMask), + absorb(0), resist(0), phusicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) + {} + + Unit *target; + Unit *attacker; + uint32 SpellID; + uint32 damage; + uint32 schoolMask; + uint32 absorb; + uint32 resist; + bool phusicalLog; + bool unused; + uint32 blocked; + uint32 HitInfo; + // Used for help + uint32 cleanDamage; +}; + +uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition); + +struct UnitActionBarEntry +{ + UnitActionBarEntry() : Raw(0) {} + + union + { + struct + { + uint16 SpellOrAction; + uint16 Type; + }; + struct + { + uint32 Raw; + }; + }; +}; + +#define MAX_DECLINED_NAME_CASES 5 + +struct DeclinedName +{ + std::string name[MAX_DECLINED_NAME_CASES]; +}; + +enum CurrentSpellTypes +{ + CURRENT_MELEE_SPELL = 0, + CURRENT_FIRST_NON_MELEE_SPELL = 1, // just counter + CURRENT_GENERIC_SPELL = 1, + CURRENT_AUTOREPEAT_SPELL = 2, + CURRENT_CHANNELED_SPELL = 3, + CURRENT_MAX_SPELL = 4 // just counter +}; + +enum ActiveStates +{ + ACT_PASSIVE = 0x0100, // 0x0100 - passive + ACT_DISABLED = 0x8100, // 0x8000 - castable + ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable + ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400 + ACT_REACTION = 0x0600, // 0x0200 | 0x0400 + ACT_DECIDE = 0x0001 // what is it? +}; + +enum ReactStates +{ + REACT_PASSIVE = 0, + REACT_DEFENSIVE = 1, + REACT_AGGRESSIVE = 2 +}; + +enum CommandStates +{ + COMMAND_STAY = 0, + COMMAND_FOLLOW = 1, + COMMAND_ATTACK = 2, + COMMAND_ABANDON = 3 +}; + +struct CharmSpellEntry +{ + uint16 spellId; + uint16 active; +}; + +typedef std::list SharedVisionList; + +struct TRINITY_DLL_SPEC CharmInfo +{ + public: + explicit CharmInfo(Unit* unit); + ~CharmInfo(); + uint32 GetPetNumber() const { return m_petnumber; } + void SetPetNumber(uint32 petnumber, bool statwindow); + + void SetCommandState(CommandStates st) { m_CommandState = st; } + CommandStates GetCommandState() { return m_CommandState; } + bool HasCommandState(CommandStates state) { return (m_CommandState == state); } + //void SetReactState(ReactStates st) { m_reactState = st; } + //ReactStates GetReactState() { return m_reactState; } + //bool HasReactState(ReactStates state) { return (m_reactState == state); } + + void InitPossessCreateSpells(); + void InitCharmCreateSpells(); + void InitPetActionBar(); + void InitEmptyActionBar(bool withAttack = true); + //return true if successful + bool AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate = ACT_DECIDE); + void ToggleCreatureAutocast(uint32 spellid, bool apply); + + UnitActionBarEntry* GetActionBarEntry(uint8 index) { return &(PetActionBar[index]); } + CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); } + private: + Unit* m_unit; + UnitActionBarEntry PetActionBar[10]; + CharmSpellEntry m_charmspells[4]; + CommandStates m_CommandState; + //ReactStates m_reactState; + uint32 m_petnumber; + bool m_barInit; + + //for restoration after charmed + ReactStates m_oldReactState; +}; + +// for clearing special attacks +#define REACTIVE_TIMER_START 4000 + +enum ReactiveType +{ + REACTIVE_DEFENSE = 0, + REACTIVE_HUNTER_PARRY = 1, + REACTIVE_OVERPOWER = 2 +}; + +#define MAX_REACTIVE 3 +#define SUMMON_SLOT_PET 0 +#define SUMMON_SLOT_TOTEM 1 +#define MAX_TOTEM_SLOT 5 +#define SUMMON_SLOT_MINIPET 5 +#define SUMMON_SLOT_QUEST 6 +#define MAX_SUMMON_SLOT 7 + +// delay time next attack to prevent client attack animation problems +#define ATTACK_DISPLAY_DELAY 200 + +struct SpellProcEventEntry; // used only privately + +class TRINITY_DLL_SPEC Unit : public WorldObject +{ + public: + typedef std::set AttackerSet; + typedef std::set ControlList; + typedef std::pair spellEffectPair; + typedef std::multimap AuraMap; + typedef std::list AuraEffectList; + typedef std::list AuraList; + typedef std::list Diminishing; + typedef std::set ComboPointHolderSet; + + typedef std::map VisibleAuraMap; + + virtual ~Unit ( ); + + void RemoveFromWorld(); + + void CleanupsBeforeDelete(); // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units) + + DiminishingLevels GetDiminishing(DiminishingGroup group); + void IncrDiminishing(DiminishingGroup group); + void ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level); + void ApplyDiminishingAura(DiminishingGroup group, bool apply); + void ClearDiminishings() { m_Diminishing.clear(); } + + //target dependent range checks + uint32 GetSpellMaxRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry); + uint32 GetSpellMinRangeForTarget(Unit* target,const SpellRangeEntry * rangeEntry); + uint32 GetSpellRadiusForTarget(Unit* target,const SpellRadiusEntry * radiusEntry); + + virtual void Update( uint32 time ); + + void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; } + void resetAttackTimer(WeaponAttackType type = BASE_ATTACK); + uint32 getAttackTimer(WeaponAttackType type) const { return m_attackTimer[type]; } + bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; } + bool haveOffhandWeapon() const; + bool CanDualWield() const { return m_canDualWield; } + void SetCanDualWield(bool value) { m_canDualWield = value; } + float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } + float GetMeleeReach() const { float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; } + bool IsWithinCombatRange(Unit *obj, float dist2compare) const; + bool IsWithinMeleeRange(Unit *obj, float dist = MELEE_RANGE) const; + void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const; + uint32 m_extraAttacks; + bool m_canDualWield; + + void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*) + { + m_attackers.insert(pAttacker); + } + void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop() + { + m_attackers.erase(pAttacker); + } + Unit * getAttackerForHelper() // If someone wants to help, who to give them + { + if (getVictim() != NULL) + return getVictim(); + + if (!m_attackers.empty()) + return *(m_attackers.begin()); + + return NULL; + } + bool Attack(Unit *victim, bool meleeAttack); + void CastStop(uint32 except_spellid = 0); + bool AttackStop(); + void RemoveAllAttackers(); + AttackerSet const& getAttackers() const { return m_attackers; } + bool isAttackingPlayer() const; + Unit* getVictim() const { return m_attacking; } + void CombatStop(bool cast = false); + void CombatStopWithPets(bool cast = false); + Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const; + bool hasNegativeAuraWithInterruptFlag(uint32 flag); + + void addUnitState(uint32 f) { m_state |= f; } + bool hasUnitState(const uint32 f) const { return (m_state & f); } + void clearUnitState(uint32 f) { m_state &= ~f; } + bool CanFreeMove() const + { + return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT | + UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0; + } + + uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); } + virtual uint32 getLevelForTarget(Unit const* /*target*/) const { return getLevel(); } + void SetLevel(uint32 lvl); + uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); } + uint32 getRaceMask() const { return 1 << (getRace()-1); } + uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); } + uint32 getClassMask() const { return 1 << (getClass()-1); } + uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); } + + float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0+stat)); } + void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0+stat, val); } + uint32 GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; } + void SetArmor(int32 val) { SetResistance(SPELL_SCHOOL_NORMAL, val); } + + uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(UNIT_FIELD_RESISTANCES+school); } + void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES+school,val); } + + uint32 GetHealth() const { return GetUInt32Value(UNIT_FIELD_HEALTH); } + uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); } + void SetHealth( uint32 val); + void SetMaxHealth(uint32 val); + int32 ModifyHealth(int32 val); + + Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); } + void setPowerType(Powers power); + uint32 GetPower( Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); } + uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); } + void SetPower( Powers power, uint32 val); + void SetMaxPower(Powers power, uint32 val); + int32 ModifyPower(Powers power, int32 val); + void ApplyPowerMod(Powers power, uint32 val, bool apply); + void ApplyMaxPowerMod(Powers power, uint32 val, bool apply); + + uint32 GetAttackTime(WeaponAttackType att) const { return (uint32)(GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att)/m_modAttackSpeedPct[att]); } + void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME+att,val*m_modAttackSpeedPct[att]); } + void ApplyAttackTimePercentMod(WeaponAttackType att,float val, bool apply); + void ApplyCastTimePercentMod(float val, bool apply); + + // faction template id + uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); } + void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction ); } + FactionTemplateEntry const* getFactionTemplateEntry() const; + bool IsHostileTo(Unit const* unit) const; + bool IsHostileToPlayers() const; + bool IsFriendlyTo(Unit const* unit) const; + bool IsNeutralToAll() const; + bool IsInPartyWith(Unit const* unit) const; + bool IsInRaidWith(Unit const* unit) const; + void GetPartyMember(std::list &units, float dist); + void GetRaidMember(std::list &units, float dist); + bool IsContestedGuard() const + { + if(FactionTemplateEntry const* entry = getFactionTemplateEntry()) + return entry->IsContestedGuardFaction(); + + return false; + } + bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); } + void SetPvP(bool state) + { + if(state) + SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); + else + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); + } + uint32 GetCreatureType() const; + uint32 GetCreatureTypeMask() const + { + uint32 creatureType = GetCreatureType(); + return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0; + } + + uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); } + bool IsSitState() const; + bool IsStandState() const; + void SetStandState(uint8 state); + + void SetStandFlags(uint8 flags) { SetByteFlag(UNIT_FIELD_BYTES_1, 2,flags); } + void RemoveStandFlags(uint8 flags) { RemoveByteFlag(UNIT_FIELD_BYTES_1, 2,flags); } + + bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); } + uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); } + void Mount(uint32 mount); + void Unmount(); + + uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } + void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell); + uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *spellProto = NULL, bool durabilityLoss = true); + void Kill(Unit *pVictim, bool durabilityLoss = true); + + void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL); + void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage ); + + void HandleEmoteCommand(uint32 anim_id); + void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false ); + + //float MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const; + + void CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType = BASE_ATTACK); + void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss); + + void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK); + int32 GetIgnoredArmorMultiplier(SpellEntry const *spellInfo, WeaponAttackType attackType); + void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss); + + float MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const; + SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell); + SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell); + SpellMissInfo SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool canReflect = false); + + float GetUnitDodgeChance() const; + float GetUnitParryChance() const; + float GetUnitBlockChance() const; + float GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVictim) const; + bool CanUseAttackType( uint8 attacktype ) const + { + switch(attacktype) + { + case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED); + case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_OFFHAND); + case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2,UNIT_FLAG2_DISARM_RANGED); + } + return true; + } + + virtual uint32 GetShieldBlockValue() const =0; + uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } + uint32 GetDefenseSkillValue(Unit const* target = NULL) const; + uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const; + float GetWeaponProcChance() const; + float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * spellProto) const; + + MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const; + MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const; + + bool isVendor() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ); } + bool isTrainer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER ); } + bool isQuestGiver() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER ); } + bool isGossip() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP ); } + bool isTaxi() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_FLIGHTMASTER ); } + bool isGuildMaster() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PETITIONER ); } + bool isBattleMaster() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BATTLEMASTER ); } + bool isBanker() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER ); } + bool isInnkeeper() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER ); } + bool isSpiritHealer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER ); } + bool isSpiritGuide() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE ); } + bool isTabardDesigner()const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER ); } + bool isAuctioner() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER ); } + bool isArmorer() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR ); } + bool isServiceProvider() const + { + return HasFlag( UNIT_NPC_FLAGS, + UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER | + UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER | + UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_GUARD | UNIT_NPC_FLAG_SPIRITHEALER | + UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER ); + } + bool isSpiritService() const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE ); } + + //Need fix or use this + bool isGuard() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GUARD); } + + bool isInFlight() const { return hasUnitState(UNIT_STAT_IN_FLIGHT); } + + bool isInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); } + void CombatStart(Unit* target); + void SetInCombatState(bool PvP); + void SetInCombatWith(Unit* enemy); + void ClearInCombat(); + uint32 GetCombatTimer() const { return m_CombatTimer; } + + bool virtual HasSpell(uint32 /*spellID*/) const { return false; } + + bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); } + bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); } + bool isFeared() const { return HasAuraType(SPELL_AURA_MOD_FEAR); } + bool isInRoots() const { return HasAuraType(SPELL_AURA_MOD_ROOT); } + bool IsPolymorphed() const; + + bool isFrozen() const; + + bool isTargetableForAttack() const; + bool isAttackableByAOE() const; + bool canAttack(Unit const* target, bool force = true) const; + virtual bool IsInWater() const; + virtual bool IsUnderWater() const; + bool isInAccessiblePlaceFor(Creature const* c) const; + + void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool critical = false); + void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype); + uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell = false, bool useSpellDamage = true); + void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(Unit* Victim,SpellEntry const *spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void AddAura(uint32 spellId, Unit *target); + void HandleAuraEffect(AuraEffect * aureff, bool apply); + Aura *AddAuraEffect(uint32 spellId, uint8 effIndex, Unit* caster); + + bool IsDamageToThreatSpell(SpellEntry const * spellInfo) const; + + void DeMorph(); + + void SendAttackStart(Unit* pVictim); + void SendAttackStateUpdate(CalcDamageInfo *damageInfo); + void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount); + void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log); + void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false); + void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo); + + void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false); + + void SendMonsterStop(); + void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL); + void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL); + //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); + void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end); + void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); + void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); + + virtual void MoveOutOfRange(Player &) { }; + + bool isAlive() const { return (m_deathState == ALIVE); }; + bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); }; + DeathState getDeathState() { return m_deathState; }; + virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet + + uint64 GetOwnerGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMONEDBY); } + void SetOwnerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner); } + uint64 GetCreatorGUID() const { return GetUInt64Value(UNIT_FIELD_CREATEDBY); } + void SetCreatorGUID(uint64 creator) { SetUInt64Value(UNIT_FIELD_CREATEDBY, creator); } + uint64 GetGuardianGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); } + void SetGuardianGUID(uint64 guid) { SetUInt64Value(UNIT_FIELD_SUMMON, guid); } + uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); } + void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); } + uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); } + void SetPetGUID(uint64 guid) { m_SummonSlot[SUMMON_SLOT_PET] = guid; } + uint64 GetPetGUID() const { return m_SummonSlot[SUMMON_SLOT_PET]; } + + uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); } + uint64 GetCharmerOrOwnerOrOwnGUID() const + { + if(uint64 guid = GetCharmerOrOwnerGUID()) + return guid; + return GetGUID(); + } + bool isCharmedOwnedByPlayerOrPlayer() const { return IS_PLAYER_GUID(GetCharmerOrOwnerOrOwnGUID()); } + + Player* GetSpellModOwner() const; + + Unit* GetOwner() const; + Guardian *GetGuardianPet() const; + Unit* GetCharmer() const; + Unit* GetCharm() const; + Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); } + Unit* GetCharmerOrOwnerOrSelf() const + { + if(Unit *u = GetCharmerOrOwner()) + return u; + + return (Unit*)this; + } + Player* GetCharmerOrOwnerPlayerOrPlayerItself() const; + + void SetGuardian(Guardian* target, bool apply); + void SetCharm(Unit* target, bool apply); + Unit* GetNextRandomRaidMemberOrPet(float radius); + void SetCharmedOrPossessedBy(Unit* charmer, bool possess); + void RemoveCharmedOrPossessedBy(Unit* charmer); + void RestoreFaction(); + + ControlList m_Controlled; + Unit* GetFirstControlled() const; + void RemoveAllControlled(); + + bool isCharmed() const { return GetCharmerGUID() != 0; } + bool isPossessed() const { return hasUnitState(UNIT_STAT_POSSESSED); } + bool isPossessedByPlayer() const { return hasUnitState(UNIT_STAT_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); } + bool isPossessing() const + { + if(Unit *u = GetCharm()) + return u->isPossessed(); + else + return false; + } + bool isPossessing(Unit* u) const { return u->isPossessed() && GetCharmGUID() == u->GetGUID(); } + + CharmInfo* GetCharmInfo() { return m_charmInfo; } + CharmInfo* InitCharmInfo(); + void DeleteCharmInfo(); + void UpdateCharmAI(); + SharedVisionList const& GetSharedVisionList() { return m_sharedVision; } + void AddPlayerToVision(Player* plr); + void RemovePlayerFromVision(Player* plr); + bool HasSharedVision() const { return !m_sharedVision.empty(); } + void RemoveBindSightAuras(); + void RemoveCharmAuras(); + + Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); + + bool AddAura(Aura *aur); + + void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveAura(uint32 spellId, uint64 caster = 0 ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); + void RemoveAura(Aura * aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode= AURA_REMOVE_BY_DEFAULT); + void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); + inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode); + void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); + void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); + void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); + void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except=NULL); + void RemoveAurasByTypeWithDispel(AuraType auraType, Spell * spell = NULL); + void RemoveNotOwnSingleTargetAuras(); + bool RemoveNoStackAurasDueToAura(Aura *Aur); + void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = NULL); + void RemoveAllAuras(); + void RemoveArenaAuras(bool onleave = false); + void RemoveAllAurasOnDeath(); + void DelayAura(uint32 spellId, uint64 caster, int32 delaytime); + + float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); } + void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); } + void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModSignedFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } + void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); } + void InitStatBuffMods() + { + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_POSSTAT0+i, 0); + for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(UNIT_FIELD_NEGSTAT0+i, 0); + } + void ApplyStatBuffMod(Stats stat, float val, bool apply) { ApplyModSignedFloatValue((val > 0 ? UNIT_FIELD_POSSTAT0+stat : UNIT_FIELD_NEGSTAT0+stat), val, apply); } + void ApplyStatPercentBuffMod(Stats stat, float val, bool apply) + { + ApplyPercentModFloatValue(UNIT_FIELD_POSSTAT0+stat, val, apply); + ApplyPercentModFloatValue(UNIT_FIELD_NEGSTAT0+stat, val, apply); + } + void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; } + void SetCreateHealth(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_HEALTH, val); } + uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); } + void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); } + uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); } + uint32 GetCreatePowers(Powers power) const; + float GetPosStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_POSSTAT0+stat); } + float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); } + float GetCreateStat(Stats stat) const { return m_createStats[stat]; } + + void SetCurrentCastedSpell(Spell * pSpell); + virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } + void InterruptSpell(uint32 spellType, bool withDelayed = true); + + // set withDelayed to true to account delayed spells as casted + // delayed+channeled spells are always accounted as casted + // we can skip channeled or delayed checks using flags + bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false) const; + + // set withDelayed to true to interrupt delayed spells too + // delayed+channeled spells are always interrupted + void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0); + + Spell* FindCurrentSpellBySpellId(uint32 spell_id) const; + + Spell* m_currentSpells[CURRENT_MAX_SPELL]; + + uint32 m_addDmgOnce; + uint64 m_SummonSlot[MAX_SUMMON_SLOT]; + uint64 m_ObjectSlot[4]; + uint32 m_detectInvisibilityMask; + uint32 m_invisibilityMask; + + uint32 m_ShapeShiftFormSpellId; + ShapeshiftForm m_form; + bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; } + + float m_modMeleeHitChance; + float m_modRangedHitChance; + float m_modSpellHitChance; + int32 m_baseSpellCritChance; + + float m_threatModifier[MAX_SPELL_SCHOOL]; + float m_modAttackSpeedPct[3]; + + // Event handler + EventProcessor m_Events; + + // stat system + bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply); + void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; } + float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const; + float GetTotalStatValue(Stats stat) const; + float GetTotalAuraModValue(UnitMods unitMod) const; + SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const; + Stats GetStatByAuraGroup(UnitMods unitMod) const; + Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const; + bool CanModifyStats() const { return m_canModifyStats; } + void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; } + virtual bool UpdateStats(Stats stat) = 0; + virtual bool UpdateAllStats() = 0; + virtual void UpdateResistances(uint32 school) = 0; + virtual void UpdateArmor() = 0; + virtual void UpdateMaxHealth() = 0; + virtual void UpdateMaxPower(Powers power) = 0; + virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0; + virtual void UpdateDamagePhysical(WeaponAttackType attType) = 0; + float GetTotalAttackPowerValue(WeaponAttackType attType) const; + float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const; + void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } + + bool isInFront(Unit const* target,float distance, float arc = M_PI) const; + void SetInFront(Unit const* target); + bool isInBack(Unit const* target, float distance, float arc = M_PI) const; + bool isInLine(Unit const* target, float distance) const; + + // Visibility system + UnitVisibility GetVisibility() const { return m_Visibility; } + void SetVisibility(UnitVisibility x); + void DestroyForNearbyPlayers(); + + // common function for visibility checks for player/creatures with detection code + virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const = 0; + bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const; + bool canDetectInvisibilityOf(Unit const* u) const; + bool canDetectStealthOf(Unit const* u, float distance) const; + void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask + + // virtual functions for all world objects types + bool isVisibleForInState(Player const* u, bool inVisibleList) const; + // function for low level grid visibility checks in player/creature cases + virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0; + + AuraList & GetSingleCastAuras() { return m_scAuras; } + AuraList const& GetSingleCastAuras() const { return m_scAuras; } + SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; + + // Threat related methods + bool CanHaveThreatList() const; + void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL); + float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL); + void DeleteThreatList(); + void TauntApply(Unit* pVictim); + void TauntFadeOut(Unit *taunter); + ThreatManager& getThreatManager() { return m_ThreatManager; } + void addHatedBy(HostilReference* pHostilReference) { m_HostilRefManager.insertFirst(pHostilReference); }; + void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ } + HostilRefManager& getHostilRefManager() { return m_HostilRefManager; } + + VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; } + Aura * GetVisibleAura(uint8 slot) + { + VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); + if(itr != m_visibleAuras.end()) + return itr->second; + return 0; + } + void SetVisibleAura(uint8 slot, Aura * aur){ m_visibleAuras[slot]=aur; } + void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); } + + AuraMap & GetAuras() { return m_Auras; } + AuraMap const& GetAuras() const { return m_Auras; } + AuraEffectList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; } + + AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const; + Aura * GetAura(uint32 spellId, uint64 casterGUID = 0) const; + AuraEffect* GetAura(AuraType type, uint32 family, uint32 familyFlag1 , uint32 familyFlag2=0, uint32 familyFlag3=0, uint64 casterGUID=0); + bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster = 0) const; + bool HasAura(uint32 spellId, uint64 caster = 0) const; + bool HasAuraType(AuraType auraType) const; + bool HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const; + + int32 GetTotalAuraModifier(AuraType auratype) const; + float GetTotalAuraMultiplier(AuraType auratype) const; + int32 GetMaxPositiveAuraModifier(AuraType auratype); + int32 GetMaxNegativeAuraModifier(AuraType auratype) const; + + int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; + float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const; + int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; + int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const; + + int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; + float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const; + int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; + int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const; + + AuraEffect* GetDummyAura(uint32 spell_id) const; + uint32 GetInterruptMask() const { return m_interruptMask; } + void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } + void UpdateInterruptMask(); + + uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } + void SetDisplayId(uint32 modelId); + uint32 GetNativeDisplayId() { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } + void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } + void setTransForm(uint32 spellid) { m_transform = spellid;} + uint32 getTransForm() const { return m_transform;} + void AddDynObject(DynamicObject* dynObj); + void RemoveDynObject(uint32 spellid); + void RemoveDynObjectWithGUID(uint64 guid) { m_dynObjGUIDs.remove(guid); } + void RemoveAllDynObjects(); + void AddGameObject(GameObject* gameObj); + void RemoveGameObject(GameObject* gameObj, bool del); + void RemoveGameObject(uint32 spellid, bool del); + void RemoveAllGameObjects(); + DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex); + DynamicObject *GetDynObject(uint32 spellId); + uint32 CalculateDamage(WeaponAttackType attType, bool normalized); + float GetAPMultiplier(WeaponAttackType attType, bool normalized); + void ModifyAuraState(AuraState flag, bool apply); + bool HasAuraState(AuraState flag, SpellEntry const *spellProto = NULL, Unit * Caster = NULL) const ; + void UnsummonAllTotems(); + int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask); + int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask); + int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); + int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); + uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); + bool isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK); + bool isBlockCritical(); + bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK); + uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); + uint32 SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); + + void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; } + bool IsUnderLastManaUseEffect() const; + + void SetContestedPvP(Player *attackedPlayer = NULL); + + void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL); + uint32 GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime ); + + void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); + void ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType type, bool apply); + virtual bool IsImmunedToSpell(SpellEntry const* spellInfo); + // redefined in Creature + bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask); + virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const; + // redefined in Creature + + uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK); + void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL); + + void UpdateSpeed(UnitMoveType mtype, bool forced); + float GetSpeed( UnitMoveType mtype ) const; + float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; } + void SetSpeed(UnitMoveType mtype, float rate, bool forced = false); + float m_TempSpeed; + + void SetHover(bool on); + bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); } + + void _RemoveAllAuraMods(); + void _ApplyAllAuraMods(); + + int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target); + int32 CalcSpellDuration(SpellEntry const* spellProto); + int32 ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive); + void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell const * spell=NULL); + float CalculateLevelPenalty(SpellEntry const* spellProto) const; + + void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } + void removeFollower(FollowerReference* /*pRef*/ ) { /* nothing to do yet */ } + static Unit* GetUnit(WorldObject& object, uint64 guid); + + MotionMaster* GetMotionMaster() { return &i_motionMaster; } + + bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); } + void StopMoving(); + + void AddUnitMovementFlag(uint32 f) { m_unit_movement_flags |= f; } + void RemoveUnitMovementFlag(uint32 f) + { + uint32 oldval = m_unit_movement_flags; + m_unit_movement_flags = oldval & ~f; + } + uint32 HasUnitMovementFlag(uint32 f) const { return m_unit_movement_flags & f; } + uint32 GetUnitMovementFlags() const { return m_unit_movement_flags; } + void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; } + + void SetControlled(bool apply, UnitState state); + + void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); } + void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); } + void ClearComboPointHolders(); + + ///----------Pet responses methods----------------- + void SendPetCastFail(uint32 spellid, SpellCastResult msg); + void SendPetActionFeedback (uint8 msg); + void SendPetTalk (uint32 pettalk); + void SendPetSpellCooldown (uint32 spellid, time_t cooltime); + void SendPetClearCooldown (uint32 spellid); + void SendPetAIReaction(uint64 guid); + ///----------End of Pet responses methods---------- + + void propagateSpeedChange() { GetMotionMaster()->propagateSpeedChange(); } + + // reactive attacks + void ClearAllReactives(); + void StartReactiveTimer( ReactiveType reactive ) { m_reactiveTimer[reactive] = REACTIVE_TIMER_START;} + void UpdateReactives(uint32 p_time); + + // group updates + void UpdateAuraForGroup(uint8 slot); + + // pet auras + typedef std::set PetAuraSet; + PetAuraSet m_petAuras; + void AddPetAura(PetAura const* petSpell); + void RemovePetAura(PetAura const* petSpell); + + void SetToNotify(); + bool m_Notified, m_IsInNotifyList; + void SetReducedThreatPercent(uint32 pct, uint64 guid) + { + m_reducedThreatPercent = pct; + m_misdirectionTargetGUID = guid; + } + uint32 GetReducedThreatPercent() { return m_reducedThreatPercent; } + Unit *GetMisdirectionTarget() { return m_misdirectionTargetGUID ? GetUnit(*this, m_misdirectionTargetGUID) : NULL; } + + bool IsAIEnabled, NeedChangeAI; + protected: + explicit Unit (); + + UnitAI *i_AI, *i_disabledAI; + + void _UpdateSpells(uint32 time); + + void _UpdateAutoRepeatSpell(); + bool m_AutoRepeatFirstCast; + + uint32 m_attackTimer[MAX_ATTACK]; + + float m_createStats[MAX_STATS]; + + AttackerSet m_attackers; + Unit* m_attacking; + + DeathState m_deathState; + + AuraMap m_Auras; + + typedef std::list DynObjectGUIDs; + DynObjectGUIDs m_dynObjGUIDs; + + std::list m_gameObj; + bool m_isSorted; + uint32 m_transform; + uint32 m_removedAuras; + + AuraEffectList m_modAuras[TOTAL_AURAS]; + AuraList m_scAuras; // casted singlecast auras + AuraList m_interruptableAuras; + AuraList m_ccAuras; + uint32 m_interruptMask; + + float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]; + float m_weaponDamage[MAX_ATTACK][2]; + bool m_canModifyStats; + //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem + VisibleAuraMap m_visibleAuras; + + float m_speed_rate[MAX_MOVE_TYPE]; + + CharmInfo *m_charmInfo; + SharedVisionList m_sharedVision; + + virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; + + MotionMaster i_motionMaster; + uint32 m_unit_movement_flags; + + uint32 m_reactiveTimer[MAX_REACTIVE]; + uint32 m_regenTimer; + + ThreatManager m_ThreatManager; + + private: + void SendAttackStop(Unit* victim); // only from AttackStop(Unit*) + //void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*) + + bool IsTriggeredAtSpellProcEvent(Unit *pVictim, AuraEffect* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ); + bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleObsModEnergyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown); + bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura); + bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura); + + void SetFeared(bool apply); + void SetConfused(bool apply); + void SetStunned(bool apply); + void SetRooted(bool apply); + + uint32 m_state; // Even derived shouldn't modify + uint32 m_CombatTimer; + uint32 m_lastManaUse; // msecs + + UnitVisibility m_Visibility; + + Diminishing m_Diminishing; + // Manage all Units threatening us +// ThreatManager m_ThreatManager; + // Manage all Units that are threatened by us + HostilRefManager m_HostilRefManager; + + FollowerRefManager m_FollowingRefManager; + + ComboPointHolderSet m_ComboPointHolders; + + uint32 m_reducedThreatPercent; + uint64 m_misdirectionTargetGUID; +}; +#endif + -- cgit v1.2.3