Index: trunk/src/game/Object.cpp
===================================================================
--- trunk/src/game/Object.cpp (revision 19)
+++ trunk/src/game/Object.cpp (revision 28)
Index: trunk/src/game/Creature.h
===================================================================
--- trunk/src/game/Creature.h (revision 18)
+++ trunk/src/game/Creature.h (revision 28)
@@ -309,4 +309,5 @@
     bool RemoveItem( uint32 item_id );
     VendorItem const* FindItem(uint32 item_id) const;
+    size_t FindItemSlot(uint32 item_id) const;
 
     void Clear()
Index: trunk/src/game/SpellEffects.cpp
===================================================================
--- trunk/src/game/SpellEffects.cpp (revision 18)
+++ trunk/src/game/SpellEffects.cpp (revision 28)
@@ -1466,5 +1466,5 @@
                         return;
 
-                    if( !unitTarget->hasUnitState(UNIT_STAT_STUNDED) && m_caster->GetTypeId()==TYPEID_PLAYER)
+                    if( !unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER)
                     {
                         // decreased damage (/2) for non-stunned target.
@@ -3402,5 +3402,5 @@
 
     // target must be OK to do this
-    if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING ) )
+    if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING ) )
         return;
 
Index: trunk/src/game/Chat.h
===================================================================
--- trunk/src/game/Chat.h (revision 18)
+++ trunk/src/game/Chat.h (revision 28)
@@ -70,5 +70,5 @@
 
     protected:
-        bool hasStringAbbr(const char* s1, const char* s2);
+        bool hasStringAbbr(const char* name, const char* part);
         void SendGlobalSysMessage(const char *str);
 
@@ -95,4 +95,5 @@
         bool HandleNotifyCommand(const char* args);
         bool HandleGMmodeCommand(const char* args);
+        bool HandleGMChatCommand(const char* args);
         bool HandleVisibleCommand(const char* args);
         bool HandleGPSCommand(const char* args);
Index: trunk/src/game/PetHandler.cpp
===================================================================
--- trunk/src/game/PetHandler.cpp (revision 2)
+++ trunk/src/game/PetHandler.cpp (revision 28)
@@ -31,4 +31,5 @@
 #include "Util.h"
 #include "Pet.h"
+#include "Language.h"
 
 void WorldSession::HandlePetAction( WorldPacket & recv_data )
@@ -396,5 +397,5 @@
     if((!ObjectMgr::IsValidPetName(name)) || (objmgr.IsReservedName(name)))
     {
-        SendNotification("Invalid name");
+        SendNotification(LANG_PET_INVALID_NAME);
         return;
     }
@@ -416,5 +417,5 @@
         if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname,0),declinedname))
         {
-            SendNotification("Invalid name");
+            SendNotification(LANG_PET_INVALID_NAME);
             return;
         }
Index: trunk/src/game/Level1.cpp
===================================================================
--- trunk/src/game/Level1.cpp (revision 9)
+++ trunk/src/game/Level1.cpp (revision 28)
@@ -148,7 +148,9 @@
     if(!*args)
     {
-        SendSysMessage(LANG_USE_BOL);
-        SetSentErrorMessage(true);
-        return false;
+        if(m_session->GetPlayer()->isGameMaster())
+            m_session->SendNotification(LANG_GM_ON);
+        else
+            m_session->SendNotification(LANG_GM_OFF);
+        return true;
     }
 
