diff options
Diffstat (limited to 'src/game/Level2.cpp')
| -rw-r--r-- | src/game/Level2.cpp | 2561 | 
1 files changed, 1562 insertions, 999 deletions
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 4937d230142..ef3cb99d919 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1,7 +1,7 @@  /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>   * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>   *   * 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 @@ -10,19 +10,16 @@   *   * 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 + * 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 + * 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 "Player.h"  #include "Item.h" @@ -33,9 +30,11 @@  #include "MapManager.h"  #include "Language.h"  #include "World.h" -#include "GameEvent.h" +#include "GameEventMgr.h"  #include "SpellMgr.h" +#include "PoolHandler.h"  #include "AccountMgr.h" +#include "TicketMgr.h"  #include "WaypointManager.h"  #include "Util.h"  #include <cctype> @@ -46,6 +45,7 @@  #include "TicketMgr.h"  #include "TargetedMovementGenerator.h"                      // for HandleNpcUnFollowCommand +#include "CreatureGroups.h"  static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =  { @@ -59,11 +59,13 @@ bool ChatHandler::HandleMuteCommand(const char* args)      if (!*args)          return false; -    char *charname = strtok((char*)args, " "); -    if (!charname) +    std::string name = extractPlayerNameFromLink((char*)args); +    if(name.empty()) +    { +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true);          return false; - -    std::string cname = charname; +    }      char *timetonotspeak = strtok(NULL, " ");      if(!timetonotspeak) @@ -71,14 +73,7 @@ bool ChatHandler::HandleMuteCommand(const char* args)      uint32 notspeaktime = (uint32) atoi(timetonotspeak); -    if(!normalizePlayerName(cname)) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); +    uint64 guid = objmgr.GetPlayerGUIDByName(name);      if(!guid)      {          SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -88,27 +83,11 @@ bool ChatHandler::HandleMuteCommand(const char* args)      Player *chr = objmgr.GetPlayer(guid); -    // check security -    uint32 account_id = 0; -    uint32 security = 0; - -    if (chr) -    { -        account_id = chr->GetSession()->GetAccountId(); -        security = chr->GetSession()->GetSecurity(); -    } -    else -    { -        account_id = objmgr.GetPlayerAccountIdByGUID(guid); -        security = accmgr.GetSecurity(account_id); -    } - -    if(m_session && security >= m_session->GetSecurity()) -    { -        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); -        SetSentErrorMessage(true); +    // must have strong lesser security level +    if(HasLowerSecurity (chr,guid,true))          return false; -    } + +    uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);      time_t mutetime = time(NULL) + notspeaktime*60; @@ -120,7 +99,9 @@ bool ChatHandler::HandleMuteCommand(const char* args)      if(chr)          ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); -    PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime); +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);      return true;  } @@ -131,20 +112,15 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)      if (!*args)          return false; -    char *charname = strtok((char*)args, " "); -    if (!charname) -        return false; - -    std::string cname = charname; - -    if(!normalizePlayerName(cname)) +    std::string name = extractPlayerNameFromLink((char*)args); +    if(name.empty())      {          SendSysMessage(LANG_PLAYER_NOT_FOUND);          SetSentErrorMessage(true);          return false;      } -    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); +    uint64 guid = objmgr.GetPlayerGUIDByName(name);      if(!guid)      {          SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -154,27 +130,11 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)      Player *chr = objmgr.GetPlayer(guid); -    // check security -    uint32 account_id = 0; -    uint32 security = 0; - -    if (chr) -    { -        account_id = chr->GetSession()->GetAccountId(); -        security = chr->GetSession()->GetSecurity(); -    } -    else -    { -        account_id = objmgr.GetPlayerAccountIdByGUID(guid); -        security = accmgr.GetSecurity(account_id); -    } - -    if(m_session && security >= m_session->GetSecurity()) -    { -        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); -        SetSentErrorMessage(true); +    // must have strong lesser security level +    if(HasLowerSecurity (chr,guid,true))          return false; -    } + +    uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);      if (chr)      { @@ -193,161 +153,15 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)      if(chr)          ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); -    PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str()); -    return true; -} - -bool ChatHandler::HandleTargetObjectCommand(const char* args) -{ -    Player* pl = m_session->GetPlayer(); -    QueryResult *result; -    GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList(); -    if(*args) -    { -        int32 id = atoi((char*)args); -        if(id) -            result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", -                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id); -        else -        { -            std::string name = args; -            WorldDatabase.escape_string(name); -            result = WorldDatabase.PQuery( -                "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " -                "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1", -                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str()); -        } -    } -    else -    { -        std::ostringstream eventFilter; -        eventFilter << " AND (event IS NULL "; -        bool initString = true; - -        for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr) -        { -            if (initString) -            { -                eventFilter  <<  "OR event IN (" <<*itr; -                initString =false; -            } -            else -                eventFilter << "," << *itr; -        } - -        if (!initString) -            eventFilter << "))"; -        else -            eventFilter << ")"; - -        result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, " -            "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject " -            "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1", -            m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str()); -    } - -    if (!result) -    { -        SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND); -        return true; -    } - -    Field *fields = result->Fetch(); -    uint32 lowguid = fields[0].GetUInt32(); -    uint32 id = fields[1].GetUInt32(); -    float x = fields[2].GetFloat(); -    float y = fields[3].GetFloat(); -    float z = fields[4].GetFloat(); -    float o = fields[5].GetFloat(); -    int mapid = fields[6].GetUInt16(); -    delete result; - -    GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id); - -    if (!goI) -    { -        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); -        return false; -    } - -    GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT)); - -    PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o); - -    if(target) -    { -        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_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); -    } -    return true; -} - -//teleport to gameobject -bool ChatHandler::HandleGoObjectCommand(const char* args) -{ -    if(!*args) -        return false; - -    Player* _player = m_session->GetPlayer(); - -    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r -    char* cId = extractKeyFromLink((char*)args,"Hgameobject"); -    if(!cId) -        return false; +    std::string nameLink = playerLink(name); -    int32 guid = atoi(cId); -    if(!guid) -        return false; - -    float x, y, z, ort; -    int mapid; - -    // by DB guid -    if (GameObjectData const* go_data = objmgr.GetGOData(guid)) -    { -        x = go_data->posX; -        y = go_data->posY; -        z = go_data->posZ; -        ort = go_data->orientation; -        mapid = go_data->mapid; -    } -    else -    { -        SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) -    { -        PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid); -        SetSentErrorMessage(true); -        return false; -    } - -    // stop flight if need -    if(_player->isInFlight()) -    { -        _player->GetMotionMaster()->MovementExpired(); -        _player->m_taxi.ClearTaxiDestinations(); -    } -    // save only in non-flight case -    else -        _player->SaveRecallPosition(); - -    _player->TeleportTo(mapid, x, y, z, ort); +    PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());      return true;  }  bool ChatHandler::HandleGoTicketCommand(const char * args)  { -     if(!*args) +    if(!*args)          return false;      char *cstrticket_id = strtok((char*)args, " "); @@ -478,15 +292,15 @@ bool ChatHandler::HandleGoGraveyardCommand(const char* args)  }  /** \brief Teleport the GM to the specified creature - * - * .gocreature <GUID>      --> TP using creature.guid - * .gocreature azuregos    --> TP player to the mob with this name - *                             Warning: If there is more than one mob with this name - *                                      you will be teleported to the first one that is found. - * .gocreature id 6109     --> TP player to the mob, that has this creature_template.entry - *                             Warning: If there is more than one mob with this "id" - *                                      you will be teleported to the first one that is found. - */ +* +* .gocreature <GUID>      --> TP using creature.guid +* .gocreature azuregos    --> TP player to the mob with this name +*                             Warning: If there is more than one mob with this name +*                                      you will be teleported to the first one that is found. +* .gocreature id 6109     --> TP player to the mob, that has this creature_template.entry +*                             Warning: If there is more than one mob with this "id" +*                                      you will be teleported to the first one that is found. +*/  //teleport to creature  bool ChatHandler::HandleGoCreatureCommand(const char* args)  { @@ -584,434 +398,180 @@ bool ChatHandler::HandleGoCreatureCommand(const char* args)      return true;  } -bool ChatHandler::HandleGUIDCommand(const char* /*args*/) +//teleport to gameobject +bool ChatHandler::HandleGoObjectCommand(const char* args)  { -    uint64 guid = m_session->GetPlayer()->GetSelection(); - -    if (guid == 0) -    { -        SendSysMessage(LANG_NO_SELECTION); -        SetSentErrorMessage(true); +    if(!*args)          return false; -    } -    PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); -    return true; -} +    Player* _player = m_session->GetPlayer(); -bool ChatHandler::HandleLookupFactionCommand(const char* args) -{ -    if (!*args) +    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r +    char* cId = extractKeyFromLink((char*)args,"Hgameobject"); +    if(!cId)          return false; -    // Can be NULL at console call -    Player *target = getSelectedPlayer (); - -    std::string namepart = args; -    std::wstring wnamepart; - -    if (!Utf8toWStr (namepart,wnamepart)) +    int32 guid = atoi(cId); +    if(!guid)          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. +    float x, y, z, ort; +    int mapid; -    for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id) +    // by DB guid +    if (GameObjectData const* go_data = objmgr.GetGOData(guid))      { -        FactionEntry const *factionEntry = sFactionStore.LookupEntry (id); -        if (factionEntry) -        { -            FactionState const* repState = NULL; -            if(target) -            { -                FactionStateList::const_iterator repItr = target->m_factions.find (factionEntry->reputationListID); -                if(repItr != target->m_factions.end()) -                    repState = &repItr->second; -            } - -            int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); -            std::string name = factionEntry->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 = factionEntry->name[loc]; -                    if(name.empty()) -                        continue; - -                    if (Utf8FitTo(name, wnamepart)) -                        break; -                } -            } - -            if(loc < MAX_LOCALE) -            { -                // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format -                // or              "id - [faction] [no reputation]" format -                std::ostringstream ss; -                if (m_session) -                    ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r"; -                else -                    ss << id << " - " << name << " " << localeNames[loc]; - -                if (repState)                               // and then target!=NULL also -                { -                    ReputationRank rank = target->GetReputationRank(factionEntry); -                    std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]); - -                    ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")"; - -                    if(repState->Flags & FACTION_FLAG_VISIBLE) -                        ss << GetTrinityString(LANG_FACTION_VISIBLE); -                    if(repState->Flags & FACTION_FLAG_AT_WAR) -                        ss << GetTrinityString(LANG_FACTION_ATWAR); -                    if(repState->Flags & FACTION_FLAG_PEACE_FORCED) -                        ss << GetTrinityString(LANG_FACTION_PEACE_FORCED); -                    if(repState->Flags & FACTION_FLAG_HIDDEN) -                        ss << GetTrinityString(LANG_FACTION_HIDDEN); -                    if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED) -                        ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); -                    if(repState->Flags & FACTION_FLAG_INACTIVE) -                        ss << GetTrinityString(LANG_FACTION_INACTIVE); -                } -                else -                    ss << GetTrinityString(LANG_FACTION_NOREPUTATION); - -                SendSysMessage(ss.str().c_str()); -                counter++; -            } -        } +        x = go_data->posX; +        y = go_data->posY; +        z = go_data->posZ; +        ort = go_data->orientation; +        mapid = go_data->mapid;      } - -    if (counter == 0)                                       // if counter == 0 then we found nth -        SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND); -    return true; -} - -bool ChatHandler::HandleModifyRepCommand(const char * args) -{ -    if (!*args) return false; - -    Player* target = NULL; -    target = getSelectedPlayer(); - -    if(!target) +    else      { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);          SetSentErrorMessage(true);          return false;      } -    char* factionTxt = extractKeyFromLink((char*)args,"Hfaction"); -    if(!factionTxt) -        return false; - -    uint32 factionId = atoi(factionTxt); - -    int32 amount = 0; -    char *rankTxt = strtok(NULL, " "); -    if (!factionTxt || !rankTxt) -        return false; - -    amount = atoi(rankTxt); -    if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0])) -    { -        std::string rankStr = rankTxt; -        std::wstring wrankStr; -        if(!Utf8toWStr(rankStr,wrankStr)) -            return false; -        wstrToLower( wrankStr ); - -        int r = 0; -        amount = -42000; -        for (; r < MAX_REPUTATION_RANK; ++r) -        { -            std::string rank = GetTrinityString(ReputationRankStrIndex[r]); -            if(rank.empty()) -                continue; - -            std::wstring wrank; -            if(!Utf8toWStr(rank,wrank)) -                continue; - -            wstrToLower(wrank); - -            if(wrank.substr(0,wrankStr.size())==wrankStr) -            { -                char *deltaTxt = strtok(NULL, " "); -                if (deltaTxt) -                { -                    int32 delta = atoi(deltaTxt); -                    if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1)) -                    { -                        PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1)); -                        SetSentErrorMessage(true); -                        return false; -                    } -                    amount += delta; -                } -                break; -            } -            amount += Player::ReputationRank_Length[r]; -        } -        if (r >= MAX_REPUTATION_RANK) -        { -            PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt); -            SetSentErrorMessage(true); -            return false; -        } -    } - -    FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId); - -    if (!factionEntry) +    if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))      { -        PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId); +        PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);          SetSentErrorMessage(true);          return false;      } -    if (factionEntry->reputationListID < 0) +    // stop flight if need +    if(_player->isInFlight())      { -        PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId); -        SetSentErrorMessage(true); -        return false; +        _player->GetMotionMaster()->MovementExpired(); +        _player->m_taxi.ClearTaxiDestinations();      } +    // save only in non-flight case +    else +        _player->SaveRecallPosition(); -    target->SetFactionReputation(factionEntry,amount); -    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId)); +    _player->TeleportTo(mapid, x, y, z, ort);      return true;  } -bool ChatHandler::HandleNameCommand(const char* args) +bool ChatHandler::HandleGameObjectTargetCommand(const char* args)  { -    /* Temp. disabled -        if(!*args) +    Player* pl = m_session->GetPlayer(); +    QueryResult *result; +    GameEventMgr::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList(); +    if(*args) +    { +        // 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; -        if(strlen((char*)args)>75) +        uint32 id = atol(cId); + +        if(id) +            result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", +                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id); +        else          { -            PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75); -            return true; +            std::string name = cId; +            WorldDatabase.escape_string(name); +            result = WorldDatabase.PQuery( +                "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " +                "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1", +                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());          } +    } +    else +    { +        std::ostringstream eventFilter; +        eventFilter << " AND (event IS NULL "; +        bool initString = true; -        for (uint8 i = 0; i < strlen(args); i++) +        for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)          { -            if(!isalpha(args[i]) && args[i]!=' ') +            if (initString)              { -                SendSysMessage(LANG_CHARS_ONLY); -                return false; +                eventFilter  <<  "OR event IN (" <<*itr; +                initString =false;              } +            else +                eventFilter << "," << *itr;          } -        uint64 guid; -        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; -        } - -        pCreature->SetName(args); -        uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName()); -        pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); - -        pCreature->SaveToDB(); -    */ - -    return true; -} - -bool ChatHandler::HandleSubNameCommand(const char* /*args*/) -{ -    /* Temp. disabled - -    if(!*args) -        args = ""; - -    if(strlen((char*)args)>75) -    { +        if (!initString) +            eventFilter << "))"; +        else +            eventFilter << ")"; -        PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75); -        return true; +        result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, " +            "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject " +            "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10", +            m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());      } -    for (uint8 i = 0; i < strlen(args); i++) -    { -        if(!isalpha(args[i]) && args[i]!=' ') -        { -            SendSysMessage(LANG_CHARS_ONLY); -            return false; -        } -    } -    uint64 guid; -    guid = m_session->GetPlayer()->GetSelection(); -    if (guid == 0) +    if (!result)      { -        SendSysMessage(LANG_NO_SELECTION); +        SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);          return true;      } -    Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid); +    bool found = false; +    float x, y, z, o; +    uint32 lowguid, id; +    uint16 mapid, pool_id; -    if(!pCreature) +    do      { -        SendSysMessage(LANG_SELECT_CREATURE); -        return true; -    } - -    uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID)); -    pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); - -    pCreature->SaveToDB(); -    */ -    return true; -} - -//move item to other slot -bool ChatHandler::HandleItemMoveCommand(const char* args) -{ -    if(!*args) -        return false; -    uint8 srcslot, dstslot; - -    char* pParam1 = strtok((char*)args, " "); -    if (!pParam1) -        return false; - -    char* pParam2 = strtok(NULL, " "); -    if (!pParam2) -        return false; - -    srcslot = (uint8)atoi(pParam1); -    dstslot = (uint8)atoi(pParam2); - -    if(srcslot==dstslot) -        return true; - -    if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot)) -        return false; - -    if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot)) -        return false; - -    uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot); -    uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot); - -    m_session->GetPlayer()->SwapItem( src, dst ); - -    return true; -} - -//add spawn of creature -bool ChatHandler::HandleNpcAddCommand(const char* args) -{ -    if(!*args) -        return false; -    char* charID = strtok((char*)args, " "); -    if (!charID) -        return false; - -    char* team = strtok(NULL, " "); -    int32 teamval = 0; -    if (team) { teamval = atoi(team); } -    if (teamval < 0) { teamval = 0; } - -    uint32 id  = atoi(charID); +        Field *fields = result->Fetch(); +        lowguid = fields[0].GetUInt32(); +        id =      fields[1].GetUInt32(); +        x =       fields[2].GetFloat(); +        y =       fields[3].GetFloat(); +        z =       fields[4].GetFloat(); +        o =       fields[5].GetFloat(); +        mapid =   fields[6].GetUInt16(); +        pool_id = poolhandler.IsPartOfAPool(lowguid, TYPEID_GAMEOBJECT); +        if (!pool_id || (pool_id && poolhandler.IsSpawnedObject(pool_id, lowguid, TYPEID_GAMEOBJECT))) +            found = true; +    } while( result->NextRow() && (!found) ); -    Player *chr = m_session->GetPlayer(); -    float x = chr->GetPositionX(); -    float y = chr->GetPositionY(); -    float z = chr->GetPositionZ(); -    float o = chr->GetOrientation(); -    Map *map = chr->GetMap(); +    delete result; -    Creature* pCreature = new Creature; -    if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval)) +    if (!found)      { -        delete pCreature; +        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);          return false;      } -    pCreature->Relocate(x,y,z,o); +    GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id); -    if(!pCreature->IsPositionValid()) +    if (!goI)      { -        sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); -        delete pCreature; +        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);          return false;      } -    pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); - -    uint32 db_guid = pCreature->GetDBTableGUIDLow(); +    GameObject* target = m_session->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT)); -    // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); -    pCreature->LoadFromDB(db_guid, map); - -    map->Add(pCreature); -    objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid)); -    return true; -} - -bool ChatHandler::HandleNpcDeleteCommand(const char* args) -{ -    Creature* unit = NULL; +    PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o); -    if(*args) +    if(target)      { -        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r -        char* cId = extractKeyFromLink((char*)args,"Hcreature"); -        if(!cId) -            return false; - -        uint32 lowguid = atoi(cId); -        if(!lowguid) -            return false; +        int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); +        if(curRespawnDelay < 0) +            curRespawnDelay = 0; -        if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid)) -            unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT)); -    } -    else -        unit = getSelectedCreature(); +        std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); +        std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); -    if(!unit || unit->isPet() || unit->isTotem()) -    { -        SendSysMessage(LANG_SELECT_CREATURE); -        SetSentErrorMessage(true); -        return false; +        PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());      } - -    // Delete the creature -    unit->CombatStop(); -    unit->DeleteFromDB(); -    unit->CleanupsBeforeDelete(); -    unit->AddObjectToRemoveList(); - -    SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); -      return true;  }  //delete object by selection or guid -bool ChatHandler::HandleDelObjectCommand(const char* args) +bool ChatHandler::HandleGameObjectDeleteCommand(const char* args)  {      // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r      char* cId = extractKeyFromLink((char*)args,"Hgameobject"); @@ -1039,7 +599,7 @@ bool ChatHandler::HandleDelObjectCommand(const char* args)      if(owner_guid)      {          Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid); -        if(!owner && !IS_PLAYER_GUID(owner_guid)) +        if(!owner || !IS_PLAYER_GUID(owner_guid))          {              PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());              SetSentErrorMessage(true); @@ -1059,7 +619,7 @@ bool ChatHandler::HandleDelObjectCommand(const char* args)  }  //turn selected object -bool ChatHandler::HandleTurnObjectCommand(const char* args) +bool ChatHandler::HandleGameObjectTurnCommand(const char* args)  {      // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r      char* cId = extractKeyFromLink((char*)args,"Hgameobject"); @@ -1096,109 +656,24 @@ bool ChatHandler::HandleTurnObjectCommand(const char* args)          o = chr->GetOrientation();      } -    float rot2 = sin(o/2); -    float rot3 = cos(o/2); - -    Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); +    Map* map = obj->GetMap();      map->Remove(obj,false);      obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o); - -    obj->SetFloatValue(GAMEOBJECT_FACING, o); -    obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2); -    obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3); +    obj->UpdateRotationFields();      map->Add(obj);      obj->SaveToDB();      obj->Refresh(); -    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o); - -    return true; -} - -//move selected creature -bool ChatHandler::HandleNpcMoveCommand(const char* args) -{ -    uint32 lowguid = 0; - -    Creature* pCreature = getSelectedCreature(); - -    if(!pCreature) -    { -        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r -        char* cId = extractKeyFromLink((char*)args,"Hcreature"); -        if(!cId) -            return false; - -        uint32 lowguid = atoi(cId); - -        /* FIXME: impossibel without entry -        if(lowguid) -            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); -        */ +    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow(), o); -        // Attempting creature load from DB data -        if(!pCreature) -        { -            CreatureData const* data = objmgr.GetCreatureData(lowguid); -            if(!data) -            { -                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); -                SetSentErrorMessage(true); -                return false; -            } - -            uint32 map_id = data->mapid; - -            if(m_session->GetPlayer()->GetMapId()!=map_id) -            { -                PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); -                SetSentErrorMessage(true); -                return false; -            } -        } -        else -        { -            lowguid = pCreature->GetDBTableGUIDLow(); -        } -    } -    else -    { -        lowguid = pCreature->GetDBTableGUIDLow(); -    } - -    float x = m_session->GetPlayer()->GetPositionX(); -    float y = m_session->GetPlayer()->GetPositionY(); -    float z = m_session->GetPlayer()->GetPositionZ(); -    float o = m_session->GetPlayer()->GetOrientation(); - -    if (pCreature) -    { -        if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow())) -        { -            const_cast<CreatureData*>(data)->posX = x; -            const_cast<CreatureData*>(data)->posY = y; -            const_cast<CreatureData*>(data)->posZ = z; -            const_cast<CreatureData*>(data)->orientation = o; -        } -        MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o); -        pCreature->GetMotionMaster()->Initialize(); -        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn -        { -            pCreature->setDeathState(JUST_DIED); -            pCreature->Respawn(); -        } -    } - -    WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); -    PSendSysMessage(LANG_COMMAND_CREATUREMOVED);      return true;  }  //move selected object -bool ChatHandler::HandleMoveObjectCommand(const char* args) +bool ChatHandler::HandleGameObjectMoveCommand(const char* args)  {      // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r      char* cId = extractKeyFromLink((char*)args,"Hgameobject"); @@ -1230,7 +705,7 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)      {          Player *chr = m_session->GetPlayer(); -        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); +        Map* map = obj->GetMap();          map->Remove(obj,false);          obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation()); @@ -1256,7 +731,7 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)              return false;          } -        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); +        Map* map = obj->GetMap();          map->Remove(obj,false);          obj->Relocate(x, y, z, obj->GetOrientation()); @@ -1270,25 +745,422 @@ bool ChatHandler::HandleMoveObjectCommand(const char* args)      obj->SaveToDB();      obj->Refresh(); -    PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow()); +    PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());      return true;  } -//demorph player or unit -bool ChatHandler::HandleDeMorphCommand(const char* /*args*/) +//spawn go +bool ChatHandler::HandleGameObjectAddCommand(const char* args)  { -    Unit *target = getSelectedUnit(); +    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 id = atol(cId); +    if(!id) +        return false; + +    char* spawntimeSecs = strtok(NULL, " "); + +    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id); + +    if (!goI) +    { +        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); +        SetSentErrorMessage(true); +        return false; +    } + +    Player *chr = m_session->GetPlayer(); +    float x = float(chr->GetPositionX()); +    float y = float(chr->GetPositionY()); +    float z = float(chr->GetPositionZ()); +    float o = float(chr->GetOrientation()); +    Map *map = chr->GetMap(); + +    GameObject* pGameObj = new GameObject; +    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); + +    if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) +    { +        delete pGameObj; +        return false; +    } + +    if( spawntimeSecs ) +    { +        uint32 value = atoi((char*)spawntimeSecs); +        pGameObj->SetRespawnTime(value); +        //sLog.outDebug("*** spawntimeSecs: %d", value); +    } + +    // fill the gameobject data and save to the db +    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()),chr->GetPhaseMaskForSpawn()); + +    // this will generate a new guid if the object is in an instance +    if(!pGameObj->LoadFromDB(db_lowGUID, map)) +    { +        delete pGameObj; +        return false; +    } + +    sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o); + +    map->Add(pGameObj); + +    // TODO: is it really necessary to add both the real and DB table guid here ? +    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID)); + +    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z); +    return true; +} + +//set pahsemask for selected object +bool ChatHandler::HandleGameObjectPhaseCommand(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* obj = NULL; + +    // by DB guid +    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) +        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); + +    if(!obj) +    { +        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); +        SetSentErrorMessage(true); +        return false; +    } + +    char* phaseStr = strtok (NULL, " "); +    uint32 phasemask = phaseStr? atoi(phaseStr) : 0; +    if ( phasemask == 0 ) +    { +        SendSysMessage(LANG_BAD_VALUE); +        SetSentErrorMessage(true); +        return false; +    } + +    obj->SetPhaseMask(phasemask,true); +    obj->SaveToDB(); +    return true; +} + +bool ChatHandler::HandleGameObjectNearCommand(const char* args) +{ +    float distance = (!*args) ? 10 : atol(args); +    uint32 count = 0; + +    Player* pl = m_session->GetPlayer(); +    QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, 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 map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_", +        pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), +        pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance); + +    if (result) +    { +        do +        { +            Field *fields = result->Fetch(); +            uint32 guid = fields[0].GetUInt32(); +            uint32 entry = fields[1].GetUInt32(); +            float x = fields[2].GetFloat(); +            float y = fields[3].GetFloat(); +            float z = fields[4].GetFloat(); +            int mapid = fields[5].GetUInt16(); + +            GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry); + +            if(!gInfo) +                continue; + +            PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid); + +            ++count; +        } while (result->NextRow()); + +        delete result; +    } + +    PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count); +    return true; +} + +bool ChatHandler::HandleGUIDCommand(const char* /*args*/) +{ +    uint64 guid = m_session->GetPlayer()->GetSelection(); + +    if (guid == 0) +    { +        SendSysMessage(LANG_NO_SELECTION); +        SetSentErrorMessage(true); +        return false; +    } + +    PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); +    return true; +} + +bool ChatHandler::HandleLookupFactionCommand(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. + +    for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id) +    { +        FactionEntry const *factionEntry = sFactionStore.LookupEntry (id); +        if (factionEntry) +        { +            FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL; + +            int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); +            std::string name = factionEntry->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 = factionEntry->name[loc]; +                    if(name.empty()) +                        continue; + +                    if (Utf8FitTo(name, wnamepart)) +                        break; +                } +            } + +            if(loc < MAX_LOCALE) +            { +                // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format +                // or              "id - [faction] [no reputation]" format +                std::ostringstream ss; +                if (m_session) +                    ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r"; +                else +                    ss << id << " - " << name << " " << localeNames[loc]; + +                if (repState)                               // and then target!=NULL also +                { +                    ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); +                    std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); + +                    ss << " " << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ")"; + +                    if(repState->Flags & FACTION_FLAG_VISIBLE) +                        ss << GetTrinityString(LANG_FACTION_VISIBLE); +                    if(repState->Flags & FACTION_FLAG_AT_WAR) +                        ss << GetTrinityString(LANG_FACTION_ATWAR); +                    if(repState->Flags & FACTION_FLAG_PEACE_FORCED) +                        ss << GetTrinityString(LANG_FACTION_PEACE_FORCED); +                    if(repState->Flags & FACTION_FLAG_HIDDEN) +                        ss << GetTrinityString(LANG_FACTION_HIDDEN); +                    if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED) +                        ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); +                    if(repState->Flags & FACTION_FLAG_INACTIVE) +                        ss << GetTrinityString(LANG_FACTION_INACTIVE); +                } +                else +                    ss << GetTrinityString(LANG_FACTION_NOREPUTATION); + +                SendSysMessage(ss.str().c_str()); +                counter++; +            } +        } +    } + +    if (counter == 0)                                       // if counter == 0 then we found nth +        SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND); +    return true; +} + +bool ChatHandler::HandleModifyRepCommand(const char * args) +{ +    if (!*args) return false; + +    Player* target = NULL; +    target = getSelectedPlayer(); +      if(!target) -        target = m_session->GetPlayer(); +    { +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true); +        return false; +    } -    target->DeMorph(); +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; + +    char* factionTxt = extractKeyFromLink((char*)args,"Hfaction"); +    if(!factionTxt) +        return false; +    uint32 factionId = atoi(factionTxt); + +    int32 amount = 0; +    char *rankTxt = strtok(NULL, " "); +    if (!factionTxt || !rankTxt) +        return false; + +    amount = atoi(rankTxt); +    if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0])) +    { +        std::string rankStr = rankTxt; +        std::wstring wrankStr; +        if(!Utf8toWStr(rankStr,wrankStr)) +            return false; +        wstrToLower( wrankStr ); + +        int r = 0; +        amount = -42000; +        for (; r < MAX_REPUTATION_RANK; ++r) +        { +            std::string rank = GetTrinityString(ReputationRankStrIndex[r]); +            if(rank.empty()) +                continue; + +            std::wstring wrank; +            if(!Utf8toWStr(rank,wrank)) +                continue; + +            wstrToLower(wrank); + +            if(wrank.substr(0,wrankStr.size())==wrankStr) +            { +                char *deltaTxt = strtok(NULL, " "); +                if (deltaTxt) +                { +                    int32 delta = atoi(deltaTxt); +                    if ((delta < 0) || (delta > ReputationMgr::PointsInRank[r] -1)) +                    { +                        PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1)); +                        SetSentErrorMessage(true); +                        return false; +                    } +                    amount += delta; +                } +                break; +            } +            amount += ReputationMgr::PointsInRank[r]; +        } +        if (r >= MAX_REPUTATION_RANK) +        { +            PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt); +            SetSentErrorMessage(true); +            return false; +        } +    } + +    FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId); + +    if (!factionEntry) +    { +        PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId); +        SetSentErrorMessage(true); +        return false; +    } + +    if (factionEntry->reputationListID < 0) +    { +        PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId); +        SetSentErrorMessage(true); +        return false; +    } + +    target->GetReputationMgr().SetReputation(factionEntry,amount); +    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, +        GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); +    return true; +} + +//-----------------------Npc Commands----------------------- +//add spawn of creature +bool ChatHandler::HandleNpcAddCommand(const char* args) +{ +    if(!*args) +        return false; +    char* charID = extractKeyFromLink((char*)args,"Hcreature_entry"); +    if(!charID) +        return false; + +    char* team = strtok(NULL, " "); +    int32 teamval = 0; +    if (team) { teamval = atoi(team); } +    if (teamval < 0) { teamval = 0; } + +    uint32 id  = atoi(charID); + +    Player *chr = m_session->GetPlayer(); +    float x = chr->GetPositionX(); +    float y = chr->GetPositionY(); +    float z = chr->GetPositionZ(); +    float o = chr->GetOrientation(); +    Map *map = chr->GetMap(); + +    Creature* pCreature = new Creature; +    if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval)) +    { +        delete pCreature; +        return false; +    } + +    pCreature->Relocate(x,y,z,o); + +    if(!pCreature->IsPositionValid()) +    { +        sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); +        delete pCreature; +        return false; +    } + +    pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + +    uint32 db_guid = pCreature->GetDBTableGUIDLow(); + +    // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); +    pCreature->LoadFromDB(db_guid, map); + +    map->Add(pCreature); +    objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));      return true;  }  //add item in vendorlist -bool ChatHandler::HandleAddVendorItemCommand(const char* args) +bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args)  {      if (!*args)          return false; @@ -1335,7 +1207,7 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)  }  //del item from vendor list -bool ChatHandler::HandleDelVendorItemCommand(const char* args) +bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args)  {      if (!*args)          return false; @@ -1357,7 +1229,6 @@ bool ChatHandler::HandleDelVendorItemCommand(const char* args)      }      uint32 itemId = atol(pitem); -      if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))      {          PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); @@ -1413,9 +1284,11 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)      Player* player = m_session->GetPlayer(); +    //WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0); +      // update movement type      WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); -    if(pCreature && pCreature->GetWaypointPath()) +    if(pCreature && pCreature->GetWaypointPathId())      {          pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);          pCreature->GetMotionMaster()->Initialize(); @@ -1427,10 +1300,198 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)          pCreature->SaveToDB();      } +    SendSysMessage(LANG_WAYPOINT_ADDED); +      return true;  } -/** +//change level of creature or pet +bool ChatHandler::HandleNpcChangeLevelCommand(const char* args) +{ +    if (!*args) +        return false; + +    uint8 lvl = (uint8) atoi((char*)args); +    if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3) +    { +        SendSysMessage(LANG_BAD_VALUE); +        SetSentErrorMessage(true); +        return false; +    } + +    Creature* pCreature = getSelectedCreature(); +    if(!pCreature) +    { +        SendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true); +        return false; +    } + +    if(pCreature->isPet()) +    { +        if(((Pet*)pCreature)->getPetType()==HUNTER_PET) +        { +            pCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(lvl)/4); +            pCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); +        } +        ((Pet*)pCreature)->GivePetLevel(lvl); +    } +    else +    { +        pCreature->SetMaxHealth( 100 + 30*lvl); +        pCreature->SetHealth( 100 + 30*lvl); +        pCreature->SetLevel( lvl); +        pCreature->SaveToDB(); +    } + +    return true; +} + +//set npcflag of creature +bool ChatHandler::HandleNpcFlagCommand(const char* args) +{ +    if (!*args) +        return false; + +    uint32 npcFlags = (uint32) atoi((char*)args); + +    Creature* pCreature = getSelectedCreature(); + +    if(!pCreature) +    { +        SendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true); +        return false; +    } + +    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); + +    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); + +    SendSysMessage(LANG_VALUE_SAVED_REJOIN); + +    return true; +} + +bool ChatHandler::HandleNpcDeleteCommand(const char* args) +{ +    Creature* unit = NULL; + +    if(*args) +    { +        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r +        char* cId = extractKeyFromLink((char*)args,"Hcreature"); +        if(!cId) +            return false; + +        uint32 lowguid = atoi(cId); +        if(!lowguid) +            return false; + +        if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid)) +            unit = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT)); +    } +    else +        unit = getSelectedCreature(); + +    if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle()) +    { +        SendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true); +        return false; +    } + +    // Delete the creature +    unit->CombatStop(); +    unit->DeleteFromDB(); +    unit->CleanupsBeforeDelete(); +    unit->AddObjectToRemoveList(); + +    SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); + +    return true; +} + +//move selected creature +bool ChatHandler::HandleNpcMoveCommand(const char* args) +{ +    uint32 lowguid = 0; + +    Creature* pCreature = getSelectedCreature(); + +    if(!pCreature) +    { +        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r +        char* cId = extractKeyFromLink((char*)args,"Hcreature"); +        if(!cId) +            return false; + +        lowguid = atoi(cId); + +        /* FIXME: impossibel without entry +        if(lowguid) +            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); +        */ + +        // Attempting creature load from DB data +        if(!pCreature) +        { +            CreatureData const* data = objmgr.GetCreatureData(lowguid); +            if(!data) +            { +                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); +                SetSentErrorMessage(true); +                return false; +            } + +            uint32 map_id = data->mapid; + +            if(m_session->GetPlayer()->GetMapId()!=map_id) +            { +                PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); +                SetSentErrorMessage(true); +                return false; +            } +        } +        else +        { +            lowguid = pCreature->GetDBTableGUIDLow(); +        } +    } +    else +    { +        lowguid = pCreature->GetDBTableGUIDLow(); +    } + +    float x = m_session->GetPlayer()->GetPositionX(); +    float y = m_session->GetPlayer()->GetPositionY(); +    float z = m_session->GetPlayer()->GetPositionZ(); +    float o = m_session->GetPlayer()->GetOrientation(); + +    if (pCreature) +    { +        if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow())) +        { +            const_cast<CreatureData*>(data)->posX = x; +            const_cast<CreatureData*>(data)->posY = y; +            const_cast<CreatureData*>(data)->posZ = z; +            const_cast<CreatureData*>(data)->orientation = o; +        } +        pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o); +        pCreature->GetMotionMaster()->Initialize(); +        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn +        { +            pCreature->setDeathState(JUST_DIED); +            pCreature->Respawn(); +        } +    } + +    WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); +    PSendSysMessage(LANG_COMMAND_CREATUREMOVED); +    return true; +} + +/**HandleNpcSetMoveTypeCommand   * Set the movement type for an NPC.<br/>   * <br/>   * Valid movement types are: @@ -1545,11 +1606,15 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)      else          return false; +    // update movement type +    //if(doNotDelete == false) +    //    WaypointMgr.DeletePath(lowguid); +      if(pCreature)      {          // update movement type          if(doNotDelete == false) -            pCreature->LoadPath(0); +            pCreature->SetWaypointPathId(0);          pCreature->SetDefaultMovementType(move_type);          pCreature->GetMotionMaster()->Initialize(); @@ -1570,23 +1635,49 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)      }      return true; -}                                                           // HandleNpcSetMoveTypeCommand +} -//change level of creature or pet -bool ChatHandler::HandleChangeLevelCommand(const char* args) +//set model of creature +bool ChatHandler::HandleNpcSetModelCommand(const char* args)  {      if (!*args)          return false; -    uint8 lvl = (uint8) atoi((char*)args); -    if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3) +    uint32 displayId = (uint32) atoi((char*)args); + +    Creature *pCreature = getSelectedCreature(); + +    if(!pCreature || pCreature->isPet())      { -        SendSysMessage(LANG_BAD_VALUE); +        SendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true); +        return false; +    } + +    pCreature->SetDisplayId(displayId); +    pCreature->SetNativeDisplayId(displayId); + +    pCreature->SaveToDB(); + +    return true; +} +//set faction of creature +bool ChatHandler::HandleNpcFactionIdCommand(const char* args) +{ +    if (!*args) +        return false; + +    uint32 factionId = (uint32) atoi((char*)args); + +    if (!sFactionTemplateStore.LookupEntry(factionId)) +    { +        PSendSysMessage(LANG_WRONG_FACTION, factionId);          SetSentErrorMessage(true);          return false;      }      Creature* pCreature = getSelectedCreature(); +      if(!pCreature)      {          SendSysMessage(LANG_SELECT_CREATURE); @@ -1594,126 +1685,441 @@ bool ChatHandler::HandleChangeLevelCommand(const char* args)          return false;      } -    if(pCreature->isPet()) +    pCreature->setFaction(factionId); + +    // faction is set in creature_template - not inside creature + +    // update in memory +    if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())      { -        ((Pet*)pCreature)->GivePetLevel(lvl); +        const_cast<CreatureInfo*>(cinfo)->faction_A = factionId; +        const_cast<CreatureInfo*>(cinfo)->faction_H = factionId; +    } + +    // and DB +    WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry()); + +    return true; +} +//set spawn dist of creature +bool ChatHandler::HandleNpcSpawnDistCommand(const char* args) +{ +    if(!*args) +        return false; + +    float option = atof((char*)args); +    if (option < 0.0f) +    { +        SendSysMessage(LANG_BAD_VALUE); +        return false;      } + +    MovementGeneratorType mtype = IDLE_MOTION_TYPE; +    if (option >0.0f) +        mtype = RANDOM_MOTION_TYPE; + +    Creature *pCreature = getSelectedCreature(); +    uint32 u_guidlow = 0; + +    if (pCreature) +        u_guidlow = pCreature->GetDBTableGUIDLow();      else +        return false; + +    pCreature->SetRespawnRadius((float)option); +    pCreature->SetDefaultMovementType(mtype); +    pCreature->GetMotionMaster()->Initialize(); +    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn      { -        pCreature->SetMaxHealth( 100 + 30*lvl); -        pCreature->SetHealth( 100 + 30*lvl); -        pCreature->SetLevel( lvl); -        pCreature->SaveToDB(); +        pCreature->setDeathState(JUST_DIED); +        pCreature->Respawn();      } +    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); +    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);      return true;  } - -//set npcflag of creature -bool ChatHandler::HandleNpcFlagCommand(const char* args) +//spawn time handling +bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)  { -    if (!*args) +    if(!*args)          return false; -    uint32 npcFlags = (uint32) atoi((char*)args); +    char* stime = strtok((char*)args, " "); -    Creature* pCreature = getSelectedCreature(); +    if (!stime) +        return false; -    if(!pCreature) +    int i_stime = atoi((char*)stime); + +    if (i_stime < 0)      { -        SendSysMessage(LANG_SELECT_CREATURE); +        SendSysMessage(LANG_BAD_VALUE);          SetSentErrorMessage(true);          return false;      } -    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); +    Creature *pCreature = getSelectedCreature(); +    uint32 u_guidlow = 0; -    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); +    if (pCreature) +        u_guidlow = pCreature->GetDBTableGUIDLow(); +    else +        return false; -    SendSysMessage(LANG_VALUE_SAVED_REJOIN); +    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); +    pCreature->SetRespawnDelay((uint32)i_stime); +    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);      return true;  } - -//set model of creature -bool ChatHandler::HandleNpcSetModelCommand(const char* args) +//npc follow handling +bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)  { -    if (!*args) +    Player *player = m_session->GetPlayer(); +    Creature *creature = getSelectedCreature(); + +    if(!creature) +    { +        PSendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true);          return false; +    } -    uint32 displayId = (uint32) atoi((char*)args); +    // Follow player - Using pet's default dist and angle +    creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); -    Creature *pCreature = getSelectedCreature(); +    PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); +    return true; +} +//npc unfollow handling +bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) +{ +    Player *player = m_session->GetPlayer(); +    Creature *creature = getSelectedCreature(); -    if(!pCreature || pCreature->isPet()) +    if(!creature)      { -        SendSysMessage(LANG_SELECT_CREATURE); +        PSendSysMessage(LANG_SELECT_CREATURE);          SetSentErrorMessage(true);          return false;      } -    pCreature->SetDisplayId(displayId); -    pCreature->SetNativeDisplayId(displayId); +    if (/*creature->GetMotionMaster()->empty() ||*/ +        creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE) +    { +        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); +        SetSentErrorMessage(true); +        return false; +    } -    pCreature->SaveToDB(); +    TargetedMovementGenerator<Creature> const* mgen +        = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top())); +    if(mgen->GetTarget()!=player) +    { +        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); +        SetSentErrorMessage(true); +        return false; +    } + +    // reset movement +    creature->GetMotionMaster()->MovementExpired(true); + +    PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());      return true;  } +//npc tame handling +bool ChatHandler::HandleNpcTameCommand(const char* /*args*/) +{ +    Creature *creatureTarget = getSelectedCreature (); +    if (!creatureTarget || creatureTarget->isPet ()) +    { +        PSendSysMessage (LANG_SELECT_CREATURE); +        SetSentErrorMessage (true); +        return false; +    } -//morph creature or player -bool ChatHandler::HandleMorphCommand(const char* args) +    Player *player = m_session->GetPlayer (); + +    if(player->GetPetGUID ()) +    { +        SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); +        SetSentErrorMessage (true); +        return false; +    } + +    CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); + +    if (!cInfo->isTameable ()) +    { +        PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); +        SetSentErrorMessage (true); +        return false; +    } + +    // Everything looks OK, create new pet +    Pet* pet = player->CreateTamedPetFrom (creatureTarget); +    if (!pet) +    { +        PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); +        SetSentErrorMessage (true); +        return false; +    } + +    // place pet before player +    float x,y,z; +    player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); +    pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); + +    // set pet to defensive mode by default (some classes can't control controlled pets in fact). +    pet->SetReactState(REACT_DEFENSIVE); + +    // calculate proper level +    uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); + +    // prepare visual effect for levelup +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); + +    // add to world +    pet->GetMap()->Add((Creature*)pet); + +    // visual effect for levelup +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); + +    // caster have pet now +    player->SetMinion(pet, true); + +    pet->SavePetToDB(PET_SAVE_AS_CURRENT); +    player->PetSpellInitialize(); + +    return true; +} +//npc phasemask handling +//change phasemask of creature or pet +bool ChatHandler::HandleNpcSetPhaseCommand(const char* args)  {      if (!*args)          return false; -    uint16 display_id = (uint16)atoi((char*)args); +    uint32 phasemask = (uint32) atoi((char*)args); +    if ( phasemask == 0 ) +    { +        SendSysMessage(LANG_BAD_VALUE); +        SetSentErrorMessage(true); +        return false; +    } -    Unit *target = getSelectedUnit(); -    if(!target) -        target = m_session->GetPlayer(); +    Creature* pCreature = getSelectedCreature(); +    if(!pCreature) +    { +        SendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true); +        return false; +    } -    target->SetDisplayId(display_id); +    pCreature->SetPhaseMask(phasemask,true); + +    if(!pCreature->isPet()) +        pCreature->SaveToDB();      return true;  } - -//set faction of creature -bool ChatHandler::HandleNpcFactionIdCommand(const char* args) +//npc deathstate handling +bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args)  {      if (!*args)          return false; -    uint32 factionId = (uint32) atoi((char*)args); +    Creature* pCreature = getSelectedCreature(); +    if(!pCreature || pCreature->isPet()) +    { +        SendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true); +        return false; +    } -    if (!sFactionTemplateStore.LookupEntry(factionId)) +    if (strncmp(args, "on", 3) == 0) +        pCreature->SetDeadByDefault(true); +    else if (strncmp(args, "off", 4) == 0) +        pCreature->SetDeadByDefault(false); +    else      { -        PSendSysMessage(LANG_WRONG_FACTION, factionId); +        SendSysMessage(LANG_USE_BOL);          SetSentErrorMessage(true);          return false;      } -    Creature* pCreature = getSelectedCreature(); +    pCreature->SaveToDB(); +    pCreature->Respawn(); + +    return true; +} + +//TODO: NpcCommands that need to be fixed : + +bool ChatHandler::HandleNpcNameCommand(const char* /*args*/) +{ +    /* Temp. disabled +    if(!*args) +        return false; + +    if(strlen((char*)args)>75) +    { +        PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75); +        return true; +    } + +    for (uint8 i = 0; i < strlen(args); ++i) +    { +        if(!isalpha(args[i]) && args[i]!=' ') +        { +            SendSysMessage(LANG_CHARS_ONLY); +            return false; +        } +    } + +    uint64 guid; +    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); -        SetSentErrorMessage(true); -        return false; +        return true;      } -    pCreature->setFaction(factionId); +    pCreature->SetName(args); +    uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName()); +    pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); -    // faction is set in creature_template - not inside creature +    pCreature->SaveToDB(); +    */ -    // update in memory -    if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo()) +    return true; +} + +bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/) +{ +    /* Temp. disabled + +    if(!*args) +        args = ""; + +    if(strlen((char*)args)>75)      { -        const_cast<CreatureInfo*>(cinfo)->faction_A = factionId; -        const_cast<CreatureInfo*>(cinfo)->faction_H = factionId; + +        PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75); +        return true;      } -    // and DB -    WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry()); +    for (uint8 i = 0; i < strlen(args); i++) +    { +        if(!isalpha(args[i]) && args[i]!=' ') +        { +            SendSysMessage(LANG_CHARS_ONLY); +            return false; +        } +    } +    uint64 guid; +    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; +    } + +    uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID)); +    pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); + +    pCreature->SaveToDB(); +    */ +    return true; +} + +//move item to other slot +bool ChatHandler::HandleItemMoveCommand(const char* args) +{ +    if(!*args) +        return false; +    uint8 srcslot, dstslot; + +    char* pParam1 = strtok((char*)args, " "); +    if (!pParam1) +        return false; + +    char* pParam2 = strtok(NULL, " "); +    if (!pParam2) +        return false; + +    srcslot = (uint8)atoi(pParam1); +    dstslot = (uint8)atoi(pParam2); + +    if(srcslot==dstslot) +        return true; + +    if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot)) +        return false; + +    if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot)) +        return false; + +    uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot); +    uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot); + +    m_session->GetPlayer()->SwapItem( src, dst ); + +    return true; +} + +//demorph player or unit +bool ChatHandler::HandleDeMorphCommand(const char* /*args*/) +{ +    Unit *target = getSelectedUnit(); +    if(!target) +        target = m_session->GetPlayer(); + + +    // check online security +    else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) +        return false; + +    target->DeMorph(); + +    return true; +} + +//morph creature or player +bool ChatHandler::HandleModifyMorphCommand(const char* args) +{ +    if (!*args) +        return false; + +    uint16 display_id = (uint16)atoi((char*)args); + +    Unit *target = getSelectedUnit(); +    if(!target) +        target = m_session->GetPlayer(); + +    // check online security +    else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) +        return false; + +    target->SetDisplayId(display_id);      return true;  } @@ -1731,7 +2137,7 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)          kicker = m_session->GetPlayer()->GetName();      if(!kickName) -     { +    {          Player* player = getSelectedPlayer();          if(!player)          { @@ -1747,14 +2153,16 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)              return false;          } +        // check online security +        if (HasLowerSecurity(player, 0)) +            return false; +          if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)          { -              sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());          }          else          { -              PSendSysMessage(LANG_COMMAND_KICKMESSAGE, player->GetName(), kicker.c_str(), reason.c_str());          } @@ -1762,8 +2170,8 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)      }      else      { -        std::string name = kickName; -        if(!normalizePlayerName(name)) +        std::string name = extractPlayerNameFromLink((char*)kickName); +        if(name.empty())          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -1785,34 +2193,56 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)              return false;          } -        if(m_session && player->GetSession()->GetSecurity() > m_session->GetSecurity()) +        if(HasLowerSecurity(player, 0))          {              SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); //maybe replacement string for this later on              SetSentErrorMessage(true);              return false;          } -        if(sWorld.KickPlayer(name.c_str())) +        std::string nameLink = playerLink(name); +     +        if(sWorld.KickPlayer(name))          {              if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)              { - -                sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str()); +                sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, nameLink.c_str(), kicker.c_str(), reason.c_str());              }              else              { -                PSendSysMessage(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str()); +                PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());              }          }          else          { -            PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER, name.c_str()); +            PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());              return false;          }      }      return true;  } +//set temporary phase mask for player +bool ChatHandler::HandleModifyPhaseCommand(const char* args) +{ +    if (!*args) +        return false; + +    uint32 phasemask = (uint32)atoi((char*)args); + +    Unit *target = getSelectedUnit(); +    if(!target) +        target = m_session->GetPlayer(); + +    // check online security +    else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) +        return false; + +    target->SetPhaseMask(phasemask,true); + +    return true; +} +  //show info of player  bool ChatHandler::HandlePInfoCommand(const char* args)  { @@ -1826,12 +2256,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      if (px)      { -        name = px; - +        name = extractPlayerNameFromLink(px);          if(name.empty()) -            return false; - -        if(!normalizePlayerName(name))          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -1872,6 +2298,10 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      // get additional information from Player object      if(target)      { +        // check online security +        if (HasLowerSecurity(target, 0)) +            return false; +          targetGUID = target->GetGUID();          name = target->GetName();                           // re-read for case getSelectedPlayer() target          accId = target->GetSession()->GetAccountId(); @@ -1883,6 +2313,11 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      // get additional information from DB      else      { +        // check offline security +        if (HasLowerSecurity(NULL, targetGUID)) +            return false; + +        //                                                     0          QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));          if (!result)          { @@ -1933,7 +2368,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)          delete result;      } -    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency); +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);      std::string timeStr = secsToTimeString(total_player_time,true,true);      uint32 gold = money /GOLD; @@ -1951,18 +2388,16 @@ bool ChatHandler::HandlePInfoCommand(const char* args)              return false;          } -        char* FactionName; -        for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr) +        FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); +        for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)          {              FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); -            if (factionEntry) -                FactionName = factionEntry->name[m_session->GetSessionDbcLocale()]; -            else -                FactionName = "#Not found#"; -            ReputationRank rank = target->GetReputationRank(factionEntry); -            std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]); +            char const* factionName = factionEntry ? factionEntry->name[m_session->GetSessionDbcLocale()] : "#Not found#"; +            ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); +            std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);              std::ostringstream ss; -            ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")"; +            ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << "]|h|r " << rankName << "|h|r (" +               << target->GetReputationMgr().GetReputation(factionEntry) << ")";              if(itr->second.Flags & FACTION_FLAG_VISIBLE)                  ss << GetTrinityString(LANG_FACTION_VISIBLE); @@ -1983,81 +2418,215 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      return true;  } -//set spawn dist of creature -bool ChatHandler::HandleNpcSpawnDistCommand(const char* args) +/*//show tickets +void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)  { -    if(!*args) -        return false; +    std::string name; +    if(!objmgr.GetPlayerNameByGUID(guid,name)) +        name = GetTrinityString(LANG_UNKNOWN); -    float option = atof((char*)args); -    if (option < 0.0f) +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_COMMAND_TICKETVIEW, nameLink.c_str(),time,text); +} + +//ticket commands +bool ChatHandler::HandleTicketCommand(const char* args) +{ +    char* px = strtok((char*)args, " "); + +    // ticket<end> +    if (!px)      { -        SendSysMessage(LANG_BAD_VALUE); -        return false; +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } + +        size_t count = ticketmgr.GetTicketCount(); + +        bool accept = m_session->GetPlayer()->isAcceptTickets(); + +        PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ?  GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF)); +        return true;      } -    MovementGeneratorType mtype = IDLE_MOTION_TYPE; -    if (option >0.0f) -        mtype = RANDOM_MOTION_TYPE; +    // ticket on +    if(strncmp(px,"on",3) == 0) +    { +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } -    Creature *pCreature = getSelectedCreature(); -    uint32 u_guidlow = 0; +        m_session->GetPlayer()->SetAcceptTicket(true); +        SendSysMessage(LANG_COMMAND_TICKETON); +        return true; +    } -    if (pCreature) -        u_guidlow = pCreature->GetDBTableGUIDLow(); -    else -        return false; +    // ticket off +    if(strncmp(px,"off",4) == 0) +    { +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } -    pCreature->SetRespawnRadius((float)option); -    pCreature->SetDefaultMovementType(mtype); -    pCreature->GetMotionMaster()->Initialize(); -    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn +        m_session->GetPlayer()->SetAcceptTicket(false); +        SendSysMessage(LANG_COMMAND_TICKETOFF); +        return true; +    } + +    // ticket #num +    int num = atoi(px); +    if(num > 0)      { -        pCreature->setDeathState(JUST_DIED); -        pCreature->Respawn(); +        QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1); + +        if(!result) +        { +            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); +            SetSentErrorMessage(true); +            return false; +        } + +        Field* fields = result->Fetch(); + +        uint32 guid = fields[0].GetUInt32(); +        char const* text = fields[1].GetString(); +        char const* time = fields[2].GetString(); + +        ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time); +        delete result; +        return true;      } -    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); -    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option); +    std::string name = extractPlayerNameFromLink(px); +    if(name.empty()) +    { +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true); +        return false; +    } + +    uint64 guid = objmgr.GetPlayerGUIDByName(name); + +    if(!guid) +        return false; + +    // ticket $char_name +    GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid)); +    if(!ticket) +        return false; + +    std::string time = TimeToTimestampStr(ticket->GetLastUpdate()); + +    ShowTicket(guid, ticket->GetText(), time.c_str()); +      return true;  } -bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args) +//dell all tickets +bool ChatHandler::HandleDelTicketCommand(const char *args)  { -    if(!*args) +    char* px = strtok((char*)args, " "); +    if (!px)          return false; -    char* stime = strtok((char*)args, " "); +    // delticket all +    if(strncmp(px,"all",4) == 0) +    { +        ticketmgr.DeleteAll(); +        SendSysMessage(LANG_COMMAND_ALLTICKETDELETED); +        return true; +    } -    if (!stime) -        return false; +    int num = (uint32)atoi(px); -    int i_stime = atoi((char*)stime); +    // delticket #num +    if(num > 0) +    { +        QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1); +        if(!result) +        { +            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); +            SetSentErrorMessage(true); +            return false; +        } +        Field* fields = result->Fetch(); +        uint32 guid = fields[0].GetUInt32(); +        delete result; -    if (i_stime < 0) +        ticketmgr.Delete(guid); + +        //notify player +        if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER))) +        { +            pl->GetSession()->SendGMTicketGetTicket(0x0A, 0); +            PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, GetNameLink(pl).c_str()); +        } +        else +            PSendSysMessage(LANG_COMMAND_TICKETDEL); + +        return true; +    } + +    std::string name = extractPlayerNameFromLink(px); +    if(name.empty())      { -        SendSysMessage(LANG_BAD_VALUE); +        SendSysMessage(LANG_PLAYER_NOT_FOUND);          SetSentErrorMessage(true);          return false;      } -    Creature *pCreature = getSelectedCreature(); -    uint32 u_guidlow = 0; +    uint64 guid = objmgr.GetPlayerGUIDByName(name); -    if (pCreature) -        u_guidlow = pCreature->GetDBTableGUIDLow(); -    else +    if(!guid)          return false; -    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); -    pCreature->SetRespawnDelay((uint32)i_stime); -    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime); +    // delticket $char_name +    ticketmgr.Delete(GUID_LOPART(guid)); + +    // notify players about ticket deleting +    if(Player* sender = objmgr.GetPlayer(guid)) +        sender->GetSession()->SendGMTicketGetTicket(0x0A,0); +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());      return true; -} +}*/ +  /////WAYPOINT COMMANDS +/** + * Add a waypoint to a creature. + * + * The user can either select an npc or provide its GUID. + * + * The user can even select a visual waypoint - then the new waypoint + * is placed *after* the selected one - this makes insertion of new + * waypoints possible. + * + * eg: + * .wp add 12345 + * -> adds a waypoint to the npc with the GUID 12345 + * + * .wp add + * -> adds a waypoint to the currently selected creature + * + * + * @param args if the user did not provide a GUID, it is NULL + * + * @return true - command did succeed, false - something went wrong + */  bool ChatHandler::HandleWpAddCommand(const char* args)  {      sLog.outDebug("DEBUG: HandleWpAddCommand"); @@ -2075,7 +2644,7 @@ bool ChatHandler::HandleWpAddCommand(const char* args)      if (!path_number)          {          if(target) -            pathid = target->GetWaypointPath(); +            pathid = target->GetWaypointPathId();                  else                  {                      QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(id) FROM waypoint_data"); @@ -2130,7 +2699,6 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)      if(*args)          path_number = strtok((char*)args, " "); -      uint32 pathid = 0;      uint32 guidlow = 0;      Creature* target = getSelectedCreature(); @@ -2161,6 +2729,7 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)          return true;      } +    /*      guidlow = target->GetDBTableGUIDLow();      QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE guid = '%u'",guidlow); @@ -2171,31 +2740,31 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)      }      else          WorldDatabase.PExecute("INSERT INTO creature_addon(guid,path_id) VALUES ('%u','%u')", guidlow, pathid); +    */      WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow); -    target->LoadPath(pathid); +    target->SetWaypointPathId(pathid);      target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);      target->GetMotionMaster()->Initialize(); -    target->Say("Path loaded.",0,0); +    target->MonsterSay("Path loaded.",0,0);      return true;  } -  bool ChatHandler::HandleReloadAllPaths(const char* args)  { -if(!*args) -    return false; +    if(!*args) +        return false; -uint32 id = atoi(args); +    uint32 id = atoi(args); -if(!id) -    return false; +    if(!id) +        return false;      PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);      WaypointMgr.UpdatePath(id); -        return true; +    return true;  }  bool ChatHandler::HandleWpUnLoadPathCommand(const char *args) @@ -2209,24 +2778,39 @@ bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)          return true;      } -    if(target->GetCreatureAddon()) +    if(target->GetWaypointPathId())      { -        if(target->GetCreatureAddon()->path_id != 0) +        uint32 pathId = target->GetDBTableGUIDLow() * 10; +        if(target->GetWaypointPathId() == pathId)          { -            WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = %u", target->GetGUIDLow()); -            target->UpdateWaypointID(0); -            WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow); -            target->LoadPath(0); -            target->SetDefaultMovementType(IDLE_MOTION_TYPE); -            target->GetMotionMaster()->MoveTargetedHome(); -            target->GetMotionMaster()->Initialize(); -            target->Say("Path unloaded.",0,0); -            return true; +            for(uint32 i = 1; i < 11; ++i) +            { +                if(i == 10) +                { +                    PSendSysMessage("%s%s|r", "|cffff33ff", "Target cannot have more than 9 script paths. Unloading failed."); +                    break; +                } + +                if(WaypointMgr.GetPath(++pathId)) +                    continue; + +                WorldDatabase.PExecute("UPDATE waypoint_data SET id = %u WHERE id = %u", pathId, target->GetDBTableGUIDLow() * 10); +                WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow); +                target->SetWaypointPathId(0); +                target->UpdateWaypointID(0); +                target->SetDefaultMovementType(IDLE_MOTION_TYPE); +                target->GetMotionMaster()->Initialize(); +                target->GetMotionMaster()->MoveTargetedHome(); +                PSendSysMessage("Path unloaded."); +                break; +            }          } -        PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path."); -        return true; +        else +            PSendSysMessage("%s%s|r", "|cffff33ff", "Target has path but that path is not its default path. Unloading failed.");      } -    PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path."); +    else +        PSendSysMessage("%s%s|r", "|cffff33ff", "Target has no loaded path."); +      return true;  } @@ -2507,7 +3091,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)      // Did the user select a visual spawnpoint?      if(wpGuid) -        wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); +        wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));      // attempt check creature existence by DB data      else      { @@ -2577,7 +3161,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)          if( wpGuid != 0 )          { -            wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); +            wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));              wpCreature->CombatStop();              wpCreature->DeleteFromDB();              wpCreature->AddObjectToRemoveList(); @@ -2606,13 +3190,13 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)              // Respawn the owner of the waypoints              if( wpGuid != 0 )              { -                wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); +                wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));                  wpCreature->CombatStop();                  wpCreature->DeleteFromDB();                  wpCreature->AddObjectToRemoveList();                  // re-create                  Creature* wpCreature2 = new Creature; -                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0)) +                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))                  {                      PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);                      delete wpCreature2; @@ -2622,12 +3206,12 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)                  if(!wpCreature2->IsPositionValid())                  { -                    sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY()); +                    sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());                      delete wpCreature2;                      return false;                  } -                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());                  // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();                  wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);                  map->Add(wpCreature2); @@ -2661,7 +3245,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)      }      PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); -      return true;  } @@ -2701,7 +3284,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              return false;          } -        pathid = target->GetWaypointPath(); +        pathid = target->GetWaypointPathId();      }      else @@ -2718,11 +3301,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          pathid = atoi((char*)guid_str);      } -      sLog.outDebug("DEBUG: HandleWpShowCommand: danach"); - -      std::string show = show_str;      uint32 Maxpoint; @@ -2801,7 +3381,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              {                  Field *fields = result2->Fetch();                  uint32 wpguid = fields[0].GetUInt32(); -                Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT)); +                Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));                  if(!pCreature)                  { @@ -2843,7 +3423,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              float o = chr->GetOrientation();              Creature* wpCreature = new Creature; -            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) +            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))              {                  PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);                  delete wpCreature; @@ -2855,7 +3435,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              if(!wpCreature->IsPositionValid())              { -                sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY()); +                sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());                  delete wpCreature;                  delete result;                  return false; @@ -2865,7 +3445,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              // set "wpguid" column to the visual waypoint              WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point); -            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); +            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();              wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);              map->Add(wpCreature); @@ -2906,7 +3487,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          Map *map = chr->GetMap();          Creature* pCreature = new Creature; -        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0)) +        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))          {              PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);              delete pCreature; @@ -2918,13 +3499,13 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          if(!pCreature->IsPositionValid())          { -            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); +            sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());              delete pCreature;              delete result;              return false;          } -        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());          pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);          map->Add(pCreature); @@ -2971,7 +3552,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          Map *map = chr->GetMap();          Creature* pCreature = new Creature; -        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) +        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))          {              PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);              delete pCreature; @@ -2983,13 +3564,13 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          if(!pCreature->IsPositionValid())          { -            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); +            sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());              delete pCreature;              delete result;              return false;          } -        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());          pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);          map->Add(pCreature); @@ -3018,7 +3599,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          {              Field *fields = result->Fetch();              uint32 guid = fields[0].GetUInt32(); -            Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT)); +            Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));              if(!pCreature)              { @@ -3061,7 +3642,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)  //////////// WAYPOINT COMMANDS //  //rename characters -bool ChatHandler::HandleRenameCommand(const char* args) +bool ChatHandler::HandleCharacterRenameCommand(const char* args)  {      Player* target = NULL;      uint64 targetGUID = 0; @@ -3071,9 +3652,8 @@ bool ChatHandler::HandleRenameCommand(const char* args)      if(px)      { -        oldname = px; - -        if(!normalizePlayerName(oldname)) +        oldname = extractPlayerNameFromLink(px); +        if(oldname.empty())          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -3100,104 +3680,85 @@ bool ChatHandler::HandleRenameCommand(const char* args)      if(target)      { -        PSendSysMessage(LANG_RENAME_PLAYER, target->GetName()); +        // check online security +        if (HasLowerSecurity(target, 0)) +            return false; + +        PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());          target->SetAtLoginFlag(AT_LOGIN_RENAME);          CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());      }      else      { -        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID)); +        // check offline security +        if (HasLowerSecurity(NULL, targetGUID)) +            return false; + +        std::string oldNameLink = playerLink(oldname); + +        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));          CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));      }      return true;  } -//spawn go -bool ChatHandler::HandleGameObjectCommand(const char* args) +// customize characters +bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)  { -    if (!*args) -        return false; +    Player* target = NULL; +    uint64 targetGUID = 0; +    std::string oldname; -    char* pParam1 = strtok((char*)args, " "); -    if (!pParam1) -        return false; +    char* px = strtok((char*)args, " "); -    uint32 id = atoi((char*)pParam1); -    if(!id) -        return false; +    if(px) +    { +        oldname = extractPlayerNameFromLink(px); +        if(oldname.empty()) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } -    char* spawntimeSecs = strtok(NULL, " "); +        target = objmgr.GetPlayer(oldname.c_str()); -    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id); +        if (!target) +            targetGUID = objmgr.GetPlayerGUIDByName(oldname); +    } -    if (!goI) +    if(!target && !targetGUID)      { -        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); -        SetSentErrorMessage(true); -        return false; +        target = getSelectedPlayer();      } -    Player *chr = m_session->GetPlayer(); -    float x = float(chr->GetPositionX()); -    float y = float(chr->GetPositionY()); -    float z = float(chr->GetPositionZ()); -    float o = float(chr->GetOrientation()); -    Map *map = chr->GetMap(); - -    float rot2 = sin(o/2); -    float rot3 = cos(o/2); - -    GameObject* pGameObj = new GameObject; -    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); - -    if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1)) +    if(!target && !targetGUID)      { -        delete pGameObj; +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true);          return false;      } -    if( spawntimeSecs ) +    if(target)      { -        uint32 value = atoi((char*)spawntimeSecs); -        pGameObj->SetRespawnTime(value); -        //sLog.outDebug("*** spawntimeSecs: %d", value); +        PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); +        target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());      } - -    // fill the gameobject data and save to the db -    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); - -    // this will generate a new guid if the object is in an instance -    if(!pGameObj->LoadFromDB(db_lowGUID, map)) +    else      { -        delete pGameObj; -        return false; -    } - -    sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o); - -    map->Add(pGameObj); - -    // TODO: is it really necessary to add both the real and DB table guid here ? -    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID)); +        std::string oldNameLink = playerLink(oldname); -    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z); -    return true; -} - -//show animation -bool ChatHandler::HandleAnimCommand(const char* args) -{ -    if (!*args) -        return false; +        PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID)); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); +    } -    uint32 anim_id = atoi((char*)args); -    m_session->GetPlayer()->HandleEmoteCommand(anim_id);      return true;  }  //change standstate -bool ChatHandler::HandleStandStateCommand(const char* args) +bool ChatHandler::HandleModifyStandStateCommand(const char* args)  {      if (!*args)          return false; @@ -3208,7 +3769,7 @@ bool ChatHandler::HandleStandStateCommand(const char* args)      return true;  } -bool ChatHandler::HandleAddHonorCommand(const char* args) +bool ChatHandler::HandleHonorAddCommand(const char* args)  {      if (!*args)          return false; @@ -3221,6 +3782,10 @@ bool ChatHandler::HandleAddHonorCommand(const char* args)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      uint32 amount = (uint32)atoi(args);      target->RewardHonor(NULL, 1, amount);      return true; @@ -3236,11 +3801,15 @@ bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)          return false;      } +    // check online security +    if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) +        return false; +      m_session->GetPlayer()->RewardHonor(target, 1);      return true;  } -bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/) +bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)  {      Player *target = getSelectedPlayer();      if(!target) @@ -3250,6 +3819,10 @@ bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      target->UpdateHonorFields();      return true;  } @@ -3270,8 +3843,8 @@ bool ChatHandler::HandleLookupEventCommand(const char* args)      uint32 counter = 0; -    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); -    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); +    GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap(); +    GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();      for(uint32 id = 0; id < events.size(); ++id )      { @@ -3304,12 +3877,12 @@ bool ChatHandler::HandleEventActiveListCommand(const char* args)  {      uint32 counter = 0; -    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); -    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); +    GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap(); +    GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();      char const* active = GetTrinityString(LANG_ACTIVE); -    for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr ) +    for(GameEventMgr::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )      {          uint32 event_id = *itr;          GameEventData const& eventData = events[event_id]; @@ -3340,7 +3913,7 @@ bool ChatHandler::HandleEventInfoCommand(const char* args)      uint32 event_id = atoi(cId); -    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); +    GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();      if(event_id >=events.size())      { @@ -3357,7 +3930,7 @@ bool ChatHandler::HandleEventInfoCommand(const char* args)          return false;      } -    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); +    GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();      bool active = activeEvents.find(event_id) != activeEvents.end();      char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : ""; @@ -3389,7 +3962,7 @@ bool ChatHandler::HandleEventStartCommand(const char* args)      int32 event_id = atoi(cId); -    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); +    GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();      if(event_id < 1 || event_id >=events.size())      { @@ -3406,7 +3979,7 @@ bool ChatHandler::HandleEventStartCommand(const char* args)          return false;      } -    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); +    GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();      if(activeEvents.find(event_id) != activeEvents.end())      {          PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id); @@ -3430,7 +4003,7 @@ bool ChatHandler::HandleEventStopCommand(const char* args)      int32 event_id = atoi(cId); -    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); +    GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();      if(event_id < 1 || event_id >=events.size())      { @@ -3447,7 +4020,7 @@ bool ChatHandler::HandleEventStopCommand(const char* args)          return false;      } -    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList(); +    GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();      if(activeEvents.find(event_id) == activeEvents.end())      { @@ -3466,9 +4039,8 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)      if(*args)      { -        std::string playername = args; - -        if(!normalizePlayerName(playername)) +        std::string playername = extractPlayerNameFromLink((char*)args); +        if(playername.empty())          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -3492,6 +4064,10 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)              player = m_session->GetPlayer();      } +    // check online security +    if (HasLowerSecurity(player, 0)) +        return false; +      player->CombatStop();      player->getHostilRefManager().deleteReferences();      return true; @@ -3530,7 +4106,7 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)                  if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))                      continue; -                m_session->GetPlayer()->learnSpell(skillLine->spellId); +                m_session->GetPlayer()->learnSpell(skillLine->spellId,false);              }          }      } @@ -3603,7 +4179,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)                      continue;                  if( !target->HasSpell(spellInfo->Id) ) -                    m_session->GetPlayer()->learnSpell(skillLine->spellId); +                    m_session->GetPlayer()->learnSpell(skillLine->spellId,false);              }              uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id); @@ -3710,6 +4286,13 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)      delete result; +    if(i==0)                                                // empty accounts only +    { +        PSendSysMessage(LANG_NO_PLAYERS_FOUND); +        SetSentErrorMessage(true); +        return false; +    } +      return true;  } @@ -3731,68 +4314,50 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      // Repair items      target->DurabilityRepairAll(false, 0, false); -    PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName()); +    PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());      if(needReportToTarget(target)) -        ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName()); +        ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());      return true;  } -bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/) +bool ChatHandler::HandleWaterwalkCommand(const char* args)  { -    Player *player = m_session->GetPlayer(); -    Creature *creature = getSelectedCreature(); - -    if(!creature) -    { -        PSendSysMessage(LANG_SELECT_CREATURE); -        SetSentErrorMessage(true); +    if(!*args)          return false; -    } - -    // Follow player - Using pet's default dist and angle -    creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); -    PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); -    return true; -} +    Player *player = getSelectedPlayer(); -bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) -{ -    Player *player = m_session->GetPlayer(); -    Creature *creature = getSelectedCreature(); - -    if(!creature) +    if(!player)      { -        PSendSysMessage(LANG_SELECT_CREATURE); +        PSendSysMessage(LANG_NO_CHAR_SELECTED);          SetSentErrorMessage(true);          return false;      } -    if (/*creature->GetMotionMaster()->empty() ||*/ -        creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE) -    { -        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); -        SetSentErrorMessage(true); +    // check online security +    if (HasLowerSecurity(player, 0))          return false; -    } -    TargetedMovementGenerator<Creature> const* mgen -        = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top())); - -    if(mgen->GetTarget()!=player) +    if (strncmp(args, "on", 3) == 0) +        player->SetMovement(MOVE_WATER_WALK);               // ON +    else if (strncmp(args, "off", 4) == 0) +        player->SetMovement(MOVE_LAND_WALK);                // OFF +    else      { -        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); -        SetSentErrorMessage(true); +        SendSysMessage(LANG_USE_BOL);          return false;      } -    // reset movement -    creature->GetMotionMaster()->MovementExpired(true); - -    PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName()); +    PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str()); +    if(needReportToTarget(player)) +        ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());      return true;  } @@ -3825,7 +4390,7 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)      }      // Everything looks OK, create new pet -    Pet* pet = new Pet(HUNTER_PET); +    Pet* pet = new Pet(player, HUNTER_PET);      if(!pet->CreateBaseAtCreature(creatureTarget))      { @@ -3838,7 +4403,6 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)      creatureTarget->RemoveCorpse();      creatureTarget->SetHealth(0); // just for nice GM-mode view -    pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, player->GetGUID());      pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());      pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); @@ -3854,16 +4418,15 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)       pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);       // this enables pet details window (Shift+P) -     pet->AIM_Initialize();       pet->InitPetCreateSpells();       pet->SetHealth(pet->GetMaxHealth()); -     MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); +     pet->GetMap()->Add((Creature*)pet);       // visual effect for levelup       pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); -     player->SetPet(pet); +     player->SetMinion(pet, true);       pet->SavePetToDB(PET_SAVE_AS_CURRENT);       player->PetSpellInitialize(); @@ -3955,7 +4518,7 @@ bool ChatHandler::HandlePetTpCommand(const char *args)      uint32 tp = atol(args); -    pet->SetTP(tp); +    //pet->SetTP(tp);      PSendSysMessage("Pet's tp changed to %u", tp);      return true; @@ -4086,7 +4649,7 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)      group_member->groupAI        = 0;      CreatureGroupMap[lowguid] = group_member; -    pCreature->SearchFormation(); +    pCreature->SearchFormationAndPath();      WorldDatabase.PExecuteLog("INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`) VALUES ('%u','%u','%f', '%f', '%u')",          leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI);  | 
