diff options
Diffstat (limited to 'src/game/Level2.cpp')
| -rw-r--r-- | src/game/Level2.cpp | 2927 | 
1 files changed, 1655 insertions, 1272 deletions
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index fc6e8a51a74..c76c6e78102 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,31 +10,28 @@   *   * 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"  #include "GameObject.h"  #include "Opcodes.h"  #include "Chat.h" -#include "ObjectAccessor.h"  #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 "WaypointManager.h"  #include "Util.h" @@ -43,9 +40,9 @@  #include <fstream>  #include <map>  #include "GlobalEvents.h" -#include "TicketMgr.h"  #include "TargetedMovementGenerator.h"                      // for HandleNpcUnFollowCommand +#include "CreatureGroups.h"  static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =  { @@ -56,298 +53,97 @@ static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =  //mute player for some times  bool ChatHandler::HandleMuteCommand(const char* args)  { -    if (!*args) +    char* nameStr; +    char* delayStr; +    extractOptFirstArg((char*)args,&nameStr,&delayStr); +    if(!delayStr)          return false; -    char *charname = strtok((char*)args, " "); -    if (!charname) -        return false; - -    std::string cname = charname; - -    char *timetonotspeak = strtok(NULL, " "); -    if(!timetonotspeak) +    Player* target; +    uint64 target_guid; +    std::string target_name; +    if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))          return false; -    uint32 notspeaktime = (uint32) atoi(timetonotspeak); +    uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid); -    if(!normalizePlayerName(cname)) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); -    if(!guid) +    // find only player from same account if any +    if(!target)      { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); -        return false; +        if(WorldSession* session = sWorld.FindSession(account_id)) +            target = session->GetPlayer();      } -    Player *chr = objmgr.GetPlayer(guid); +    uint32 notspeaktime = (uint32) atoi(delayStr); -    // 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 (target,target_guid,true))          return false; -    }      time_t mutetime = time(NULL) + notspeaktime*60; -    if (chr) -        chr->GetSession()->m_muteTime = mutetime; +    if (target) +        target->GetSession()->m_muteTime = mutetime; -    LoginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); +    LoginDatabase.PExecute("UPDATE account SET mutetime = " UI64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); -    if(chr) -        ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); +    if(target) +        ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); -    PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime); +    std::string nameLink = playerLink(target_name); +    PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);      return true;  }  //unmute player  bool ChatHandler::HandleUnmuteCommand(const char* args)  { -    if (!*args) +    Player* target; +    uint64 target_guid; +    std::string target_name; +    if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))          return false; -    char *charname = strtok((char*)args, " "); -    if (!charname) -        return false; - -    std::string cname = charname; +    uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid); -    if(!normalizePlayerName(cname)) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); -    if(!guid) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    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 +    // find only player from same account if any +    if(!target)      { -        account_id = objmgr.GetPlayerAccountIdByGUID(guid); -        security = accmgr.GetSecurity(account_id); +        if(WorldSession* session = sWorld.FindSession(account_id)) +            target = session->GetPlayer();      } -    if(m_session && security >= m_session->GetSecurity()) -    { -        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); -        SetSentErrorMessage(true); +    // must have strong lesser security level +    if(HasLowerSecurity (target,target_guid,true))          return false; -    } -    if (chr) +    if (target)      { -        if(chr->CanSpeak()) +        if(target->CanSpeak())          {              SendSysMessage(LANG_CHAT_ALREADY_ENABLED);              SetSentErrorMessage(true);              return false;          } -        chr->GetSession()->m_muteTime = 0; +        target->GetSession()->m_muteTime = 0;      }      LoginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id ); -    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; +        ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); -        std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); -        std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); +    std::string nameLink = playerLink(target_name); -        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; - -    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, " "); @@ -359,7 +155,7 @@ bool ChatHandler::HandleGoTicketCommand(const char * args)      if(!ticket_id)          return false; -    GM_Ticket *ticket = ticketmgr.GetGMTicket(ticket_id); +    GM_Ticket *ticket = objmgr.GetGMTicket(ticket_id);      if(!ticket)      {          SendSysMessage(LANG_COMMAND_TICKETNOTEXIST); @@ -478,15 +274,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 +380,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())); +    GameObject* target = m_session->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT)); -    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; -} - -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 +581,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 +601,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 +638,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); +    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, 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)); -        */ - -        // 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,13 +687,10 @@ 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()); -        obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX()); -        obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY()); -        obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());          map->Add(obj);      } @@ -1256,13 +710,10 @@ 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()); -        obj->SetFloatValue(GAMEOBJECT_POS_X, x); -        obj->SetFloatValue(GAMEOBJECT_POS_Y, y); -        obj->SetFloatValue(GAMEOBJECT_POS_Z, z);          map->Add(obj);      } @@ -1270,25 +721,413 @@ 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 = GetSessionDbcLocale(); +            std::string name = factionEntry->name[loc]; +            if(name.empty()) +                continue; + +            if (!Utf8FitTo(name, wnamepart)) +            { +                loc = 0; +                for(; loc < MAX_LOCALE; ++loc) +                { +                    if(loc==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[GetSessionDbcLocale()], factionId); +        SetSentErrorMessage(true); +        return false; +    } + +    target->GetReputationMgr().SetReputation(factionEntry,amount); +    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[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, x, y, z, o)) +    { +        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 +1174,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 +1196,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 +1251,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 +1267,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 +1573,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 +1602,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 +1652,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 (player->CanTameExoticPets())) +    { +        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;  } @@ -1721,7 +2094,7 @@ bool ChatHandler::HandleNpcFactionIdCommand(const char* args)  //kick player  bool ChatHandler::HandleKickPlayerCommand(const char *args)  { -    const char* kickName = strtok((char*)args, " "); +/*    const char* kickName = strtok((char*)args, " ");      char* kickReason = strtok(NULL, "\n");      std::string reason = "No Reason";      std::string kicker = "Console"; @@ -1731,7 +2104,7 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)          kicker = m_session->GetPlayer()->GetName();      if(!kickName) -     { +    {          Player* player = getSelectedPlayer();          if(!player)          { @@ -1747,14 +2120,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 +2137,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,83 +2160,82 @@ 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;          } +    }*/ +    Player* target; +    if(!extractPlayerTarget((char*)args,&target)) +        return false; + +    if (m_session && target==m_session->GetPlayer()) +    { +        SendSysMessage(LANG_COMMAND_KICKSELF); +        SetSentErrorMessage(true); +        return false;      } + +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; + +    // send before target pointer invalidate +    PSendSysMessage(LANG_COMMAND_KICKMESSAGE,GetNameLink(target).c_str()); +    target->GetSession()->KickPlayer();      return true;  } -//show info of player -bool ChatHandler::HandlePInfoCommand(const char* args) +//set temporary phase mask for player +bool ChatHandler::HandleModifyPhaseCommand(const char* args)  { -    Player* target = NULL; -    uint64 targetGUID = 0; - -    char* px = strtok((char*)args, " "); -    char* py = NULL; - -    std::string name; +    if (!*args) +        return false; -    if (px) -    { -        name = px; +    uint32 phasemask = (uint32)atoi((char*)args); -        if(name.empty()) -            return false; +    Unit *target = getSelectedUnit(); +    if(!target) +        target = m_session->GetPlayer(); -        if(!normalizePlayerName(name)) -        { -            SendSysMessage(LANG_PLAYER_NOT_FOUND); -            SetSentErrorMessage(true); -            return false; -        } +    // check online security +    else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) +        return false; -        target = objmgr.GetPlayer(name.c_str()); -        if (target) -            py = strtok(NULL, " "); -        else -        { -            targetGUID = objmgr.GetPlayerGUIDByName(name); -            if(targetGUID) -                py = strtok(NULL, " "); -            else -                py = px; -        } -    } +    target->SetPhaseMask(phasemask,true); -    if(!target && !targetGUID) -    { -        target = getSelectedPlayer(); -    } +    return true; +} -    if(!target && !targetGUID) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); +//show info of player +bool ChatHandler::HandlePInfoCommand(const char* args) +{ +    Player* target; +    uint64 target_guid; +    std::string target_name; +    if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))          return false; -    }      uint32 accId = 0;      uint32 money = 0; @@ -1872,8 +2246,10 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      // get additional information from Player object      if(target)      { -        targetGUID = target->GetGUID(); -        name = target->GetName();                           // re-read for case getSelectedPlayer() target +        // check online security +        if (HasLowerSecurity(target, 0)) +            return false; +          accId = target->GetSession()->GetAccountId();          money = target->GetMoney();          total_player_time = target->GetTotalPlayedTime(); @@ -1883,28 +2259,26 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      // get additional information from DB      else      { -        QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID)); +        // check offline security +        if (HasLowerSecurity(NULL, target_guid)) +            return false; + +        //                                                     0 +        QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid));          if (!result) -        { -            SendSysMessage(LANG_PLAYER_NOT_FOUND); -            SetSentErrorMessage(true);              return false; -        } +          Field *fields = result->Fetch();          total_player_time = fields[0].GetUInt32();          delete result;          Tokens data; -        if (!Player::LoadValuesArrayFromDB(data,targetGUID)) -        { -            SendSysMessage(LANG_PLAYER_NOT_FOUND); -            SetSentErrorMessage(true); +        if (!Player::LoadValuesArrayFromDB(data,target_guid))              return false; -        }          money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);          level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL); -        accId = objmgr.GetPlayerAccountIdByGUID(targetGUID); +        accId = objmgr.GetPlayerAccountIdByGUID(target_guid);      }      std::string username = GetTrinityString(LANG_ERROR); @@ -1933,7 +2307,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(target_name); + +    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), 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; @@ -1941,123 +2317,202 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      uint32 copp = (money % GOLD) % SILVER;      PSendSysMessage(LANG_PINFO_LEVEL,  timeStr.c_str(), level, gold,silv,copp ); -    if ( py && strncmp(py, "rep", 3) == 0 ) +    return true; +} + +/*//show tickets +void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time) +{ +    std::string name; +    if(!objmgr.GetPlayerNameByGUID(guid,name)) +        name = GetTrinityString(LANG_UNKNOWN); + +    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)      { -        if(!target) +        if(!m_session)          { -            // rep option not implemented for offline case -            SendSysMessage(LANG_PINFO_NO_REP); +            SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true);              return false;          } -        char* FactionName; -        for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr) +        size_t count = objmgr.GetTicketCount(); + +        bool accept = m_session->GetPlayer()->isAcceptTickets(); + +        PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ?  GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF)); +        return true; +    } + +    // ticket on +    if(strncmp(px,"on",3) == 0) +    { +        if(!m_session)          { -            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]); -            std::ostringstream ss; -            ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")"; - -            if(itr->second.Flags & FACTION_FLAG_VISIBLE) -                ss << GetTrinityString(LANG_FACTION_VISIBLE); -            if(itr->second.Flags & FACTION_FLAG_AT_WAR) -                ss << GetTrinityString(LANG_FACTION_ATWAR); -            if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED) -                ss << GetTrinityString(LANG_FACTION_PEACE_FORCED); -            if(itr->second.Flags & FACTION_FLAG_HIDDEN) -                ss << GetTrinityString(LANG_FACTION_HIDDEN); -            if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED) -                ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); -            if(itr->second.Flags & FACTION_FLAG_INACTIVE) -                ss << GetTrinityString(LANG_FACTION_INACTIVE); - -            SendSysMessage(ss.str().c_str()); +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false;          } -    } -    return true; -} -//set spawn dist of creature -bool ChatHandler::HandleNpcSpawnDistCommand(const char* args) -{ -    if(!*args) -        return false; +        m_session->GetPlayer()->SetAcceptTicket(true); +        SendSysMessage(LANG_COMMAND_TICKETON); +        return true; +    } -    float option = atof((char*)args); -    if (option < 0.0f) +    // ticket off +    if(strncmp(px,"off",4) == 0)      { -        SendSysMessage(LANG_BAD_VALUE); -        return false; +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } + +        m_session->GetPlayer()->SetAcceptTicket(false); +        SendSysMessage(LANG_COMMAND_TICKETOFF); +        return true;      } -    MovementGeneratorType mtype = IDLE_MOTION_TYPE; -    if (option >0.0f) -        mtype = RANDOM_MOTION_TYPE; +    // ticket #num +    int num = atoi(px); +    if(num > 0) +    { +        QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1); -    Creature *pCreature = getSelectedCreature(); -    uint32 u_guidlow = 0; +        if(!result) +        { +            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); +            SetSentErrorMessage(true); +            return false; +        } -    if (pCreature) -        u_guidlow = pCreature->GetDBTableGUIDLow(); -    else -        return false; +        Field* fields = result->Fetch(); -    pCreature->SetRespawnRadius((float)option); -    pCreature->SetDefaultMovementType(mtype); -    pCreature->GetMotionMaster()->Initialize(); -    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn -    { -        pCreature->setDeathState(JUST_DIED); -        pCreature->Respawn(); +        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); +    uint64 target_guid; +    if(!extractPlayerTarget(px,NULL,&target_guid)) +        return false; + +    // ticket $char_name +    GMTicket* ticket = objmgr.GetGMTicket(GUID_LOPART(target_guid)); +    if(!ticket) +        return false; + +    std::string time = TimeToTimestampStr(ticket->GetLastUpdate()); + +    ShowTicket(target_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, " "); - -    if (!stime) -        return false; +    // delticket all +    if(strncmp(px,"all",4) == 0) +    { +        objmgr.DeleteAll(); +        SendSysMessage(LANG_COMMAND_ALLTICKETDELETED); +        return true; +    } -    int i_stime = atoi((char*)stime); +    int num = (uint32)atoi(px); -    if (i_stime < 0) +    // delticket #num +    if(num > 0)      { -        SendSysMessage(LANG_BAD_VALUE); -        SetSentErrorMessage(true); -        return false; -    } +        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; -    Creature *pCreature = getSelectedCreature(); -    uint32 u_guidlow = 0; +        objmgr.Delete(guid); -    if (pCreature) -        u_guidlow = pCreature->GetDBTableGUIDLow(); -    else +        //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; +    } + +    Player* target; +    uint64 target_guid; +    std::string target_name; +    if(!extractPlayerTarget(px,&target,&target_guid,&target_name))          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 +    objmgr.Delete(GUID_LOPART(target_guid)); +    // notify players about ticket deleting +    if(target) +        target->GetSession()->SendGMTicketGetTicket(0x0A,0); + +    std::string nameLink = playerLink(target_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 +2530,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 +2585,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 +2615,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 +2626,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 +2664,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 +2977,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 +3047,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,28 +3076,20 @@ 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, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))                  {                      PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);                      delete wpCreature2;                      return false;                  } -                wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()); - -                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()); -                    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 +3123,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)      }      PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); -      return true;  } @@ -2701,7 +3162,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              return false;          } -        pathid = target->GetWaypointPath(); +        pathid = target->GetWaypointPathId();      }      else @@ -2718,11 +3179,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 +3259,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 +3301,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, x, y, z, o))              {                  PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);                  delete wpCreature; @@ -2851,21 +3309,12 @@ bool ChatHandler::HandleWpShowCommand(const char* args)                  return false;              } -            wpCreature->Relocate(x, y, z, o); - -            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()); -                delete wpCreature; -                delete result; -                return false; -            } -              sLog.outDebug("DEBUG: UPDATE waypoint_data SET wpguid = '%u");              // 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 +3355,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, x, y, z, o))          {              PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);              delete pCreature; @@ -2914,17 +3363,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              return false;          } -        pCreature->Relocate(x, y, z, o); - -        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()); -            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 +3410,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, x, y, z, o))          {              PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);              delete pCreature; @@ -2979,17 +3418,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              return false;          } -        pCreature->Relocate(x, y, z, o); - -        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()); -            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 +3447,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,143 +3490,108 @@ 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; -    std::string oldname; - -    char* px = strtok((char*)args, " "); - -    if(px) -    { -        oldname = px; - -        if(!normalizePlayerName(oldname)) -        { -            SendSysMessage(LANG_PLAYER_NOT_FOUND); -            SetSentErrorMessage(true); -            return false; -        } - -        target = objmgr.GetPlayer(oldname.c_str()); - -        if (!target) -            targetGUID = objmgr.GetPlayerGUIDByName(oldname); -    } - -    if(!target && !targetGUID) -    { -        target = getSelectedPlayer(); -    } - -    if(!target && !targetGUID) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); +    Player* target; +    uint64 target_guid; +    std::string target_name; +    if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))          return false; -    }      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)); -        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID)); +        // check offline security +        if (HasLowerSecurity(NULL, target_guid)) +            return false; + +        std::string oldNameLink = playerLink(target_name); + +        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid)); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid));      }      return true;  } -//spawn go -bool ChatHandler::HandleGameObjectCommand(const char* args) +// customize characters +bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)  { -    if (!*args) +    Player* target; +    uint64 target_guid; +    std::string target_name; +    if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))          return false; -    char* pParam1 = strtok((char*)args, " "); -    if (!pParam1) -        return false; - -    uint32 id = atoi((char*)pParam1); -    if(!id) -        return false; - -    char* spawntimeSecs = strtok(NULL, " "); - -    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id); - -    if (!goI) +    if(target)      { -        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); -        SetSentErrorMessage(true); -        return false; +        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());      } - -    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)) +    else      { -        delete pGameObj; -        return false; -    } +        std::string oldNameLink = playerLink(target_name); -    if( spawntimeSecs ) -    { -        uint32 value = atoi((char*)spawntimeSecs); -        pGameObj->SetRespawnTime(value); -        //sLog.outDebug("*** spawntimeSecs: %d", value); +        PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid)); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid));      } -    // fill the gameobject data and save to the db -    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +    return true; +} -    // this will generate a new guid if the object is in an instance -    if(!pGameObj->LoadFromDB(db_lowGUID, map)) -    { -        delete pGameObj; +bool ChatHandler::HandleCharacterReputationCommand(const char* args) +{ +    Player* target; +    if(!extractPlayerTarget((char*)args,&target))          return false; -    } -    sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o); - -    map->Add(pGameObj); +    LocaleConstant loc = GetSessionDbcLocale(); -    // TODO: is it really necessary to add both the real and DB table guid here ? -    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID)); +    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); +        char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#"; +        ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); +        std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); +        std::ostringstream ss; +        if (m_session) +            ss << itr->second.ID << " - |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << " " << localeNames[loc] << "]|h|r"; +        else +            ss << itr->second.ID << " - " << factionName << " " << localeNames[loc]; -    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z); -    return true; -} +        ss << " " << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ")"; -//show animation -bool ChatHandler::HandleAnimCommand(const char* args) -{ -    if (!*args) -        return false; +        if(itr->second.Flags & FACTION_FLAG_VISIBLE) +            ss << GetMangosString(LANG_FACTION_VISIBLE); +        if(itr->second.Flags & FACTION_FLAG_AT_WAR) +            ss << GetMangosString(LANG_FACTION_ATWAR); +        if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED) +            ss << GetMangosString(LANG_FACTION_PEACE_FORCED); +        if(itr->second.Flags & FACTION_FLAG_HIDDEN) +            ss << GetMangosString(LANG_FACTION_HIDDEN); +        if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED) +            ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED); +        if(itr->second.Flags & FACTION_FLAG_INACTIVE) +            ss << GetMangosString(LANG_FACTION_INACTIVE); -    uint32 anim_id = atoi((char*)args); -    m_session->GetPlayer()->HandleEmoteCommand(anim_id); +        SendSysMessage(ss.str().c_str()); +    }      return true;  }  //change standstate -bool ChatHandler::HandleStandStateCommand(const char* args) +bool ChatHandler::HandleModifyStandStateCommand(const char* args)  {      if (!*args)          return false; @@ -3208,7 +3602,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 +3615,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 +3634,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 +3652,10 @@ bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      target->UpdateHonorFields();      return true;  } @@ -3270,8 +3676,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 +3710,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 +3746,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 +3763,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 +3795,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 +3812,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 +3836,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 +3853,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())      { @@ -3462,39 +3868,51 @@ bool ChatHandler::HandleEventStopCommand(const char* args)  bool ChatHandler::HandleCombatStopCommand(const char* args)  { -    Player *player; +    Player* target; +    if(!extractPlayerTarget((char*)args,&target)) +        return false; -    if(*args) -    { -        std::string playername = args; +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; -        if(!normalizePlayerName(playername)) -        { -            SendSysMessage(LANG_PLAYER_NOT_FOUND); -            SetSentErrorMessage(true); -            return false; -        } +    target->CombatStop(); +    target->getHostilRefManager().deleteReferences(); +    return true; +} -        player = objmgr.GetPlayer(playername.c_str()); +void ChatHandler::HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id) +{ +    uint32 classmask = player->getClassMask(); -        if(!player) -        { -            SendSysMessage(LANG_PLAYER_NOT_FOUND); -            SetSentErrorMessage(true); -            return false; -        } -    } -    else +    for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)      { -        player = getSelectedPlayer(); +        SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); +        if (!skillLine) +            continue; -        if (!player) -            player = m_session->GetPlayer(); -    } +        // wrong skill +        if( skillLine->skillId != skill_id) +            continue; -    player->CombatStop(); -    player->getHostilRefManager().deleteReferences(); -    return true; +        // not high rank +        if(skillLine->forward_spellid ) +            continue; + +        // skip racial skills +        if (skillLine->racemask != 0) +            continue; + +        // skip wrong class skills +        if( skillLine->classmask && (skillLine->classmask & classmask) == 0) +            continue; + +        SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); +        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false)) +            continue; + +        player->learnSpell(skillLine->spellId,false); +    }  }  bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/) @@ -3507,31 +3925,10 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)          if( !skillInfo )              continue; -        if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY ) +        if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) && +            skillInfo->canLink)                             // only prof. with recipes have          { -            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) -            { -                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); -                if( !skillLine ) -                    continue; - -                // skip racial skills -                if( skillLine->racemask != 0 ) -                    continue; - -                // skip wrong class skills -                if( skillLine->classmask && (skillLine->classmask & classmask) == 0) -                    continue; - -                if( skillLine->skillId != i || skillLine->forward_spellid ) -                    continue; - -                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); -                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) -                    continue; - -                m_session->GetPlayer()->learnSpell(skillLine->spellId); -            } +            HandleLearnSkillRecipesHelper(m_session->GetPlayer(),skillInfo->id);          }      } @@ -3566,54 +3963,58 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)      uint32 classmask = m_session->GetPlayer()->getClassMask(); -    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) +    std::string name; + +    SkillLineEntry const *targetSkillInfo = NULL; +    for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i)      {          SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i); -        if( !skillInfo ) +        if (!skillInfo)              continue; -        if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && -            skillInfo->categoryId != SKILL_CATEGORY_SECONDARY ) +        if ((skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && +            skillInfo->categoryId != SKILL_CATEGORY_SECONDARY) || +            !skillInfo->canLink)                            // only prof with recipes have set              continue; -        int loc = m_session->GetSessionDbcLocale(); -        std::string name = skillInfo->name[loc]; +        int loc = GetSessionDbcLocale(); +        name = skillInfo->name[loc]; +        if(name.empty()) +            continue; -        if(Utf8FitTo(name, wnamepart)) +        if (!Utf8FitTo(name, wnamepart))          { -            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) +            loc = 0; +            for(; loc < MAX_LOCALE; ++loc)              { -                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); -                if( !skillLine ) -                    continue; - -                if( skillLine->skillId != i || skillLine->forward_spellid ) -                    continue; - -                // skip racial skills -                if( skillLine->racemask != 0 ) -                    continue; - -                // skip wrong class skills -                if( skillLine->classmask && (skillLine->classmask & classmask) == 0) +                if(loc==GetSessionDbcLocale())                      continue; -                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); -                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) +                name = skillInfo->name[loc]; +                if(name.empty())                      continue; -                if( !target->HasSpell(spellInfo->Id) ) -                    m_session->GetPlayer()->learnSpell(skillLine->spellId); +                if (Utf8FitTo(name, wnamepart)) +                    break;              } +        } -            uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id); -            target->SetSkill(skillInfo->id, maxLevel, maxLevel); -            PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); -            return true; +        if(loc < MAX_LOCALE) +        { +            targetSkillInfo = skillInfo; +            break;          }      } -    return false; +    if(!targetSkillInfo) +        return false; + +    HandleLearnSkillRecipesHelper(target,targetSkillInfo->id); + +    uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->id); +    target->SetSkill(targetSkillInfo->id, maxLevel, maxLevel); +    PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); +    return true;  }  bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) @@ -3642,7 +4043,7 @@ bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)      char* limit_str = strtok (NULL, " ");      int32 limit = limit_str ? atoi (limit_str) : -1; -    if (!AccountMgr::normilizeString (account)) +    if (!AccountMgr::normalizeString (account))          return false;      LoginDatabase.escape_string (account); @@ -3710,6 +4111,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;  } @@ -3720,79 +4128,56 @@ bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)      return true;  } -bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/) +bool ChatHandler::HandleRepairitemsCommand(const char* args)  { -    Player *target = getSelectedPlayer(); +    Player* target; +    if(!extractPlayerTarget((char*)args,&target)) +        return false; -    if(!target) -    { -        PSendSysMessage(LANG_NO_CHAR_SELECTED); -        SetSentErrorMessage(true); +    // 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; -} -bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) -{ -    Player *player = m_session->GetPlayer(); -    Creature *creature = getSelectedCreature(); +    Player *player = getSelectedPlayer(); -    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 +4210,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)        return false; @@ -3841,7 +4226,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()); @@ -3858,16 +4242,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(); @@ -3935,7 +4318,7 @@ bool ChatHandler::HandlePetUnlearnCommand(const char *args)      uint32 spellId = extractSpellIdFromLink((char*)args);      if(pet->HasSpell(spellId)) -        pet->removeSpell(spellId); +        pet->removeSpell(spellId, false);      else          PSendSysMessage("Pet doesn't have that spell"); @@ -3959,7 +4342,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; @@ -4084,13 +4467,13 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)      FormationInfo *group_member;      group_member                 = new FormationInfo; -    group_member->follow_angle   = pCreature->GetAngle(chr) - chr->GetOrientation(); +    group_member->follow_angle   = (pCreature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI;      group_member->follow_dist    = sqrtf(pow(chr->GetPositionX() - pCreature->GetPositionX(),int(2))+pow(chr->GetPositionY()-pCreature->GetPositionY(),int(2)));      group_member->leaderGUID     = leaderGUID;      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);  | 