@@ -158,5 +160,5 @@
     {
         m_session->GetPlayer()->SetGameMaster(true);
-        m_session->SendNotification("GM mode is ON");
+        m_session->SendNotification(LANG_GM_ON);
         #ifdef _DEBUG_VMAPS
         VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
@@ -169,5 +171,5 @@
     {
         m_session->GetPlayer()->SetGameMaster(false);
-        m_session->SendNotification("GM mode is OFF");
+        m_session->SendNotification(LANG_GM_OFF);
         #ifdef _DEBUG_VMAPS
         VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
@@ -182,4 +184,38 @@
 }
 
+// Enables or disables hiding of the staff badge
+bool ChatHandler::HandleGMChatCommand(const char* args)
+{
+    if(!*args)
+    {
+        if(m_session->GetPlayer()->isGMChat())
+            m_session->SendNotification(LANG_GM_CHAT_ON);
+        else
+            m_session->SendNotification(LANG_GM_CHAT_OFF);
+        return true;
+    }
+
+    std::string argstr = (char*)args;
+
+    if (argstr == "on")
+    {
+        m_session->GetPlayer()->SetGMChat(true);
+        m_session->SendNotification(LANG_GM_CHAT_ON);
+        return true;
+    }
+
+    if (argstr == "off")
+    {
+        m_session->GetPlayer()->SetGMChat(false);
+        m_session->SendNotification(LANG_GM_CHAT_OFF);
+        return true;
+    }
+
+    SendSysMessage(LANG_USE_BOL);
+    SetSentErrorMessage(true);
+    return false;
+}
+
+
 //Enable\Dissable Invisible mode
 bool ChatHandler::HandleVisibleCommand(const char* args)
@@ -196,5 +232,5 @@
     {
         m_session->GetPlayer()->SetGMVisible(true);
-        m_session->SendNotification(GetMangosString(LANG_INVISIBLE_VISIBLE));
+        m_session->SendNotification(LANG_INVISIBLE_VISIBLE);
         return true;
     }
@@ -202,5 +238,5 @@
     if (argstr == "off")
     {
-        m_session->SendNotification(GetMangosString(LANG_INVISIBLE_INVISIBLE));
+        m_session->SendNotification(LANG_INVISIBLE_INVISIBLE);
         m_session->GetPlayer()->SetGMVisible(false);
         return true;
@@ -1824,7 +1860,42 @@
         return false;
 
+    // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
+
     char* pName = strtok((char*)args, " ");
-    char* msgSubject = strtok(NULL, " ");
-    char* msgText = strtok(NULL, "");
+    if(!pName)
+        return false;
+
+    char* tail1 = strtok(NULL, "");
+    if(!tail1)
+        return false;
+
+    char* msgSubject;
+    if(*tail1=='"')
+        msgSubject = strtok(tail1+1, "\"");
+    else
+    {
+        char* space = strtok(tail1, "\"");
+        if(!space)
+            return false;
+        msgSubject = strtok(NULL, "\"");
+    }
+
+    if (!msgSubject)
+        return false;
+
+    char* tail2 = strtok(NULL, "");
+    if(!tail2)
+        return false;
+
+    char* msgText;
+    if(*tail2=='"')
+        msgText = strtok(tail2+1, "\"");
+    else
+    {
+        char* space = strtok(tail2, "\"");
+        if(!space)
+            return false;
+        msgText = strtok(NULL, "\"");
+    }
 
     if (!msgText)
@@ -1832,9 +1903,62 @@
 
     // pName, msgSubject, msgText isn't NUL after prev. check
-
     std::string name    = pName;
     std::string subject = msgSubject;
     std::string text    = msgText;
 
+    // extract items
+    typedef std::pair<uint32,uint32> ItemPair;
+    typedef std::list< ItemPair > ItemPairs;
+    ItemPairs items;
+
+    // get all tail string
+    char* tail = strtok(NULL, "");
+
+    // get from tail next item str
+    while(char* itemStr = strtok(tail, " "))
+    {
+        // and get new tail 
+        tail = strtok(NULL, "");
+
+        // parse item str
+        char* itemIdStr = strtok(itemStr, ":");
+        char* itemCountStr = strtok(NULL, " ");
+        
+        uint32 item_id = atoi(itemIdStr);
+        if(!item_id)
+            return false;
+
+        ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
+        if(!item_proto)
+        {
+            PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
+            SetSentErrorMessage(true);
+            return false;
+        }
+
+        uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
+        if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
+        {
+            PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
+            SetSentErrorMessage(true);
+            return false;
+        }
+
+        while(item_count > item_proto->Stackable)
+        {
+            items.push_back(ItemPair(item_id,item_proto->Stackable));
+            item_count -= item_proto->Stackable;
+        }
+
+        items.push_back(ItemPair(item_id,item_count));
+
+        if(items.size() > MAX_MAIL_ITEMS)
+        {
+            PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
+            SetSentErrorMessage(true);
+            return false;
+        }
+    }
+
     if(!normalizePlayerName(name))
     {
@@ -1845,7 +1969,10 @@
 
     uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
-
     if(!receiver_guid)
-        return false;
+    {
+        SendSysMessage(LANG_PLAYER_NOT_FOUND);
+        SetSentErrorMessage(true);
+        return false;
+    }
 
     uint32 mailId = objmgr.GenerateMailID();
@@ -1861,5 +1988,17 @@
     Player *receiver = objmgr.GetPlayer(receiver_guid);
 
-    WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
+    // fill mail
+    MailItemsInfo mi;                                       // item list preparing
+
+    for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
+    {
+        if(Item* item = Item::CreateItem(itr->first,itr->second,m_session->GetPlayer()))
+        {
+            item->SaveToDB();                               // save for prevent lost at next mail load, if send fail then item will deleted
+            mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
+        }
+    }
+
+    WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
 
     PSendSysMessage(LANG_MAIL_SENT, name.c_str());
Index: trunk/src/game/FleeingMovementGenerator.cpp
===================================================================
--- trunk/src/game/FleeingMovementGenerator.cpp (revision 2)
+++ trunk/src/game/FleeingMovementGenerator.cpp (revision 28)
@@ -33,5 +33,5 @@
         return;
 
-    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
+    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
         return;
 
@@ -339,5 +339,5 @@
     if( !&owner || !owner.isAlive() )
         return false;
-    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
+    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
         return true;
 
Index: trunk/src/game/WaypointMovementGenerator.cpp
===================================================================
--- trunk/src/game/WaypointMovementGenerator.cpp (revision 18)
+++ trunk/src/game/WaypointMovementGenerator.cpp (revision 28)
@@ -86,5 +86,5 @@
     // Waypoint movement can be switched on/off
     // This is quite handy for escort quests and other stuff
-    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
+    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
         return true;
 
Index: trunk/src/game/PetitionsHandler.cpp
===================================================================
--- trunk/src/game/PetitionsHandler.cpp (revision 2)
+++ trunk/src/game/PetitionsHandler.cpp (revision 28)
@@ -112,5 +112,5 @@
         if(_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
         {
-            SendNotification(GetMangosString(LANG_ARENA_ONE_TOOLOW), 70);
+            SendNotification(LANG_ARENA_ONE_TOOLOW, 70);
             return;
         }
@@ -531,5 +531,5 @@
     {
         // player is too low level to join an arena team
-        SendNotification("You must be level %u to join an arena team!",sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+        SendNotification(LANG_YOUR_ARENA_LEVEL_REQ_ERROR,sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
         return;
     }
Index: trunk/src/game/Chat.cpp
===================================================================
--- trunk/src/game/Chat.cpp (revision 18)
+++ trunk/src/game/Chat.cpp (revision 28)
@@ -354,4 +354,5 @@
     static ChatCommand gmCommandTable[] =
     {
+        { "chat",           SEC_MODERATOR,      &ChatHandler::HandleGMChatCommand,              "", NULL },
         { "list",           SEC_PLAYER,         &ChatHandler::HandleGMListCommand,              "", NULL },
         { "visible",        SEC_MODERATOR,      &ChatHandler::HandleVisibleCommand,             "", NULL },
@@ -508,16 +509,27 @@
 }
 
-bool ChatHandler::hasStringAbbr(const char* s1, const char* s2)
-{
-    for(;;)
-    {
-        if( !*s2 )
-            return true;
-        else if( !*s1 )
+bool ChatHandler::hasStringAbbr(const char* name, const char* part)
+{
+    // non "" command
+    if( *name )
+    {
+        // "" part from non-"" command
+        if( !*part )
             return false;
-        else if( tolower( *s1 ) != tolower( *s2 ) )
-            return false;
-        ++s1; ++s2;
-    }
+
+        for(;;)
+        {
+            if( !*part )
+                return true;
+            else if( !*name )
+                return false;
+            else if( tolower( *name ) != tolower( *part ) )
+                return false;
+            ++name; ++part;
+        }
+    }
+    // allow with any for ""
+
+    return true;
 }
 
@@ -595,11 +607,7 @@
     while (*text == ' ') ++text;
 
-    if(!cmd.length())
-        return false;
-
     for(uint32 i = 0; table[i].Name != NULL; i++)
     {
-        // allow pass "" command name in table
-        if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, cmd.c_str()))
+        if( !hasStringAbbr(table[i].Name, cmd.c_str()) )
             continue;
 
@@ -689,6 +697,5 @@
             continue;
 
-        if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, subcmd))
-            continue;
+        if( !hasStringAbbr(table[i].Name, subcmd) )
 
         (list += "\n    ") += table[i].Name;
@@ -718,5 +725,5 @@
                 continue;
 
-            if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, cmd))
+            if( !hasStringAbbr(table[i].Name, cmd) )
                 continue;
 
Index: trunk/src/game/ConfusedMovementGenerator.cpp
===================================================================
--- trunk/src/game/ConfusedMovementGenerator.cpp (revision 2)
+++ trunk/src/game/ConfusedMovementGenerator.cpp (revision 28)
@@ -102,5 +102,5 @@
         return true;
 
-    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
+    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
         return true;
 
Index: trunk/src/game/ArenaTeamHandler.cpp
===================================================================
--- trunk/src/game/ArenaTeamHandler.cpp (revision 2)
+++ trunk/src/game/ArenaTeamHandler.cpp (revision 28)
@@ -26,4 +26,5 @@
 #include "World.h"
 #include "SocialMgr.h"
+#include "Language.h"
 
 void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
@@ -118,5 +119,5 @@
         //SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S);
                                                             // can't find related opcode
-        SendNotification("%s is not high enough level to join your team", player->GetName());
+        SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName());
         return;
     }
