diff options
Diffstat (limited to 'src/game/Level2.cpp')
| -rw-r--r-- | src/game/Level2.cpp | 2420 | 
1 files changed, 1487 insertions, 933 deletions
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 26a701fc507..a9c27a719e3 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1,7 +1,7 @@  /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>   * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -10,19 +10,16 @@   *   * This program is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details.   *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */  #include "Common.h"  #include "Database/DatabaseEnv.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "World.h"  #include "ObjectMgr.h"  #include "Player.h"  #include "Item.h" @@ -33,9 +30,11 @@  #include "MapManager.h"  #include "Language.h"  #include "World.h" -#include "GameEvent.h" +#include "GameEventMgr.h"  #include "SpellMgr.h" +#include "PoolHandler.h"  #include "AccountMgr.h" +//#include "GMTicketMgr.h"  #include "WaypointManager.h"  #include "Util.h"  #include <cctype> @@ -58,11 +57,13 @@ bool ChatHandler::HandleMuteCommand(const char* args)      if (!*args)          return false; -    char *charname = strtok((char*)args, " "); -    if (!charname) +    std::string name = extractPlayerNameFromLink((char*)args); +    if(name.empty()) +    { +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true);          return false; - -    std::string cname = charname; +    }      char *timetonotspeak = strtok(NULL, " ");      if(!timetonotspeak) @@ -70,14 +71,7 @@ bool ChatHandler::HandleMuteCommand(const char* args)      uint32 notspeaktime = (uint32) atoi(timetonotspeak); -    if(!normalizePlayerName(cname)) -    { -        SendSysMessage(LANG_PLAYER_NOT_FOUND); -        SetSentErrorMessage(true); -        return false; -    } - -    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); +    uint64 guid = objmgr.GetPlayerGUIDByName(name);      if(!guid)      {          SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -87,27 +81,11 @@ bool ChatHandler::HandleMuteCommand(const char* args)      Player *chr = objmgr.GetPlayer(guid); -    // check security -    uint32 account_id = 0; -    uint32 security = 0; - -    if (chr) -    { -        account_id = chr->GetSession()->GetAccountId(); -        security = chr->GetSession()->GetSecurity(); -    } -    else -    { -        account_id = objmgr.GetPlayerAccountIdByGUID(guid); -        security = accmgr.GetSecurity(account_id); -    } - -    if(m_session && security >= m_session->GetSecurity()) -    { -        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); -        SetSentErrorMessage(true); +    // must have strong lesser security level +    if(HasLowerSecurity (chr,guid,true))          return false; -    } + +    uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);      time_t mutetime = time(NULL) + notspeaktime*60; @@ -119,7 +97,9 @@ bool ChatHandler::HandleMuteCommand(const char* args)      if(chr)          ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); -    PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime); +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);      return true;  } @@ -130,20 +110,15 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)      if (!*args)          return false; -    char *charname = strtok((char*)args, " "); -    if (!charname) -        return false; - -    std::string cname = charname; - -    if(!normalizePlayerName(cname)) +    std::string name = extractPlayerNameFromLink((char*)args); +    if(name.empty())      {          SendSysMessage(LANG_PLAYER_NOT_FOUND);          SetSentErrorMessage(true);          return false;      } -    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str()); +    uint64 guid = objmgr.GetPlayerGUIDByName(name);      if(!guid)      {          SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -153,27 +128,11 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)      Player *chr = objmgr.GetPlayer(guid); -    // check security -    uint32 account_id = 0; -    uint32 security = 0; - -    if (chr) -    { -        account_id = chr->GetSession()->GetAccountId(); -        security = chr->GetSession()->GetSecurity(); -    } -    else -    { -        account_id = objmgr.GetPlayerAccountIdByGUID(guid); -        security = accmgr.GetSecurity(account_id); -    } - -    if(m_session && security >= m_session->GetSecurity()) -    { -        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); -        SetSentErrorMessage(true); +    // must have strong lesser security level +    if(HasLowerSecurity (chr,guid,true))          return false; -    } + +    uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);      if (chr)      { @@ -192,155 +151,9 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)      if(chr)          ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); -    PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str()); -    return true; -} +    std::string nameLink = playerLink(name); -bool ChatHandler::HandleTargetObjectCommand(const char* args) -{ -    Player* pl = m_session->GetPlayer(); -    QueryResult *result; -    GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList(); -    if(*args) -    { -        int32 id = atoi((char*)args); -        if(id) -            result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", -                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id); -        else -        { -            std::string name = args; -            WorldDatabase.escape_string(name); -            result = WorldDatabase.PQuery( -                "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " -                "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1", -                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str()); -        } -    } -    else -    { -        std::ostringstream eventFilter; -        eventFilter << " AND (event IS NULL "; -        bool initString = true; - -        for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr) -        { -            if (initString) -            { -                eventFilter  <<  "OR event IN (" <<*itr; -                initString =false; -            } -            else -                eventFilter << "," << *itr; -        } - -        if (!initString) -            eventFilter << "))"; -        else -            eventFilter << ")"; - -        result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, " -            "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject " -            "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1", -            m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str()); -    } - -    if (!result) -    { -        SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND); -        return true; -    } - -    Field *fields = result->Fetch(); -    uint32 lowguid = fields[0].GetUInt32(); -    uint32 id = fields[1].GetUInt32(); -    float x = fields[2].GetFloat(); -    float y = fields[3].GetFloat(); -    float z = fields[4].GetFloat(); -    float o = fields[5].GetFloat(); -    int mapid = fields[6].GetUInt16(); -    delete result; - -    GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id); - -    if (!goI) -    { -        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); -        return false; -    } - -    GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT)); - -    PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o); - -    if(target) -    { -        int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); -        if(curRespawnDelay < 0) -            curRespawnDelay = 0; - -        std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); -        std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); - -        PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); -    } -    return true; -} - -//teleport to gameobject -bool ChatHandler::HandleGoObjectCommand(const char* args) -{ -    if(!*args) -        return false; - -    Player* _player = m_session->GetPlayer(); - -    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r -    char* cId = extractKeyFromLink((char*)args,"Hgameobject"); -    if(!cId) -        return false; - -    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;  } @@ -435,15 +248,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)  { @@ -541,6 +354,508 @@ bool ChatHandler::HandleGoCreatureCommand(const char* args)      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); +    return true; +} + +bool ChatHandler::HandleGameObjectTargetCommand(const char* 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; + +        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 +        { +            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 (GameEventMgr::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 10", +            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; +    } + +    bool found = false; +    float x, y, z, o; +    uint32 lowguid, id; +    uint16 mapid, pool_id; + +    do +    { +        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) ); + +    delete result; + +    if (!found) +    { +        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); +        return false; +    } + +    GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id); + +    if (!goI) +    { +        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); +        return false; +    } + +    GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT)); + +    PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o); + +    if(target) +    { +        int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); +        if(curRespawnDelay < 0) +            curRespawnDelay = 0; + +        std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true); +        std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); + +        PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); +    } +    return true; +} + +//delete object by selection or guid +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"); +    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; +    } + +    uint64 owner_guid = obj->GetOwnerGUID(); +    if(owner_guid) +    { +        Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid); +        if(!owner && !IS_PLAYER_GUID(owner_guid)) +        { +            PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow()); +            SetSentErrorMessage(true); +            return false; +        } + +        owner->RemoveGameObject(obj,false); +    } + +    obj->SetRespawnTime(0);                                 // not save respawn time +    obj->Delete(); +    obj->DeleteFromDB(); + +    PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow()); + +    return true; +} + +//turn selected object +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"); +    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* po = strtok(NULL, " "); +    float o; + +    if (po) +    { +        o = (float)atof(po); +    } +    else +    { +        Player *chr = m_session->GetPlayer(); +        o = chr->GetOrientation(); +    } + +    Map* map = obj->GetMap(); +    map->Remove(obj,false); + +    obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o); +    obj->UpdateRotationFields(); + +    map->Add(obj); + +    obj->SaveToDB(); +    obj->Refresh(); + +    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow(), o); + +    return true; +} + +//move selected object +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"); +    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* px = strtok(NULL, " "); +    char* py = strtok(NULL, " "); +    char* pz = strtok(NULL, " "); + +    if (!px) +    { +        Player *chr = m_session->GetPlayer(); + +        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); +    } +    else +    { +        if(!py || !pz) +            return false; + +        float x = (float)atof(px); +        float y = (float)atof(py); +        float z = (float)atof(pz); + +        if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z)) +        { +            PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId()); +            SetSentErrorMessage(true); +            return false; +        } + +        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); +    } + +    obj->SaveToDB(); +    obj->Refresh(); + +    PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow()); + +    return true; +} + +//spawn go +bool ChatHandler::HandleGameObjectAddCommand(const char* args) +{ +    if (!*args) +        return false; + +    // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r +    char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry"); +    if(!cId) +        return false; + +    uint32 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, 1)) +    { +        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(); @@ -588,6 +903,7 @@ bool ChatHandler::HandleLookupFactionCommand(const char* args)                      repState = &repItr->second;              } +              int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();              std::string name = factionEntry->name[loc];              if(name.empty()) @@ -668,6 +984,10 @@ bool ChatHandler::HandleModifyRepCommand(const char * args)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");      if(!factionTxt)          return false; @@ -745,145 +1065,18 @@ bool ChatHandler::HandleModifyRepCommand(const char * args)      }      target->SetFactionReputation(factionEntry,amount); -    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId)); -    return true; -} - -bool ChatHandler::HandleNameCommand(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); -            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) -    { - -        PSendSysMessage(LANG_TOO_LONG_SUBNAME, 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); -        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 ); - +    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, GetNameLink(target).c_str(), target->GetReputation(factionId));      return true;  } +//-----------------------Npc Commands-----------------------  //add spawn of creature  bool ChatHandler::HandleNpcAddCommand(const char* args)  {      if(!*args)          return false; -    char* charID = strtok((char*)args, " "); -    if (!charID) +    char* charID = extractKeyFromLink((char*)args,"Hcreature_entry"); +    if(!charID)          return false;      char* team = strtok(NULL, " "); @@ -901,7 +1094,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)      Map *map = chr->GetMap();      Creature* pCreature = new Creature; -    if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval)) +    if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval))      {          delete pCreature;          return false; @@ -911,12 +1104,12 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)      if(!pCreature->IsPositionValid())      { -        sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); +        sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());          delete pCreature;          return false;      } -    pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +    pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());      uint32 db_guid = pCreature->GetDBTableGUIDLow(); @@ -928,466 +1121,334 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)      return true;  } -bool ChatHandler::HandleNpcDeleteCommand(const char* args) +//add item in vendorlist +bool ChatHandler::HandleNpcAddVendorItemCommand(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 = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT)); -    } -    else -        unit = getSelectedCreature(); +    if (!*args) +        return false; -    if(!unit || unit->isPet() || unit->isTotem()) +    char* pitem  = extractKeyFromLink((char*)args,"Hitem"); +    if (!pitem)      { -        SendSysMessage(LANG_SELECT_CREATURE); +        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);          SetSentErrorMessage(true);          return false;      } -    // Delete the creature -    unit->CombatStop(); -    unit->DeleteFromDB(); -    unit->CleanupsBeforeDelete(); -    unit->AddObjectToRemoveList(); - -    SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); +    uint32 itemId = atol(pitem); -    return true; -} +    char* fmaxcount = strtok(NULL, " ");                    //add maxcount, default: 0 +    uint32 maxcount = 0; +    if (fmaxcount) +        maxcount = atol(fmaxcount); -//delete object by selection or guid -bool ChatHandler::HandleDelObjectCommand(const char* 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; +    char* fincrtime = strtok(NULL, " ");                    //add incrtime, default: 0 +    uint32 incrtime = 0; +    if (fincrtime) +        incrtime = atol(fincrtime); -    uint32 lowguid = atoi(cId); -    if(!lowguid) -        return false; +    char* fextendedcost = strtok(NULL, " ");                //add ExtendedCost, default: 0 +    uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; -    GameObject* obj = NULL; +    Creature* vendor = getSelectedCreature(); -    // by DB guid -    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) -        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); +    uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; -    if(!obj) +    if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))      { -        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);          SetSentErrorMessage(true);          return false;      } -    uint64 owner_guid = obj->GetOwnerGUID(); -    if(owner_guid) -    { -        Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid); -        if(!owner && !IS_PLAYER_GUID(owner_guid)) -        { -            PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow()); -            SetSentErrorMessage(true); -            return false; -        } - -        owner->RemoveGameObject(obj,false); -    } - -    obj->SetRespawnTime(0);                                 // not save respawn time -    obj->Delete(); -    obj->DeleteFromDB(); +    objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost); -    PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow()); +    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId); +    PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);      return true;  } -//turn selected object -bool ChatHandler::HandleTurnObjectCommand(const char* args) +//del item from vendor list +bool ChatHandler::HandleNpcDelVendorItemCommand(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) +    if (!*args)          return false; -    GameObject* obj = NULL; - -    // by DB guid -    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) -        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); - -    if(!obj) +    Creature* vendor = getSelectedCreature(); +    if (!vendor || !vendor->isVendor())      { -        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); +        SendSysMessage(LANG_COMMAND_VENDORSELECTION);          SetSentErrorMessage(true);          return false;      } -    char* po = strtok(NULL, " "); -    float o; - -    if (po) +    char* pitem  = extractKeyFromLink((char*)args,"Hitem"); +    if (!pitem)      { -        o = (float)atof(po); +        SendSysMessage(LANG_COMMAND_NEEDITEMSEND); +        SetSentErrorMessage(true); +        return false;      } -    else +    uint32 itemId = atol(pitem); + +    if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))      { -        Player *chr = m_session->GetPlayer(); -        o = chr->GetOrientation(); +        PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); +        SetSentErrorMessage(true); +        return false;      } -    float rot2 = sin(o/2); -    float rot3 = cos(o/2); - -    Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); -    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); - -    map->Add(obj); - -    obj->SaveToDB(); -    obj->Refresh(); - -    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o); +    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId); +    PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);      return true;  } -//move selected creature -bool ChatHandler::HandleNpcMoveCommand(const char* args) +//add move for creature +bool ChatHandler::HandleNpcAddMoveCommand(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; +    if(!*args) +        return false; -        uint32 lowguid = atoi(cId); +    char* guid_str = strtok((char*)args, " "); +    char* wait_str = strtok((char*)NULL, " "); -        /* FIXME: impossibel without entry -        if(lowguid) -            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); -        */ +    uint32 lowguid = atoi((char*)guid_str); -        // 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; -            } +    Creature* pCreature = NULL; -            uint32 map_id = data->mapid; +    /* FIXME: impossible without entry +    if(lowguid) +        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); +    */ -            if(m_session->GetPlayer()->GetMapId()!=map_id) -            { -                PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); -                SetSentErrorMessage(true); -                return false; -            } -        } -        else +    // attempt check creature existence by DB data +    if(!pCreature) +    { +        CreatureData const* data = objmgr.GetCreatureData(lowguid); +        if(!data)          { -            lowguid = pCreature->GetDBTableGUIDLow(); +            PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); +            SetSentErrorMessage(true); +            return false;          }      }      else      { +        // obtain real GUID for DB operations          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(); +    int wait = wait_str ? atoi(wait_str) : 0; -    if (pCreature) +    if(wait < 0) +        wait = 0; + +    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(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->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);          pCreature->GetMotionMaster()->Initialize();          if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn          {              pCreature->setDeathState(JUST_DIED);              pCreature->Respawn();          } +        pCreature->SaveToDB();      } -    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); +    SendSysMessage(LANG_WAYPOINT_ADDED); +      return true;  } -//move selected object -bool ChatHandler::HandleMoveObjectCommand(const char* args) +//change level of creature or pet +bool ChatHandler::HandleNpcChangeLevelCommand(const char* args)  { -    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r -    char* cId = extractKeyFromLink((char*)args,"Hgameobject"); -    if(!cId) +    if (!*args)          return false; -    uint32 lowguid = atoi(cId); -    if(!lowguid) +    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; +    } -    GameObject* obj = NULL; - -    // by DB guid -    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid)) -        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id); - -    if(!obj) +    Creature* pCreature = getSelectedCreature(); +    if(!pCreature)      { -        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid); +        SendSysMessage(LANG_SELECT_CREATURE);          SetSentErrorMessage(true);          return false;      } -    char* px = strtok(NULL, " "); -    char* py = strtok(NULL, " "); -    char* pz = strtok(NULL, " "); - -    if (!px) +    if(pCreature->isPet())      { -        Player *chr = m_session->GetPlayer(); - -        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); -        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); +        ((Pet*)pCreature)->GivePetLevel(lvl);      }      else      { -        if(!py || !pz) -            return false; - -        float x = (float)atof(px); -        float y = (float)atof(py); -        float z = (float)atof(pz); - -        if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z)) -        { -            PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId()); -            SetSentErrorMessage(true); -            return false; -        } - -        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj); -        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); +        pCreature->SetMaxHealth( 100 + 30*lvl); +        pCreature->SetHealth( 100 + 30*lvl); +        pCreature->SetLevel( lvl); +        pCreature->SaveToDB();      } -    obj->SaveToDB(); -    obj->Refresh(); - -    PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow()); -      return true;  } -//demorph player or unit -bool ChatHandler::HandleDeMorphCommand(const char* /*args*/) -{ -    Unit *target = getSelectedUnit(); -    if(!target) -        target = m_session->GetPlayer(); - -    target->DeMorph(); - -    return true; -} - -//add item in vendorlist -bool ChatHandler::HandleAddVendorItemCommand(const char* args) +//set npcflag of creature +bool ChatHandler::HandleNpcFlagCommand(const char* args)  {      if (!*args)          return false; -    char* pitem  = extractKeyFromLink((char*)args,"Hitem"); -    if (!pitem) -    { -        SendSysMessage(LANG_COMMAND_NEEDITEMSEND); -        SetSentErrorMessage(true); -        return false; -    } - -    uint32 itemId = atol(pitem); - -    char* fmaxcount = strtok(NULL, " ");                    //add maxcount, default: 0 -    uint32 maxcount = 0; -    if (fmaxcount) -        maxcount = atol(fmaxcount); - -    char* fincrtime = strtok(NULL, " ");                    //add incrtime, default: 0 -    uint32 incrtime = 0; -    if (fincrtime) -        incrtime = atol(fincrtime); - -    char* fextendedcost = strtok(NULL, " ");                //add ExtendedCost, default: 0 -    uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; - -    Creature* vendor = getSelectedCreature(); +    uint32 npcFlags = (uint32) atoi((char*)args); -    uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; +    Creature* pCreature = getSelectedCreature(); -    if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer())) +    if(!pCreature)      { +        SendSysMessage(LANG_SELECT_CREATURE);          SetSentErrorMessage(true);          return false;      } -    objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost); +    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); -    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId); +    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); + +    SendSysMessage(LANG_VALUE_SAVED_REJOIN); -    PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);      return true;  } -//del item from vendor list -bool ChatHandler::HandleDelVendorItemCommand(const char* args) +bool ChatHandler::HandleNpcDeleteCommand(const char* args)  { -    if (!*args) -        return false; +    Creature* unit = NULL; -    Creature* vendor = getSelectedCreature(); -    if (!vendor || !vendor->isVendor()) +    if(*args)      { -        SendSysMessage(LANG_COMMAND_VENDORSELECTION); -        SetSentErrorMessage(true); -        return false; -    } +        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r +        char* cId = extractKeyFromLink((char*)args,"Hcreature"); +        if(!cId) +            return false; -    char* pitem  = extractKeyFromLink((char*)args,"Hitem"); -    if (!pitem) -    { -        SendSysMessage(LANG_COMMAND_NEEDITEMSEND); -        SetSentErrorMessage(true); -        return false; -    } -    uint32 itemId = atol(pitem); +        uint32 lowguid = atoi(cId); +        if(!lowguid) +            return false; +        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(); -    if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId)) +    if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())      { -        PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); +        SendSysMessage(LANG_SELECT_CREATURE);          SetSentErrorMessage(true);          return false;      } -    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId); +    // Delete the creature +    unit->CombatStop(); +    unit->DeleteFromDB(); +    unit->CleanupsBeforeDelete(); +    unit->AddObjectToRemoveList(); + +    SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); -    PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);      return true;  } -//add move for creature -bool ChatHandler::HandleNpcAddMoveCommand(const char* args) +//move selected creature +bool ChatHandler::HandleNpcMoveCommand(const char* args)  { -    if(!*args) -        return false; +    uint32 lowguid = 0; -    char* guid_str = strtok((char*)args, " "); -    char* wait_str = strtok((char*)NULL, " "); +    Creature* pCreature = getSelectedCreature(); -    uint32 lowguid = atoi((char*)guid_str); +    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; -    Creature* pCreature = NULL; +        uint32 lowguid = atoi(cId); -    /* FIXME: impossible without entry -    if(lowguid) -        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); -    */ +        /* FIXME: impossibel without entry +        if(lowguid) +            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); +        */ -    // attempt check creature existence by DB data -    if(!pCreature) -    { -        CreatureData const* data = objmgr.GetCreatureData(lowguid); -        if(!data) +        // Attempting creature load from DB data +        if(!pCreature)          { -            PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); -            SetSentErrorMessage(true); -            return false; +            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      { -        // obtain real GUID for DB operations          lowguid = pCreature->GetDBTableGUIDLow();      } -    int wait = wait_str ? atoi(wait_str) : 0; - -    if(wait < 0) -        wait = 0; - -    Player* player = m_session->GetPlayer(); +    float x = m_session->GetPlayer()->GetPositionX(); +    float y = m_session->GetPlayer()->GetPositionY(); +    float z = m_session->GetPlayer()->GetPositionZ(); +    float o = m_session->GetPlayer()->GetOrientation(); -    // update movement type -    WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); -    if(pCreature && pCreature->GetWaypointPath()) +    if (pCreature)      { -        pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); +        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();          } -        pCreature->SaveToDB();      } +    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: @@ -1502,6 +1563,10 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)      else          return false; +    // update movement type +    //if(doNotDelete == false) +    //    WaypointMgr.DeletePath(lowguid); +      if(pCreature)      {          // update movement type @@ -1527,23 +1592,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); @@ -1551,126 +1642,441 @@ bool ChatHandler::HandleChangeLevelCommand(const char* args)          return false;      } -    if(pCreature->isPet()) +    pCreature->setFaction(factionId); + +    // faction is set in creature_template - not inside creature + +    // update in memory +    if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())      { -        ((Pet*)pCreature)->GivePetLevel(lvl); +        const_cast<CreatureInfo*>(cinfo)->faction_A = factionId; +        const_cast<CreatureInfo*>(cinfo)->faction_H = factionId; +    } + +    // and DB +    WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry()); + +    return true; +} +//set spawn dist of creature +bool ChatHandler::HandleNpcSpawnDistCommand(const char* args) +{ +    if(!*args) +        return false; + +    float option = atof((char*)args); +    if (option < 0.0f) +    { +        SendSysMessage(LANG_BAD_VALUE); +        return false;      } + +    MovementGeneratorType mtype = IDLE_MOTION_TYPE; +    if (option >0.0f) +        mtype = RANDOM_MOTION_TYPE; + +    Creature *pCreature = getSelectedCreature(); +    uint32 u_guidlow = 0; + +    if (pCreature) +        u_guidlow = pCreature->GetDBTableGUIDLow();      else +        return false; + +    pCreature->SetRespawnRadius((float)option); +    pCreature->SetDefaultMovementType(mtype); +    pCreature->GetMotionMaster()->Initialize(); +    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn      { -        pCreature->SetMaxHealth( 100 + 30*lvl); -        pCreature->SetHealth( 100 + 30*lvl); -        pCreature->SetLevel( lvl); -        pCreature->SaveToDB(); +        pCreature->setDeathState(JUST_DIED); +        pCreature->Respawn();      } +    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); +    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);      return true;  } - -//set npcflag of creature -bool ChatHandler::HandleNpcFlagCommand(const char* args) +//spawn time handling +bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)  { -    if (!*args) +    if(!*args)          return false; -    uint32 npcFlags = (uint32) atoi((char*)args); +    char* stime = strtok((char*)args, " "); -    Creature* pCreature = getSelectedCreature(); +    if (!stime) +        return false; -    if(!pCreature) +    int i_stime = atoi((char*)stime); + +    if (i_stime < 0)      { -        SendSysMessage(LANG_SELECT_CREATURE); +        SendSysMessage(LANG_BAD_VALUE);          SetSentErrorMessage(true);          return false;      } -    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); +    Creature *pCreature = getSelectedCreature(); +    uint32 u_guidlow = 0; -    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); +    if (pCreature) +        u_guidlow = pCreature->GetDBTableGUIDLow(); +    else +        return false; -    SendSysMessage(LANG_VALUE_SAVED_REJOIN); +    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); +    pCreature->SetRespawnDelay((uint32)i_stime); +    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);      return true;  } - -//set model of creature -bool ChatHandler::HandleNpcSetModelCommand(const char* args) +//npc follow handling +bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)  { -    if (!*args) +    Player *player = m_session->GetPlayer(); +    Creature *creature = getSelectedCreature(); + +    if(!creature) +    { +        PSendSysMessage(LANG_SELECT_CREATURE); +        SetSentErrorMessage(true);          return false; +    } -    uint32 displayId = (uint32) atoi((char*)args); +    // Follow player - Using pet's default dist and angle +    creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); -    Creature *pCreature = getSelectedCreature(); +    PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); +    return true; +} +//npc unfollow handling +bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) +{ +    Player *player = m_session->GetPlayer(); +    Creature *creature = getSelectedCreature(); -    if(!pCreature || pCreature->isPet()) +    if(!creature)      { -        SendSysMessage(LANG_SELECT_CREATURE); +        PSendSysMessage(LANG_SELECT_CREATURE);          SetSentErrorMessage(true);          return false;      } -    pCreature->SetDisplayId(displayId); -    pCreature->SetNativeDisplayId(displayId); +    if (/*creature->GetMotionMaster()->empty() ||*/ +        creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE) +    { +        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); +        SetSentErrorMessage(true); +        return false; +    } -    pCreature->SaveToDB(); +    TargetedMovementGenerator<Creature> const* mgen +        = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top())); +    if(mgen->GetTarget()!=player) +    { +        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); +        SetSentErrorMessage(true); +        return false; +    } + +    // reset movement +    creature->GetMotionMaster()->MovementExpired(true); + +    PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());      return true;  } +//npc tame handling +bool ChatHandler::HandleNpcTameCommand(const char* /*args*/) +{ +    Creature *creatureTarget = getSelectedCreature (); +    if (!creatureTarget || creatureTarget->isPet ()) +    { +        PSendSysMessage (LANG_SELECT_CREATURE); +        SetSentErrorMessage (true); +        return false; +    } -//morph creature or player -bool ChatHandler::HandleMorphCommand(const char* args) +    Player *player = m_session->GetPlayer (); + +    if(player->GetPetGUID ()) +    { +        SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); +        SetSentErrorMessage (true); +        return false; +    } + +    CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); + +    if (!cInfo->isTameable ()) +    { +        PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); +        SetSentErrorMessage (true); +        return false; +    } + +    // Everything looks OK, create new pet +    Pet* pet = player->CreateTamedPetFrom (creatureTarget); +    if (!pet) +    { +        PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); +        SetSentErrorMessage (true); +        return false; +    } + +    // place pet before player +    float x,y,z; +    player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); +    pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); + +    // set pet to defensive mode by default (some classes can't control controlled pets in fact). +    pet->SetReactState(REACT_DEFENSIVE); + +    // calculate proper level +    uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); + +    // prepare visual effect for levelup +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); + +    // add to world +    pet->GetMap()->Add((Creature*)pet); + +    // visual effect for levelup +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); + +    // caster have pet now +    player->SetPet(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;  } @@ -1688,7 +2094,7 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)          kicker = m_session->GetPlayer()->GetName();      if(!kickName) -     { +    {          Player* player = getSelectedPlayer();          if(!player)          { @@ -1704,14 +2110,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());          } @@ -1719,8 +2127,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); @@ -1742,34 +2150,56 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)              return false;          } -        if(m_session && player->GetSession()->GetSecurity() > m_session->GetSecurity()) +		if(HasLowerSecurity(player, 0))          {              SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); //maybe replacement string for this later on              SetSentErrorMessage(true);              return false;          } -        if(sWorld.KickPlayer(name.c_str())) +        std::string nameLink = playerLink(name); +	 +		if(sWorld.KickPlayer(name))          {              if(sWorld.getConfig(CONFIG_SHOW_KICK_IN_WORLD) == 1)              { - -                sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str()); +				sWorld.SendWorldText(LANG_COMMAND_KICKMESSAGE, nameLink.c_str(), kicker.c_str(), reason.c_str());              }              else              { -                PSendSysMessage(LANG_COMMAND_KICKMESSAGE, name.c_str(), kicker.c_str(), reason.c_str()); +				PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());              }          }          else          { -            PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER, name.c_str()); +		    PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());              return false;          }      }      return true;  } +//set temporary phase mask for player +bool ChatHandler::HandleModifyPhaseCommand(const char* args) +{ +    if (!*args) +        return false; + +    uint32 phasemask = (uint32)atoi((char*)args); + +    Unit *target = getSelectedUnit(); +    if(!target) +        target = m_session->GetPlayer(); + +    // check online security +    else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) +        return false; + +    target->SetPhaseMask(phasemask,true); + +    return true; +} +  //show info of player  bool ChatHandler::HandlePInfoCommand(const char* args)  { @@ -1783,12 +2213,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      if (px)      { -        name = px; - +        name = extractPlayerNameFromLink(px);          if(name.empty()) -            return false; - -        if(!normalizePlayerName(name))          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -1829,6 +2255,10 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      // get additional information from Player object      if(target)      { +        // check online security +        if (HasLowerSecurity(target, 0)) +            return false; +          targetGUID = target->GetGUID();          name = target->GetName();                           // re-read for case getSelectedPlayer() target          accId = target->GetSession()->GetAccountId(); @@ -1840,6 +2270,11 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      // get additional information from DB      else      { +        // check offline security +        if (HasLowerSecurity(NULL, targetGUID)) +            return false; + +        //                                                     0          QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));          if (!result)          { @@ -1890,7 +2325,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)          delete result;      } -    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency); +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);      std::string timeStr = secsToTimeString(total_player_time,true,true);      uint32 gold = money /GOLD; @@ -1908,18 +2345,14 @@ bool ChatHandler::HandlePInfoCommand(const char* args)              return false;          } -        char* FactionName;          for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)          {              FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); -            if (factionEntry) -                FactionName = factionEntry->name[m_session->GetSessionDbcLocale()]; -            else -                FactionName = "#Not found#"; +            char const* factionName = factionEntry ? factionEntry->name[m_session->GetSessionDbcLocale()] : "#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) << ")"; +            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); @@ -1940,81 +2373,215 @@ bool ChatHandler::HandlePInfoCommand(const char* args)      return true;  } -//set spawn dist of creature -bool ChatHandler::HandleNpcSpawnDistCommand(const char* args) +/*//show tickets +void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)  { -    if(!*args) -        return false; +    std::string name; +    if(!objmgr.GetPlayerNameByGUID(guid,name)) +        name = GetTrinityString(LANG_UNKNOWN); -    float option = atof((char*)args); -    if (option < 0.0f) +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_COMMAND_TICKETVIEW, nameLink.c_str(),time,text); +} + +//ticket commands +bool ChatHandler::HandleTicketCommand(const char* args) +{ +    char* px = strtok((char*)args, " "); + +    // ticket<end> +    if (!px)      { -        SendSysMessage(LANG_BAD_VALUE); -        return false; +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } + +        size_t count = ticketmgr.GetTicketCount(); + +        bool accept = m_session->GetPlayer()->isAcceptTickets(); + +        PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ?  GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF)); +        return true;      } -    MovementGeneratorType mtype = IDLE_MOTION_TYPE; -    if (option >0.0f) -        mtype = RANDOM_MOTION_TYPE; +    // ticket on +    if(strncmp(px,"on",3) == 0) +    { +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } -    Creature *pCreature = getSelectedCreature(); -    uint32 u_guidlow = 0; +        m_session->GetPlayer()->SetAcceptTicket(true); +        SendSysMessage(LANG_COMMAND_TICKETON); +        return true; +    } -    if (pCreature) -        u_guidlow = pCreature->GetDBTableGUIDLow(); -    else -        return false; +    // ticket off +    if(strncmp(px,"off",4) == 0) +    { +        if(!m_session) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } -    pCreature->SetRespawnRadius((float)option); -    pCreature->SetDefaultMovementType(mtype); -    pCreature->GetMotionMaster()->Initialize(); -    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn +        m_session->GetPlayer()->SetAcceptTicket(false); +        SendSysMessage(LANG_COMMAND_TICKETOFF); +        return true; +    } + +    // ticket #num +    int num = atoi(px); +    if(num > 0)      { -        pCreature->setDeathState(JUST_DIED); -        pCreature->Respawn(); +        QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1); + +        if(!result) +        { +            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); +            SetSentErrorMessage(true); +            return false; +        } + +        Field* fields = result->Fetch(); + +        uint32 guid = fields[0].GetUInt32(); +        char const* text = fields[1].GetString(); +        char const* time = fields[2].GetString(); + +        ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time); +        delete result; +        return true;      } -    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); -    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option); +    std::string name = extractPlayerNameFromLink(px); +    if(name.empty()) +    { +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true); +        return false; +    } + +    uint64 guid = objmgr.GetPlayerGUIDByName(name); + +    if(!guid) +        return false; + +    // ticket $char_name +    GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid)); +    if(!ticket) +        return false; + +    std::string time = TimeToTimestampStr(ticket->GetLastUpdate()); + +    ShowTicket(guid, ticket->GetText(), time.c_str()); +      return true;  } -bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args) +//dell all tickets +bool ChatHandler::HandleDelTicketCommand(const char *args)  { -    if(!*args) +    char* px = strtok((char*)args, " "); +    if (!px)          return false; -    char* stime = strtok((char*)args, " "); +    // delticket all +    if(strncmp(px,"all",4) == 0) +    { +        ticketmgr.DeleteAll(); +        SendSysMessage(LANG_COMMAND_ALLTICKETDELETED); +        return true; +    } -    if (!stime) -        return false; +    int num = (uint32)atoi(px); -    int i_stime = atoi((char*)stime); +    // delticket #num +    if(num > 0) +    { +        QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1); +        if(!result) +        { +            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); +            SetSentErrorMessage(true); +            return false; +        } +        Field* fields = result->Fetch(); +        uint32 guid = fields[0].GetUInt32(); +        delete result; -    if (i_stime < 0) +        ticketmgr.Delete(guid); + +        //notify player +        if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER))) +        { +            pl->GetSession()->SendGMTicketGetTicket(0x0A, 0); +            PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, GetNameLink(pl).c_str()); +        } +        else +            PSendSysMessage(LANG_COMMAND_TICKETDEL); + +        return true; +    } + +    std::string name = extractPlayerNameFromLink(px); +    if(name.empty())      { -        SendSysMessage(LANG_BAD_VALUE); +        SendSysMessage(LANG_PLAYER_NOT_FOUND);          SetSentErrorMessage(true);          return false;      } -    Creature *pCreature = getSelectedCreature(); -    uint32 u_guidlow = 0; +    uint64 guid = objmgr.GetPlayerGUIDByName(name); -    if (pCreature) -        u_guidlow = pCreature->GetDBTableGUIDLow(); -    else +    if(!guid)          return false; -    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); -    pCreature->SetRespawnDelay((uint32)i_stime); -    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime); +    // delticket $char_name +    ticketmgr.Delete(GUID_LOPART(guid)); + +    // notify players about ticket deleting +    if(Player* sender = objmgr.GetPlayer(guid)) +        sender->GetSession()->SendGMTicketGetTicket(0x0A,0); +    std::string nameLink = playerLink(name); + +    PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());      return true; -} +}*/ +  /////WAYPOINT COMMANDS +/** + * Add a waypoint to a creature. + * + * The user can either select an npc or provide its GUID. + * + * The user can even select a visual waypoint - then the new waypoint + * is placed *after* the selected one - this makes insertion of new + * waypoints possible. + * + * eg: + * .wp add 12345 + * -> adds a waypoint to the npc with the GUID 12345 + * + * .wp add + * -> adds a waypoint to the currently selected creature + * + * + * @param args if the user did not provide a GUID, it is NULL + * + * @return true - command did succeed, false - something went wrong + */  bool ChatHandler::HandleWpAddCommand(const char* args)  {      sLog.outDebug("DEBUG: HandleWpAddCommand"); @@ -2134,7 +2701,7 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)      target->LoadPath(pathid);      target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);      target->GetMotionMaster()->Initialize(); -    target->Say("Path loaded.",0,0); +    target->MonsterSay("Path loaded.",0,0);      return true;  } @@ -2177,7 +2744,7 @@ bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)              target->SetDefaultMovementType(IDLE_MOTION_TYPE);              target->GetMotionMaster()->MoveTargetedHome();              target->GetMotionMaster()->Initialize(); -            target->Say("Path unloaded.",0,0); +            target->MonsterSay("Path unloaded.",0,0);              return true;          }          PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path."); @@ -2569,7 +3136,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)                  wpCreature->AddObjectToRemoveList();                  // re-create                  Creature* wpCreature2 = new Creature; -                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0)) +                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))                  {                      PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);                      delete wpCreature2; @@ -2579,12 +3146,12 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)                  if(!wpCreature2->IsPositionValid())                  { -                    sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY()); +                    sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());                      delete wpCreature2;                      return false;                  } -                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());                  // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();                  wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);                  map->Add(wpCreature2); @@ -2618,7 +3185,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)      }      PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); -      return true;  } @@ -2800,7 +3366,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              float o = chr->GetOrientation();              Creature* wpCreature = new Creature; -            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) +            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))              {                  PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);                  delete wpCreature; @@ -2812,7 +3378,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              if(!wpCreature->IsPositionValid())              { -                sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY()); +                sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());                  delete wpCreature;                  delete result;                  return false; @@ -2822,7 +3388,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args)              // set "wpguid" column to the visual waypoint              WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point); -            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); +            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();              wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);              map->Add(wpCreature); @@ -2863,7 +3430,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          Map *map = chr->GetMap();          Creature* pCreature = new Creature; -        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0)) +        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))          {              PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);              delete pCreature; @@ -2875,13 +3442,13 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          if(!pCreature->IsPositionValid())          { -            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); +            sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());              delete pCreature;              delete result;              return false;          } -        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());          pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);          map->Add(pCreature); @@ -2928,7 +3495,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          Map *map = chr->GetMap();          Creature* pCreature = new Creature; -        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) +        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))          {              PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);              delete pCreature; @@ -2940,13 +3507,13 @@ bool ChatHandler::HandleWpShowCommand(const char* args)          if(!pCreature->IsPositionValid())          { -            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY()); +            sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());              delete pCreature;              delete result;              return false;          } -        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); +        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());          pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);          map->Add(pCreature); @@ -3028,9 +3595,8 @@ bool ChatHandler::HandleRenameCommand(const char* args)      if(px)      { -        oldname = px; - -        if(!normalizePlayerName(oldname)) +        oldname = extractPlayerNameFromLink(px); +        if(oldname.empty())          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -3057,93 +3623,85 @@ bool ChatHandler::HandleRenameCommand(const char* args)      if(target)      { -        PSendSysMessage(LANG_RENAME_PLAYER, target->GetName()); +        // check online security +        if (HasLowerSecurity(target, 0)) +            return false; + +        PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());          target->SetAtLoginFlag(AT_LOGIN_RENAME);          CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());      }      else      { -        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID)); +        // check offline security +        if (HasLowerSecurity(NULL, targetGUID)) +            return false; + +        std::string oldNameLink = playerLink(oldname); + +        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));          CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));      }      return true;  } -//spawn go -bool ChatHandler::HandleGameObjectCommand(const char* args) +// customize characters +bool ChatHandler::HandleCustomizeCommand(const char* args)  { -    if (!*args) -        return false; +    Player* target = NULL; +    uint64 targetGUID = 0; +    std::string oldname; -    char* pParam1 = strtok((char*)args, " "); -    if (!pParam1) -        return false; +    char* px = strtok((char*)args, " "); -    uint32 id = atoi((char*)pParam1); -    if(!id) -        return false; +    if(px) +    { +        oldname = extractPlayerNameFromLink(px); +        if(oldname.empty()) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } -    char* spawntimeSecs = strtok(NULL, " "); +        target = objmgr.GetPlayer(oldname.c_str()); -    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id); +        if (!target) +            targetGUID = objmgr.GetPlayerGUIDByName(oldname); +    } -    if (!goI) +    if(!target && !targetGUID)      { -        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id); -        SetSentErrorMessage(true); -        return false; +        target = getSelectedPlayer();      } -    Player *chr = m_session->GetPlayer(); -    float x = float(chr->GetPositionX()); -    float y = float(chr->GetPositionY()); -    float z = float(chr->GetPositionZ()); -    float o = float(chr->GetOrientation()); -    Map *map = chr->GetMap(); - -    float rot2 = sin(o/2); -    float rot3 = cos(o/2); - -    GameObject* pGameObj = new GameObject; -    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); - -    if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1)) +    if(!target && !targetGUID)      { -        delete pGameObj; +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true);          return false;      } -    if( spawntimeSecs ) +    if(target)      { -        uint32 value = atoi((char*)spawntimeSecs); -        pGameObj->SetRespawnTime(value); -        //sLog.outDebug("*** spawntimeSecs: %d", value); +        PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); +        target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());      } - -    // fill the gameobject data and save to the db -    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); - -    // this will generate a new guid if the object is in an instance -    if(!pGameObj->LoadFromDB(db_lowGUID, map)) +    else      { -        delete pGameObj; -        return false; -    } - -    sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o); +        std::string oldNameLink = playerLink(oldname); -    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_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID)); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); +    } -    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);      return true;  }  //show animation -bool ChatHandler::HandleAnimCommand(const char* args) +bool ChatHandler::HandleDebugAnimCommand(const char* args)  {      if (!*args)          return false; @@ -3154,7 +3712,7 @@ bool ChatHandler::HandleAnimCommand(const char* args)  }  //change standstate -bool ChatHandler::HandleStandStateCommand(const char* args) +bool ChatHandler::HandleModifyStandStateCommand(const char* args)  {      if (!*args)          return false; @@ -3165,7 +3723,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; @@ -3178,6 +3736,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; @@ -3193,11 +3755,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) @@ -3207,6 +3773,10 @@ bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      target->UpdateHonorFields();      return true;  } @@ -3227,8 +3797,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 )      { @@ -3261,12 +3831,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]; @@ -3297,7 +3867,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())      { @@ -3314,7 +3884,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) : ""; @@ -3346,7 +3916,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())      { @@ -3363,7 +3933,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); @@ -3387,7 +3957,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())      { @@ -3404,7 +3974,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())      { @@ -3423,9 +3993,8 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)      if(*args)      { -        std::string playername = args; - -        if(!normalizePlayerName(playername)) +        std::string playername = extractPlayerNameFromLink((char*)args); +        if(playername.empty())          {              SendSysMessage(LANG_PLAYER_NOT_FOUND);              SetSentErrorMessage(true); @@ -3449,6 +4018,10 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)              player = m_session->GetPlayer();      } +    // check online security +    if (HasLowerSecurity(player, 0)) +        return false; +      player->CombatStop();      player->getHostilRefManager().deleteReferences();      return true; @@ -3487,7 +4060,7 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)                  if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))                      continue; -                m_session->GetPlayer()->learnSpell(skillLine->spellId); +                m_session->GetPlayer()->learnSpell(skillLine->spellId,false);              }          }      } @@ -3560,7 +4133,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)                      continue;                  if( !target->HasSpell(spellInfo->Id) ) -                    m_session->GetPlayer()->learnSpell(skillLine->spellId); +                    m_session->GetPlayer()->learnSpell(skillLine->spellId,false);              }              uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id); @@ -3688,68 +4261,50 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)          return false;      } +    // check online security +    if (HasLowerSecurity(target, 0)) +        return false; +      // Repair items      target->DurabilityRepairAll(false, 0, false); -    PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName()); +    PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());      if(needReportToTarget(target)) -        ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName()); +        ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());      return true;  } -bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/) +bool ChatHandler::HandleWaterwalkCommand(const char* args)  { -    Player *player = m_session->GetPlayer(); -    Creature *creature = getSelectedCreature(); - -    if(!creature) -    { -        PSendSysMessage(LANG_SELECT_CREATURE); -        SetSentErrorMessage(true); +    if(!*args)          return false; -    } -    // Follow player - Using pet's default dist and angle -    creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); +    Player *player = getSelectedPlayer(); -    PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); -    return true; -} - -bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) -{ -    Player *player = m_session->GetPlayer(); -    Creature *creature = getSelectedCreature(); - -    if(!creature) +    if(!player)      { -        PSendSysMessage(LANG_SELECT_CREATURE); +        PSendSysMessage(LANG_NO_CHAR_SELECTED);          SetSentErrorMessage(true);          return false;      } -    if (/*creature->GetMotionMaster()->empty() ||*/ -        creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE) -    { -        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); -        SetSentErrorMessage(true); +    // check online security +    if (HasLowerSecurity(player, 0))          return false; -    } -    TargetedMovementGenerator<Creature> const* mgen -        = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top())); - -    if(mgen->GetTarget()!=player) +    if (strncmp(args, "on", 3) == 0) +        player->SetMovement(MOVE_WATER_WALK);               // ON +    else if (strncmp(args, "off", 4) == 0) +        player->SetMovement(MOVE_LAND_WALK);                // OFF +    else      { -        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); -        SetSentErrorMessage(true); +        SendSysMessage(LANG_USE_BOL);          return false;      } -    // reset movement -    creature->GetMotionMaster()->MovementExpired(true); - -    PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName()); +    PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str()); +    if(needReportToTarget(player)) +        ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());      return true;  } @@ -3820,7 +4375,7 @@ bool ChatHandler::HandleCreatePetCommand(const char* args)       // visual effect for levelup       pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); -     player->SetPet(pet); +     player->SetPet(pet, true);       pet->SavePetToDB(PET_SAVE_AS_CURRENT);       player->PetSpellInitialize(); @@ -3912,7 +4467,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; @@ -4053,4 +4608,3 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)      return true;   } -  | 