@@ -155,5 +156,5 @@
         // should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL
 //        SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL);
-        SendNotification("Your arena team is full, %s cannot join it.", player->GetName());
+        SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName());
         return;
     }
Index: trunk/src/game/Player.h
===================================================================
--- trunk/src/game/Player.h (revision 18)
+++ trunk/src/game/Player.h (revision 28)
@@ -497,4 +497,5 @@
     PLAYER_EXTRA_TAXICHEAT          = 0x0008,
     PLAYER_EXTRA_GM_INVISIBLE       = 0x0010,
+    PLAYER_EXTRA_GM_CHAT            = 0x0020,               // Show GM badge in chat messages
 
     // other states
@@ -955,4 +956,6 @@
         bool isGameMaster() const { return m_ExtraFlags & PLAYER_EXTRA_GM_ON; }
         void SetGameMaster(bool on);
+        bool isGMChat() const { return GetSession()->GetSecurity() >= SEC_MODERATOR && (m_ExtraFlags & PLAYER_EXTRA_GM_CHAT); }
+        void SetGMChat(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_GM_CHAT; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_CHAT; }
         bool isTaxiCheater() const { return m_ExtraFlags & PLAYER_EXTRA_TAXICHEAT; }
         void SetTaxiCheater(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; }
Index: trunk/src/game/HomeMovementGenerator.cpp
===================================================================
--- trunk/src/game/HomeMovementGenerator.cpp (revision 2)
+++ trunk/src/game/HomeMovementGenerator.cpp (revision 28)
@@ -44,5 +44,5 @@
         return;
 
-    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
+    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
         return;
 
Index: trunk/src/game/TradeHandler.cpp
===================================================================
--- trunk/src/game/TradeHandler.cpp (revision 2)
+++ trunk/src/game/TradeHandler.cpp (revision 28)
@@ -27,4 +27,5 @@
 #include "Item.h"
 #include "SocialMgr.h"
+#include "Language.h"
 
 enum TradeStatus
@@ -256,5 +257,5 @@
     if( _player->tradeGold > _player->GetMoney() )
     {
-        SendNotification( "You do not have enough gold" );
+        SendNotification(LANG_NOT_ENOUGH_GOLD);
         _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
         _player->acceptTrade = false;
@@ -265,5 +266,5 @@
     if( _player->pTrader->tradeGold > _player->pTrader->GetMoney() )
     {
-        _player->pTrader->GetSession( )->SendNotification( "You do not have enough gold" );
+        _player->pTrader->GetSession( )->SendNotification(LANG_NOT_ENOUGH_GOLD);
         SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
         _player->pTrader->acceptTrade = false;
@@ -339,6 +340,6 @@
         if(!myCanCompleteTrade)
         {
-            SendNotification("You do not have enough free slots");
-            GetPlayer( )->pTrader->GetSession( )->SendNotification("Your partner does not have enough free bag slots");
+            SendNotification(LANG_NOT_FREE_TRADE_SLOTS);
+            GetPlayer( )->pTrader->GetSession( )->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS);
             SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
             _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
@@ -347,6 +348,6 @@
         else if (!hisCanCompleteTrade)
         {
-            SendNotification("Your partner does not have enough free bag slots");
-            GetPlayer()->pTrader->GetSession()->SendNotification("You do not have enough free slots");
+            SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS);
+            GetPlayer()->pTrader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS);
             SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
             _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
@@ -462,5 +463,5 @@
     }
 
-    if( GetPlayer()->hasUnitState(UNIT_STAT_STUNDED) )
+    if( GetPlayer()->hasUnitState(UNIT_STAT_STUNNED) )
     {
         SendTradeStatus(TRADE_STATUS_YOU_STUNNED);
@@ -508,5 +509,5 @@
     }
 
-    if( pOther->hasUnitState(UNIT_STAT_STUNDED) )
+    if( pOther->hasUnitState(UNIT_STAT_STUNNED) )
     {
         SendTradeStatus(TRADE_STATUS_TARGET_STUNNED);
Index: trunk/src/game/AggressorAI.cpp
===================================================================
--- trunk/src/game/AggressorAI.cpp (revision 6)
+++ trunk/src/game/AggressorAI.cpp (revision 28)
@@ -48,5 +48,5 @@
         return;
     
-    if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNDED) && u->isTargetableForAttack() &&
+    if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
         ( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
         u->isInAccessablePlaceFor(&i_creature) )
Index: trunk/src/game/GridNotifiers.h
===================================================================
--- trunk/src/game/GridNotifiers.h (revision 13)
+++ trunk/src/game/GridNotifiers.h (revision 28)
@@ -853,5 +853,5 @@
         {
             if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
-                (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNDED) || u->hasUnitState(UNIT_STAT_STUNDED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
+                (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
             {
                 return true;
Index: trunk/src/game/TargetedMovementGenerator.cpp
===================================================================
--- trunk/src/game/TargetedMovementGenerator.cpp (revision 18)
+++ trunk/src/game/TargetedMovementGenerator.cpp (revision 28)
@@ -48,5 +48,5 @@
         return;
 
-    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
+    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
         return;
 
@@ -128,5 +128,5 @@
         return true;
 
-    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
+    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
         return true;
 
Index: trunk/src/game/MotionMaster.cpp
===================================================================
--- trunk/src/game/MotionMaster.cpp (revision 2)
+++ trunk/src/game/MotionMaster.cpp (revision 28)
@@ -77,5 +77,5 @@
 MotionMaster::UpdateMotion(const uint32 &diff)
 {
-    if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
+    if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
         return;
     assert( !empty() );
Index: trunk/src/game/Unit.h
===================================================================
--- trunk/src/game/Unit.h (revision 9)
+++ trunk/src/game/Unit.h (revision 28)
@@ -347,5 +347,5 @@
     UNIT_STAT_MELEE_ATTACKING = 0x0002,                     // player is melee attacking someone
     //UNIT_STAT_MELEE_ATTACK_BY = 0x0004,                     // player is melee attack by someone
-    UNIT_STAT_STUNDED         = 0x0008,
+    UNIT_STAT_STUNNED         = 0x0008,
     UNIT_STAT_ROAMING         = 0x0010,
     UNIT_STAT_CHASE           = 0x0020,
@@ -757,5 +757,5 @@
         {
             return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT |
-                UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0;
+                UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0;
         }
 
Index: trunk/src/game/MiscHandler.cpp
===================================================================
--- trunk/src/game/MiscHandler.cpp (revision 9)
+++ trunk/src/game/MiscHandler.cpp (revision 28)
@@ -1427,5 +1427,5 @@
         GetPlayer()->TeleportTo(mapid,PositionX,PositionY,PositionZ,Orientation);
     else
-        SendNotification("You do not have permission to perform that function");
+        SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
     sLog.outDebug("Received worldport command from player %s", GetPlayer()->GetName());
 }
@@ -1436,10 +1436,10 @@
 
     sLog.outDebug("Received opcode CMSG_WHOIS");
-    std::string charname, acc, email, lastip, msg;
+    std::string charname;
     recv_data >> charname;
 
     if (GetSecurity() < SEC_ADMINISTRATOR)
     {
-        SendNotification("You do not have permission to perform that function");
+        SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
         return;
     }
@@ -1447,50 +1447,44 @@
     if(charname.empty())
     {
-        SendNotification("Please provide character name");
-        return;
-    }
-
-    uint32 accid;
-    Field *fields;
+        SendNotification(LANG_NEED_CHARACTER_NAME);
+        return;
+    }
 
     Player *plr = objmgr.GetPlayer(charname.c_str());
 
-    if(plr)
-        accid = plr->GetSession()->GetAccountId();
-    else
-    {
-        SendNotification("Player %s not found or offline", charname.c_str());
-        return;
-    }
-
-    if(!accid)
-    {
-        SendNotification("Account for character %s not found", charname.c_str());
-        return;
-    }
+    if(!plr)
+    {
+        SendNotification(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, charname.c_str());
+        return;
+    }
+
+    uint32 accid = plr->GetSession()->GetAccountId();
 
     QueryResult *result = loginDatabase.PQuery("SELECT username,email,last_ip FROM account WHERE id=%u", accid);
-    if(result)
-    {
-        fields = result->Fetch();
-        acc = fields[0].GetCppString();
-        if(acc.empty())
-            acc = "Unknown";
-        email = fields[1].GetCppString();
-        if(email.empty())
-            email = "Unknown";
-        lastip = fields[2].GetCppString();
-        if(lastip.empty())
-            lastip = "Unknown";
-        msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
-
-        WorldPacket data(SMSG_WHOIS, msg.size()+1);
-        data << msg;
-        _player->GetSession()->SendPacket(&data);
-    }
-    else
-        SendNotification("Account for character %s not found", charname.c_str());
+    if(!result)
+    {
+        SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, charname.c_str());
+        return;
+    }
+
+    Field *fields = result->Fetch();
+    std::string acc = fields[0].GetCppString();
+    if(acc.empty())
+        acc = "Unknown";
+    std::string email = fields[1].GetCppString();
+    if(email.empty())
+        email = "Unknown";
+    std::string lastip = fields[2].GetCppString();
+    if(lastip.empty())
+        lastip = "Unknown";
+
+    std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
+
+    WorldPacket data(SMSG_WHOIS, msg.size()+1);
+    data << msg;
+    _player->GetSession()->SendPacket(&data);
 
     delete result;
+
     sLog.outDebug("Received whois command from player %s for character %s", GetPlayer()->GetName(), charname.c_str());
 }
Index: trunk/src/game/World.h
===================================================================
--- trunk/src/game/World.h (revision 19)
+++ trunk/src/game/World.h (revision 28)
@@ -107,8 +107,10 @@
     CONFIG_MAX_PRIMARY_TRADE_SKILL,
     CONFIG_MIN_PETITION_SIGNS,
+    CONFIG_GM_LOGIN_STATE,
+    CONFIG_GM_ACCEPT_TICKETS,
+    CONFIG_GM_CHAT,
     CONFIG_GM_WISPERING_TO,
     CONFIG_GM_IN_GM_LIST,
     CONFIG_GM_IN_WHO_LIST,
-    CONFIG_GM_LOGIN_STATE,
     CONFIG_GM_LOG_TRADE,
     CONFIG_GROUP_VISIBILITY,
Index: trunk/src/game/WorldSession.h
===================================================================
--- trunk/src/game/WorldSession.h (revision 6)
+++ trunk/src/game/WorldSession.h (revision 28)
@@ -80,4 +80,5 @@
         void SendPacket(WorldPacket const* packet);
         void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
+        void SendNotification(int32 string_id,...);
         void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type);
         void SendPartyResult(PartyOperation operation, std::string member, PartyResult res);
Index: trunk/src/game/Unit.cpp
===================================================================
--- trunk/src/game/Unit.cpp (revision 9)
+++ trunk/src/game/Unit.cpp (revision 28)
@@ -471,5 +471,5 @@
             RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
 
-        if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNDED))
+        if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED))
             pVictim->SetStandState(PLAYER_STATE_NONE);
     }
@@ -2150,5 +2150,5 @@
 void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
 {
-    if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
+    if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
         return;
 
@@ -2962,5 +2962,5 @@
 float Unit::GetUnitDodgeChance() const
 {
-    if(hasUnitState(UNIT_STAT_STUNDED))
+    if(hasUnitState(UNIT_STAT_STUNNED))
         return 0.0f;
     if( GetTypeId() == TYPEID_PLAYER )
@@ -2981,5 +2981,5 @@
 float Unit::GetUnitParryChance() const
 {
-    if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNDED))
+    if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNNED))
         return 0.0f;
 
@@ -3013,5 +3013,5 @@
 float Unit::GetUnitBlockChance() const
 {
-    if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNDED))
+    if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNNED))
         return 0.0f;
 
@@ -7986,5 +7986,5 @@
     if (spellInfo->Mechanic == MECHANIC_FEAR )
     {
-        if ( hasUnitState(UNIT_STAT_STUNDED) )
+        if ( hasUnitState(UNIT_STAT_STUNNED) )
             return true;
     }
@@ -8663,5 +8663,5 @@
 
     //If a mob or player is stunned he will not be able to detect stealth
-    if (u->hasUnitState(UNIT_STAT_STUNDED) && (u != this))
+    if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this))
         return false;
 
@@ -9137,5 +9137,5 @@
     if(target)
     {
-        if(!hasUnitState(UNIT_STAT_STUNDED))
+        if(!hasUnitState(UNIT_STAT_STUNNED))
             SetInFront(target);
         ((Creature*)this)->AI()->AttackStart(target);
Index: trunk/src/game/SocialMgr.cpp
===================================================================
--- trunk/src/game/SocialMgr.cpp (revision 2)
+++ trunk/src/game/SocialMgr.cpp (revision 28)
@@ -42,6 +42,6 @@
 bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore)
 {
-    // prevent list (client-side) overflow
-    if(m_playerSocialMap.size() >= (255-1))
+    // client limit
+    if(m_playerSocialMap.size() >= 50)
         return false;
 
@@ -181,4 +181,8 @@
     bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER;
 
+    PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
+    if(itr != player->GetSocial()->m_playerSocialMap.end())
+        friendInfo.Note = itr->second.Note;
+
     // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
     // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
@@ -219,23 +223,21 @@
     WorldPacket data;
     MakeFriendStatusPacket(result, friend_guid, &data);
+    GetFriendInfo(player, friend_guid, fi);
     switch(result)
     {
+        case FRIEND_ADDED_OFFLINE:
+        case FRIEND_ADDED_ONLINE:
+            data << fi.Note;
+            break;
+    }
+
+    switch(result)
+    {
+        case FRIEND_ADDED_ONLINE:
         case FRIEND_ONLINE:
-            GetFriendInfo(player, friend_guid, fi);
             data << uint8(fi.Status);
             data << uint32(fi.Area);
             data << uint32(fi.Level);
             data << uint32(fi.Class);
-            break;
-        case FRIEND_ADDED_ONLINE:
-            GetFriendInfo(player, friend_guid, fi);
-            data << name;
-            data << uint8(fi.Status);
-            data << uint32(fi.Area);
-            data << uint32(fi.Level);
-            data << uint32(fi.Class);
-            break;
-        case FRIEND_ADDED_OFFLINE:
-            data << name;
             break;
     }
@@ -300,6 +302,6 @@
         social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note);
 
-        // prevent list (client-side) overflow
-        if(social->m_playerSocialMap.size() >= 255)
+        // client limit
+        if(social->m_playerSocialMap.size() >= 50)
             break;
     }
Index: trunk/src/game/ObjectMgr.h
===================================================================
--- trunk/src/game/ObjectMgr.h (revision 18)
+++ trunk/src/game/ObjectMgr.h (revision 28)
@@ -743,5 +743,5 @@
         void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost);
         bool RemoveVendorItem(uint32 entry,uint32 item);
-        bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL ) const;
+        bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL ) const;
     protected:
         uint32 m_auctionid;
Index: trunk/src/game/World.cpp
===================================================================
--- trunk/src/game/World.cpp (revision 19)
+++ trunk/src/game/World.cpp (revision 28)
@@ -643,9 +643,12 @@
     }
 
-    m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetBoolDefault("GM.WhisperingTo",false);
-    m_configs[CONFIG_GM_IN_GM_LIST]  = sConfig.GetBoolDefault("GM.InGMList",false);
-    m_configs[CONFIG_GM_IN_WHO_LIST]  = sConfig.GetBoolDefault("GM.InWhoList",false);
-    m_configs[CONFIG_GM_LOGIN_STATE]  = sConfig.GetIntDefault("GM.LoginState",2);
-    m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
+    m_configs[CONFIG_GM_LOGIN_STATE]       = sConfig.GetIntDefault("GM.LoginState",2);
+    m_configs[CONFIG_GM_ACCEPT_TICKETS]    = sConfig.GetIntDefault("GM.AcceptTickets",2);
+    m_configs[CONFIG_GM_CHAT]              = sConfig.GetIntDefault("GM.Chat",2);
+    m_configs[CONFIG_GM_WISPERING_TO]      = sConfig.GetIntDefault("GM.WhisperingTo",2);
+
+    m_configs[CONFIG_GM_IN_GM_LIST]        = sConfig.GetBoolDefault("GM.InGMList",false);
+    m_configs[CONFIG_GM_IN_WHO_LIST]       = sConfig.GetBoolDefault("GM.InWhoList",false);
+    m_configs[CONFIG_GM_LOG_TRADE]         = sConfig.GetBoolDefault("GM.LogTrade", false);
 
     m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
Index: trunk/src/game/BattleGroundHandler.cpp
===================================================================
--- trunk/src/game/BattleGroundHandler.cpp (revision 9)
+++ trunk/src/game/BattleGroundHandler.cpp (revision 28)
@@ -57,5 +57,5 @@
     {
                                                             // temp, must be gossip message...
-        SendNotification("You don't meet Battleground level requirements");
+        SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR);
         return;
     }
Index: trunk/src/game/CharacterHandler.cpp
===================================================================
--- trunk/src/game/CharacterHandler.cpp (revision 6)
+++ trunk/src/game/CharacterHandler.cpp (revision 28)
@@ -37,4 +37,5 @@
 #include "SocialMgr.h"
 #include "Util.h"
+#include "Language.h"
 
 class LoginQueryHolder : public SqlQueryHolder
@@ -719,5 +720,5 @@
     {
         pCurrChar->resetSpells();
-        SendNotification("Spells has been reset.");
+        SendNotification(LANG_RESET_SPELLS);
     }
 
@@ -725,5 +726,5 @@
     {
         pCurrChar->resetTalents(true);
-        SendNotification("Talents has been reset.");
+        SendNotification(LANG_RESET_TALENTS);
     }
 
@@ -733,5 +734,5 @@
 
     if(pCurrChar->isGameMaster())
-        SendNotification("GM mode is ON");
+        SendNotification(LANG_GM_ON);
 
     std::string IP_str = GetRemoteAddress();
Index: trunk/src/game/WorldSession.cpp
===================================================================
--- trunk/src/game/WorldSession.cpp (revision 6)
+++ trunk/src/game/WorldSession.cpp (revision 28)
@@ -441,4 +441,22 @@
 }
 
+void WorldSession::SendNotification(int32 string_id,...)
+{
+    char const* format = GetMangosString(string_id);
+    if(format)
+    {
+        va_list ap;
+        char szStr [1024];
+        szStr[0] = '\0';
+        va_start(ap, format);
+        vsnprintf( szStr, 1024, format, ap );
+        va_end(ap);
+
+        WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1));
+        data << szStr;
+        SendPacket(&data);
+    }
+}
+
 const char * WorldSession::GetMangosString( int32 entry )
 {
Index: trunk/src/game/Group.cpp
===================================================================
--- trunk/src/game/Group.cpp (revision 9)
+++ trunk/src/game/Group.cpp (revision 28)
@@ -624,5 +624,5 @@
         case 1:                                             //player choose Need
         {
-            SendLootRoll(0, playerGUID, 1, 1, *roll);
+            SendLootRoll(0, playerGUID, 0, 0, *roll);
             ++roll->totalNeed;
             itr->second = NEED;
@@ -631,5 +631,5 @@
         case 2:                                             //player choose Greed
         {
-            SendLootRoll(0, playerGUID, 2, 2, *roll);
+            SendLootRoll(0, playerGUID, 128, 2, *roll);
             ++roll->totalGreed;
             itr->second = GREED;
Index: trunk/src/game/Player.cpp
===================================================================
--- trunk/src/game/Player.cpp (revision 18)
+++ trunk/src/game/Player.cpp (revision 28)
@@ -266,6 +266,6 @@
         SetAcceptTicket(true);
 
-    // players always and GM if set in config accept whispers by default
-    if(GetSession()->GetSecurity() == SEC_PLAYER || sWorld.getConfig(CONFIG_GM_WISPERING_TO))
+    // players always accept 
+    if(GetSession()->GetSecurity() == SEC_PLAYER)
         SetAcceptWhispers(true);
 
@@ -1416,5 +1416,5 @@
     // 0x2 - dnd
     // 0x1 - afk
-    if(isGameMaster())
+    if(isGMChat())
         return 4;
     else if(isDND())
@@ -1556,8 +1556,11 @@
         }
 
-        SetSemaphoreTeleport(false);
-
         if(!GetSession()->PlayerLogout())
+        {
+            // don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB
+            SetSemaphoreTeleport(false);
+
             UpdateZone(GetZoneId());
+        }
 
         // new zone
@@ -9323,4 +9326,9 @@
         if( pProto )
         {
+            // May be here should be more stronger checks; STUNNED checked
+            // ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
+            if (not_loading && hasUnitState(UNIT_STAT_STUNNED))
+                return EQUIP_ERR_YOU_ARE_STUNNED;
+
             if(pItem->IsBindedNotWith(GetGUID()))
                 return EQUIP_ERR_DONT_OWN_THAT_ITEM;
@@ -9346,4 +9354,7 @@
             if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0)
                 return EQUIP_ERR_CANT_DO_RIGHT_NOW;         // maybe exist better err
+
+            if(IsNonMeleeSpellCasted(false))
+                return EQUIP_ERR_CANT_DO_RIGHT_NOW;
 
             uint8 eslot = FindEquipSlot( pProto, slot, swap );
@@ -13799,14 +13810,43 @@
         switch(sWorld.getConfig(CONFIG_GM_LOGIN_STATE))
         {
-            case 0:                                         // disable
-                break;
-            case 1:                                         // enable
-                SetGameMaster(true);
-                break;
+            default:
+            case 0:                      break;             // disable
+            case 1: SetGameMaster(true); break;             // enable
             case 2:                                         // save state
-                if(gmstate)
+                if(gmstate & PLAYER_EXTRA_GM_ON)
                     SetGameMaster(true);
                 break;
+        }
+
+        switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS))
+        {
             default:
+            case 0:                        break;           // disable
+            case 1: SetAcceptTicket(true); break;           // enable
+            case 2:                                         // save state
+            if(gmstate & PLAYER_EXTRA_GM_ACCEPT_TICKETS)
+                SetAcceptTicket(true);
+            break;
+        }
+
+        switch(sWorld.getConfig(CONFIG_GM_CHAT))
+        {
+            default:
+            case 0:                  break;                 // disable
+            case 1: SetGMChat(true); break;                 // enable
+            case 2:                                         // save state
+                if(gmstate & PLAYER_EXTRA_GM_CHAT)
+                    SetGMChat(true);
+                break;
+        }
+
+        switch(sWorld.getConfig(CONFIG_GM_WISPERING_TO))
+        {
+            default:
+            case 0:                          break;         // disable
+            case 1: SetAcceptWhispers(true); break;         // enable
+            case 2:                                         // save state
+                if(gmstate & PLAYER_EXTRA_ACCEPT_WHISPERS)
+                    SetAcceptWhispers(true);
                 break;
         }
@@ -14878,5 +14918,5 @@
 
     ss << ", ";
-    ss << (isGameMaster()? 1 : 0);
+    ss << m_ExtraFlags;
 
     ss << ", ";
@@ -16388,10 +16428,12 @@
     }
 
-    VendorItem const* crItem = vItems->FindItem(item);
-    if(!crItem)
+    size_t vendor_slot = vItems->FindItemSlot(item);
+    if(vendor_slot >= vItems->GetItemCount())
     {
         SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
         return false;
     }
+
+    VendorItem const* crItem = vItems->m_items[vendor_slot];
 
     // check current item amount if it limited
@@ -16521,5 +16563,5 @@
             WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
             data << pCreature->GetGUID();
-            data << (uint32)crItem->item;
+            data << (uint32)(vendor_slot+1);                // numbered from 1 at client
             data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
             data << (uint32)count;
@@ -16560,5 +16602,5 @@
             WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
             data << pCreature->GetGUID();
-            data << (uint32)crItem->item;
+            data << (uint32)(vendor_slot+1);                // numbered from 1 at client
             data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
             data << (uint32)count;
Index: trunk/src/game/RandomMovementGenerator.cpp
===================================================================
--- trunk/src/game/RandomMovementGenerator.cpp (revision 26)
+++ trunk/src/game/RandomMovementGenerator.cpp (revision 28)
@@ -127,5 +127,5 @@
 RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
 {
-    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
+    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
     {
         i_nextMoveTime.Update(i_nextMoveTime.GetExpiry());    // Expire the timer
Index: trunk/src/game/PointMovementGenerator.cpp
===================================================================
--- trunk/src/game/PointMovementGenerator.cpp (revision 18)
+++ trunk/src/game/PointMovementGenerator.cpp (revision 28)
@@ -42,5 +42,5 @@
         return false;
 
-    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
+    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
         return true;
 
Index: trunk/src/game/SpellAuras.cpp
===================================================================
--- trunk/src/game/SpellAuras.cpp (revision 2)
+++ trunk/src/game/SpellAuras.cpp (revision 28)
@@ -3190,5 +3190,5 @@
     if (apply)
     {
-        m_target->addUnitState(UNIT_STAT_STUNDED);
+        m_target->addUnitState(UNIT_STAT_STUNNED);
         m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0);
 
@@ -3214,5 +3214,5 @@
             return;
 
-        m_target->clearUnitState(UNIT_STAT_STUNDED);
+        m_target->clearUnitState(UNIT_STAT_STUNNED);
         m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
 
@@ -3443,5 +3443,5 @@
         m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
 
-        if(!m_target->hasUnitState(UNIT_STAT_STUNDED))      // prevent allow move if have also stun effect
+        if(!m_target->hasUnitState(UNIT_STAT_STUNNED))      // prevent allow move if have also stun effect
         {
             if(m_target->getVictim() && m_target->isAlive())
Index: trunk/src/game/ChatHandler.cpp
===================================================================
--- trunk/src/game/ChatHandler.cpp (revision 2)
+++ trunk/src/game/ChatHandler.cpp (revision 28)
@@ -59,5 +59,5 @@
     if(!langDesc)
     {
-        SendNotification("Unknown language");
+        SendNotification(LANG_UNKNOWN_LANGUAGE);
         return;
     }
@@ -77,5 +77,5 @@
         if(!foundAura)
         {
-            SendNotification("You don't know that language");
+            SendNotification(LANG_NOT_LEARNED_LANGUAGE);
             return;
         }
Index: trunk/src/game/Spell.cpp
===================================================================
--- trunk/src/game/Spell.cpp (revision 18)
+++ trunk/src/game/Spell.cpp (revision 28)
@@ -987,5 +987,5 @@
                 if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
                 {
-                    if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNDED))
+                    if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED))
                         unit->SetStandState(PLAYER_STATE_NONE);
 
@@ -2408,5 +2408,5 @@
 
                     // check for incapacitating player states
-                    if( m_caster->hasUnitState(UNIT_STAT_STUNDED | UNIT_STAT_CONFUSED))
+                    if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED))
                         cancel();
 
Index: trunk/src/game/Creature.cpp
===================================================================
--- trunk/src/game/Creature.cpp (revision 18)
+++ trunk/src/game/Creature.cpp (revision 28)
@@ -74,4 +74,12 @@
     }
     return false;
+}
+
+size_t VendorItemData::FindItemSlot(uint32 item_id) const
+{
+    for(size_t i = 0; i < m_items.size(); ++i )
+        if(m_items[i]->item==item_id)
+            return i;
+    return m_items.size();
 }
 
@@ -1911,24 +1919,27 @@
 void Creature::GetRespawnCoord( float &x, float &y, float &z, float* ori, float* dist ) const
 {
-    if(CreatureData const* data = objmgr.GetCreatureData(GetDBTableGUIDLow()))
-    {
-        x = data->posX;
-        y = data->posY;
-        z = data->posZ;
-        if(ori)
-            *ori = data->orientation;
-        if(dist)
-            *dist = data->spawndist;
-    }
-    else
-    {
-        x = GetPositionX();
-        y = GetPositionY();
-        z = GetPositionZ();
-        if(ori)
-            *ori = GetOrientation();
-        if(dist)
-            *dist = 0;
-    }
+    if (m_DBTableGuid)
+    {
+        if (CreatureData const* data = objmgr.GetCreatureData(GetDBTableGUIDLow()))
+        {
+            x = data->posX;
+            y = data->posY;
+            z = data->posZ;
+            if(ori)
+                *ori = data->orientation;
+            if(dist)
+                *dist = data->spawndist;
+
+            return;
+        }
+    }
+
+    x = GetPositionX();
+    y = GetPositionY();
+    z = GetPositionZ();
+    if(ori)
+        *ori = GetOrientation();
+    if(dist)
+        *dist = 0;
 }
 
Index: trunk/src/game/ObjectMgr.cpp
===================================================================
--- trunk/src/game/ObjectMgr.cpp (revision 18)
+++ trunk/src/game/ObjectMgr.cpp (revision 28)
@@ -6680,4 +6680,6 @@
     m_mCacheTrainerSpellMap.clear();
 
+    std::set<uint32> skip_trainers;
+
     QueryResult *result = WorldDatabase.PQuery("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
 
@@ -6715,5 +6717,9 @@
         if(!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
         {
-            sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry);
+            if(skip_trainers.count(entry) == 0)
+            {
+                sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry);
+                skip_trainers.insert(entry);
+            }
             continue;
         }
@@ -6765,4 +6771,6 @@
     m_mCacheVendorItemMap.clear();
 
+    std::set<uint32> skip_vendors;
+
     QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
     if( !result )
@@ -6791,5 +6799,5 @@
         uint32 ExtendedCost = fields[4].GetUInt32();
 
-        if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost))
+        if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors))
             continue;
 
@@ -6879,5 +6887,5 @@
 }
 
-bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl ) const
+bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set<uint32>* skip_vendors ) const
 {
     CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry);
@@ -6893,8 +6901,14 @@
     if(!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR))
     {
-        if(pl)
-            ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
-        else
-            sLog.outErrorDb("Table `npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry);
+        if(!skip_vendors || skip_vendors->count(vendor_entry)==0)
+        {
+            if(pl)
+                ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
+            else
+                sLog.outErrorDb("Table `npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry);
+
+            if(skip_vendors)
+                skip_vendors->insert(vendor_entry);
+        }
         return false;
     }
Index: trunk/src/game/Language.h
===================================================================
--- trunk/src/game/Language.h (revision 18)
+++ trunk/src/game/Language.h (revision 28)
@@ -76,5 +76,7 @@
     LANG_LEVEL_MINREQUIRED_AND_ITEM     = 50,
     LANG_NPC_TAINER_HELLO               = 51,
-    // Room for more level 0
+    LANG_COMMAND_INVALID_ITEM_COUNT     = 52,
+    LANG_COMMAND_MAIL_ITEMS_LIMIT       = 53,
+    // Room for more level 0              54-99 not used
 
     // level 1 chat
@@ -160,5 +162,5 @@
     LANG_MAIL_SENT                      = 169,
     LANG_SOUND_NOT_EXIST                = 170,
-    // Room for more level 1
+    // Room for more level 1              171-199 not used
 
     // level 2 chat
@@ -305,6 +307,9 @@
     LANG_NO_PLAYERS_FOUND               = 330,
     LANG_EXTENDED_COST_NOT_EXIST        = 331,
-
-    // Room for more level 2
+    LANG_GM_ON                          = 332,
+    LANG_GM_OFF                         = 333,
+    LANG_GM_CHAT_ON                     = 334,
+    LANG_GM_CHAT_OFF                    = 335,
+    // Room for more level 2              336-399 not used
 
     // level 3 chat
@@ -611,78 +616,48 @@
     LANG_BG_GROUP_TOO_LARGE             = 711,
     LANG_ARENA_GROUP_TOO_LARGE          = 712,
-    LANG_ARENA_YOUR_TEAM_ONLY           = 713,
-    LANG_ARENA_NOT_ENOUGH_PLAYERS       = 714,
-    LANG_ARENA_GOLD_WINS                = 715,
-    LANG_ARENA_GREEN_WINS               = 716,
-    LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 717,
-    LANG_BG_GROUP_OFFLINE_MEMBER        = 718,
-    LANG_BG_GROUP_MIXED_FACTION         = 719,
-    LANG_BG_GROUP_MIXED_LEVELS          = 720,
-    LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 721,
-    LANG_BG_GROUP_MEMBER_DESERTER       = 722,
-    LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 723,
-
-    LANG_CANNOT_TELE_TO_BG              = 724,
-    LANG_CANNOT_SUMMON_TO_BG            = 725,
-    LANG_CANNOT_GO_TO_BG_GM             = 726,
-    LANG_CANNOT_GO_TO_BG_FROM_BG        = 727,
-
-    LANG_ARENA_TESTING                  = 728
-
+    LANG_YOUR_ARENA_LEVEL_REQ_ERROR     = 713,
+    LANG_HIS_ARENA_LEVEL_REQ_ERROR      = 714,
+    LANG_YOUR_BG_LEVEL_REQ_ERROR        = 715,
+    LANG_YOUR_ARENA_TEAM_FULL           = 716,
+    // Room for BG/ARENA                  717-799 not used
+
+    LANG_ARENA_YOUR_TEAM_ONLY           = 730,
+    LANG_ARENA_NOT_ENOUGH_PLAYERS       = 731,
+    LANG_ARENA_GOLD_WINS                = 732,
+    LANG_ARENA_GREEN_WINS               = 733,
+    LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 734,
+    LANG_BG_GROUP_OFFLINE_MEMBER        = 735,
+    LANG_BG_GROUP_MIXED_FACTION         = 736,
+    LANG_BG_GROUP_MIXED_LEVELS          = 737,
+    LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 738,
+    LANG_BG_GROUP_MEMBER_DESERTER       = 739,
+    LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 740,
+
+    LANG_CANNOT_TELE_TO_BG              = 741,
+    LANG_CANNOT_SUMMON_TO_BG            = 742,
+    LANG_CANNOT_GO_TO_BG_GM             = 743,
+    LANG_CANNOT_GO_TO_BG_FROM_BG        = 744,
+
+    LANG_ARENA_TESTING                  = 745,
+
+    // in game strings
+    LANG_PET_INVALID_NAME               = 800,
+    LANG_NOT_ENOUGH_GOLD                = 801,
+    LANG_NOT_FREE_TRADE_SLOTS           = 802,
+    LANG_NOT_PARTNER_FREE_TRADE_SLOTS   = 803,
+    LANG_YOU_NOT_HAVE_PERMISSION        = 804,
+    LANG_UNKNOWN_LANGUAGE               = 805,
+    LANG_NOT_LEARNED_LANGUAGE           = 806,
+    LANG_NEED_CHARACTER_NAME            = 807,
+    LANG_PLAYER_NOT_EXIST_OR_OFFLINE    = 808,
+    LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND   = 809,
+    // Room for in-game strings           810-999 not used
+
+    // FREE IDS                           1000-9999
+
+    // Use for not-in-svn patches         10000-10999
+    // Use for custom patches             11000-11999
+
+    // NOT RESERVED IDS                   12000-
 };
 #endif
-
-/*  NOT USED VALUES
-// alliance ranks
-#define LANG_ALI_PRIVATE                 "Private "
-#define LANG_ALI_CORPORAL                "Corporal "
-#define LANG_ALI_SERGEANT                "Sergeant "
-#define LANG_ALI_MASTER_SERGEANT         "Master Sergeant "
-#define LANG_ALI_SERGEANT_MAJOR          "Sergeant Major "
-#define LANG_ALI_KNIGHT                  "Knight "
-#define LANG_ALI_KNIGHT_LIEUTENANT       "Knight-Lieutenant "
-#define LANG_ALI_KNIGHT_CAPTAIN          "Knight-Captain "
-#define LANG_ALI_KNIGHT_CHAMPION         "Knight-Champion "
-#define LANG_ALI_LIEUTENANT_COMMANDER    "Lieutenant Commander "
-#define LANG_ALI_COMMANDER               "Commander "
-#define LANG_ALI_MARSHAL                 "Marshal "
-#define LANG_ALI_FIELD_MARSHAL           "Field Marshal "
-#define LANG_ALI_GRAND_MARSHAL           "Grand Marshal "
-#define LANG_ALI_GAME_MASTER             "Game Master "
-
-// horde ranks
-#define LANG_HRD_SCOUT                   "Scout "
-#define LANG_HRD_GRUNT                   "Grunt "
-#define LANG_HRD_SERGEANT                "Sergeant "
-#define LANG_HRD_SENIOR_SERGEANT         "Senior Sergeant "
-#define LANG_HRD_FIRST_SERGEANT          "First Sergeant "
-#define LANG_HRD_STONE_GUARD             "Stone Guard "
-#define LANG_HRD_BLOOD_GUARD             "Blood Guard "
-#define LANG_HRD_LEGIONNARE              "Legionnaire "
-#define LANG_HRD_CENTURION               "Centurion "
-#define LANG_HRD_CHAMPION                "Champion "
-#define LANG_HRD_LIEUTENANT_GENERAL      "Lieutenant General "
-#define LANG_HRD_GENERAL                 "General "
-#define LANG_HRD_WARLORD                 "Warlord "
-#define LANG_HRD_HIGH_WARLORD            "High Warlord "
-#define LANG_HRD_GAME_MASTER             "Game Master "
-
-#define LANG_NO_RANK                     "No rank "
-#define LANG_RANK                        "%s (Rank %u)"
-#define LANG_HONOR_TODAY                 "Today: [Honorable kills: |c0000ff00%u|r] [Dishonorable kills: |c00ff0000%u|r]"
-#define LANG_HONOR_YESTERDAY             "Yesterday: [Kills: |c0000ff00%u|r] [Honor: %u]"
-#define LANG_HONOR_THIS_WEEK             "This week: [Kills: |c0000ff00%u|r] [Honor: %u]"
-#define LANG_HONOR_LAST_WEEK             "Last week: [Kills: |c0000ff00%u|r] [Honor: %u] [Standing: %u]"
-#define LANG_HONOR_LIFE                  "Lifetime: [Honorable kills: |c0000ff00%u|r] [Dishonorable kills: |c00ff0000%u|r] [Highest rank %u: %s]"
-
-// level 2
-#define LANG_ADD_OBJ                     "AddObject at Chat.cpp" //log
-#define LANG_DEMORPHED                   "Demorphed %s"     //log
-
-// level 3
-#define LANG_SPAWNING_SPIRIT_HEAL        "Spawning spirit healers\n"
-#define LANG_NO_SPIRIT_HEAL_DB           "No spirit healers in database, exiting."
-
-#define LANG_ADD_OBJ_LV3                 "AddObject at Level3.cpp line 1176"
-
-*/
