Index: /trunk/src/trinityrealm/TrinityRealm.rc
===================================================================
--- /trunk/src/trinityrealm/TrinityRealm.rc (revision 18)
+++ /trunk/src/trinityrealm/TrinityRealm.rc (revision 28)
@@ -53,6 +53,6 @@
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,3,6731,680
- PRODUCTVERSION 0,3,6731,680
+ FILEVERSION 0,4,6743,685
+ PRODUCTVERSION 0,4,6743,685
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
@@ -70,10 +70,10 @@
         BEGIN
             VALUE "FileDescription", "TrinityRealm"
-            VALUE "FileVersion", "0, 3, 6731, 680"
+            VALUE "FileVersion", "0, 4, 6743, 685"
             VALUE "InternalName", "TrinityRealm"
             VALUE "LegalCopyright", "Copyright (C) 2008"
             VALUE "OriginalFilename", "TrinityRealm.exe"
             VALUE "ProductName", "TrinityRealm"
-            VALUE "ProductVersion", "0, 3, 6731, 680"
+            VALUE "ProductVersion", "0, 4, 6743, 685"
         END
     END
Index: /trunk/src/shared/WheatyExceptionReport.cpp
===================================================================
--- /trunk/src/shared/WheatyExceptionReport.cpp (revision 2)
+++ /trunk/src/shared/WheatyExceptionReport.cpp (revision 28)
@@ -9,4 +9,5 @@
 #pragma warning(disable:4311)
 #include <windows.h>
+#include <tlhelp32.h>
 #include <stdio.h>
 #include <tchar.h>
@@ -328,4 +329,52 @@
 
 //===========================================================================
+void WheatyExceptionReport::printTracesForAllThreads()
+{
+  HANDLE hThreadSnap = INVALID_HANDLE_VALUE; 
+  THREADENTRY32 te32; 
+ 
+  DWORD dwOwnerPID = GetCurrentProcessId();
+  m_hProcess = GetCurrentProcess();
+  // Take a snapshot of all running threads  
+  hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
+  if( hThreadSnap == INVALID_HANDLE_VALUE ) 
+    return; 
+ 
+  // Fill in the size of the structure before using it. 
+  te32.dwSize = sizeof(THREADENTRY32 ); 
+ 
+  // Retrieve information about the first thread,
+  // and exit if unsuccessful
+  if( !Thread32First( hThreadSnap, &te32 ) ) 
+  {
+    CloseHandle( hThreadSnap );    // Must clean up the
+                                   //   snapshot object!
+    return;
+  }
+
+  // Now walk the thread list of the system,
+  // and display information about each thread
+  // associated with the specified process
+  do 
+  { 
+    if( te32.th32OwnerProcessID == dwOwnerPID )
+    {
+        CONTEXT context;
+        context.ContextFlags = 0xffffffff;
+        HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,false, te32.th32ThreadID);
+        if(threadHandle && GetThreadContext(threadHandle, &context))
+        {
+            WriteStackDetails( &context, false, threadHandle );
+        }
+        CloseHandle(threadHandle);
+    }
+  } while( Thread32Next(hThreadSnap, &te32 ) ); 
+
+//  Don't forget to clean up the snapshot object.
+  CloseHandle( hThreadSnap );
+}
+
+
+//===========================================================================
 // Open the report file, and write the desired information to it.  Called by
 // WheatyUnhandledExceptionFilter
@@ -412,5 +461,6 @@
     CONTEXT trashableContext = *pCtx;
 
-    WriteStackDetails( &trashableContext, false );
+    WriteStackDetails( &trashableContext, false, NULL );
+    printTracesForAllThreads();
 
 //    #ifdef _M_IX86                                          // X86 Only!
@@ -420,5 +470,5 @@
 
     trashableContext = *pCtx;
-    WriteStackDetails( &trashableContext, true );
+    WriteStackDetails( &trashableContext, true, NULL );
 
     _tprintf( _T("========================\r\n") );
@@ -552,5 +602,5 @@
 void WheatyExceptionReport::WriteStackDetails(
 PCONTEXT pContext,
-bool bWriteVariables )                                      // true if local/params should be output
+bool bWriteVariables, HANDLE pThreadHandle)                                      // true if local/params should be output
 {
     _tprintf( _T("\r\nCall stack:\r\n") );
@@ -592,5 +642,5 @@
         if ( ! StackWalk64(  dwMachineType,
             m_hProcess,
-            GetCurrentThread(),
+            pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(),
             &sf,
             pContext,
Index: /trunk/src/shared/WheatyExceptionReport.h
===================================================================
--- /trunk/src/shared/WheatyExceptionReport.h (revision 2)
+++ /trunk/src/shared/WheatyExceptionReport.h (revision 28)
@@ -80,6 +80,6 @@
             PEXCEPTION_POINTERS pExceptionInfo );
 
+        static void printTracesForAllThreads();
     private:
-
         // where report info is extracted and generated
         static void GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo );
@@ -93,5 +93,5 @@
             DWORD& section, DWORD_PTR& offset );
 
-        static void WriteStackDetails( PCONTEXT pContext, bool bWriteVariables );
+        static void WriteStackDetails( PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
 
         static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
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"
-
-*/
Index: /trunk/src/trinitycore/TrinityCore.rc
===================================================================
--- /trunk/src/trinitycore/TrinityCore.rc (revision 18)
+++ /trunk/src/trinitycore/TrinityCore.rc (revision 28)
@@ -53,6 +53,6 @@
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,3,6731,680
- PRODUCTVERSION 0,3,6731,680
+ FILEVERSION 0,4,6743,685
+ PRODUCTVERSION 0,4,6743,685
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
@@ -70,10 +70,10 @@
         BEGIN
             VALUE "FileDescription", "TrinityCore"
-            VALUE "FileVersion", "0, 3, 6731, 680"
+            VALUE "FileVersion", "0, 4, 6743, 685"
             VALUE "InternalName", "TrinityCore"
             VALUE "LegalCopyright", "Copyright (C) 2008"
             VALUE "OriginalFilename", "TrinityCore.exe"
             VALUE "ProductName", "TrinityCore"
-            VALUE "ProductVersion", "0, 3, 6731, 680"
+            VALUE "ProductVersion", "0, 4, 6743, 685"
         END
     END
Index: /trunk/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp (revision 18)
+++ /trunk/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp (revision 28)
@@ -88,5 +88,5 @@
         Abuse_Bug_Timer = 10000 + rand()%7000;
         BugsTimer = 2000;
-        m_creature->clearUnitState(UNIT_STAT_STUNDED);
+        m_creature->clearUnitState(UNIT_STAT_STUNNED);
         DontYellWhenDead = false;
         EnrageTimer = 15*60000;
@@ -291,5 +291,5 @@
         DoResetThreat();
         DoCast(m_creature, SPELL_TWIN_TELEPORT_VISUAL);
-        m_creature->addUnitState(UNIT_STAT_STUNDED);
+        m_creature->addUnitState(UNIT_STAT_STUNNED);
         AfterTeleport = true;
         AfterTeleportTimer = 2000;
@@ -303,7 +303,7 @@
             if (!tspellcasted)
             {
-                m_creature->clearUnitState(UNIT_STAT_STUNDED);
+                m_creature->clearUnitState(UNIT_STAT_STUNNED);
                 DoCast(m_creature, SPELL_TWIN_TELEPORT);
-                m_creature->addUnitState(UNIT_STAT_STUNDED);
+                m_creature->addUnitState(UNIT_STAT_STUNNED);
             }
 
@@ -313,5 +313,5 @@
             {
                 AfterTeleport = false;
-                m_creature->clearUnitState(UNIT_STAT_STUNDED);
+                m_creature->clearUnitState(UNIT_STAT_STUNNED);
                 Unit *nearu = PickNearestPlayer();
                 //DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
Index: /trunk/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp (revision 18)
+++ /trunk/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp (revision 28)
@@ -400,5 +400,5 @@
         }else EnfeebleResetTimer -= diff;
 
-        if(m_creature->hasUnitState(UNIT_STAT_STUNDED))     //While shifting to phase 2 malchezaar stuns himself
+        if(m_creature->hasUnitState(UNIT_STAT_STUNNED))     //While shifting to phase 2 malchezaar stuns himself
             return;
 
Index: /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp (revision 6)
+++ /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp (revision 28)
@@ -17,5 +17,5 @@
 /* ScriptData
 SDName: Instance_Magisters_Terrace
-SD%Complete: 100
+SD%Complete: 60
 SDComment:  Designed only for Selin Fireheart
 SDCategory: Magister's Terrace
@@ -119,13 +119,22 @@
         switch(entry)
         {
-            case 24723:
-                SelinGUID = creature->GetGUID();
-                break;
-            case 24560:
-                DelrissaGUID = creature->GetGUID();
-                break;
-            case 24722:
-                FelCrystals.push_back(creature->GetGUID());
-                break;
+            case 24723: SelinGUID = creature->GetGUID(); break;
+            case 24560: DelrissaGUID = creature->GetGUID(); break;
+            case 24722: FelCrystals.push_back(creature->GetGUID()); break;
+        }
+    }
+
+    void OnObjectCreate(GameObject* go)
+    {
+        switch(go->GetEntry())
+        {
+            case 187896:  VexallusDoorGUID = go->GetGUID();       break;
+            //SunwellRaid Gate 02
+            case 187979:  SelinDoorGUID = go->GetGUID();          break;
+            //Assembly Chamber Door
+            case 188065:  SelinEncounterDoorGUID = go->GetGUID(); break;
+            case 187770:  DelrissaDoorGUID = go->GetGUID();       break;
+            case 188165:  KaelStatue[0] = go->GetGUID();          break;
+            case 188166:  KaelStatue[1] = go->GetGUID();          break;
         }
     }
@@ -165,17 +174,4 @@
         return 0;
     }
-
-    void OnObjectCreate(GameObject* go)
-    {
-        switch(go->GetEntry())
-        {
-            case 187896:  VexallusDoorGUID = go->GetGUID();       break;
-            case 187979:  SelinDoorGUID = go->GetGUID();          break;
-            case 188118:  SelinEncounterDoorGUID = go->GetGUID(); break;
-            case 187770:  DelrissaDoorGUID = go->GetGUID();       break;
-            case 188165:  KaelStatue[0] = go->GetGUID();          break;
-            case 188166:  KaelStatue[1] = go->GetGUID();          break;
-        }
-    }
 };
 
Index: /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp (revision 6)
+++ /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp (revision 28)
@@ -17,5 +17,5 @@
 /* ScriptData
 SDName: Boss_Selin_Fireheart
-SD%Complete: 99
+SD%Complete: 90
 SDComment: Heroic and Normal Support. Needs further testing.
 SDCategory: Magister's Terrace
@@ -74,5 +74,5 @@
             {
                 uint64 guid = pInstance->GetData64(DATA_FEL_CRYSTAL);
-                outstring_log("Selin: Adding Fel Crystal %u to list", guid);
+                debug_log("SD2: Selin: Adding Fel Crystal %u to list", guid);
                 Crystals.push_back(guid);
             }
@@ -117,7 +117,7 @@
 
             GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
-            if(Door)
-                Door->SetGoState(0);                        // Close the door. Open it only in JustDied.
-
+            if( Door )
+                Door->SetGoState(0);                        // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here)
+                                                            // Small door opened after event are expected to be closed by default
             // Set Inst data for encounter
             pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
@@ -161,8 +161,9 @@
             }
         }
-        if(CrystalChosen)
+        if( CrystalChosen )
         {
             DoYell(SAY_ENERGY, LANG_UNIVERSAL, NULL);
             DoPlaySoundToSet(m_creature, SOUND_ENERGY);
+
             CrystalChosen->CastSpell(CrystalChosen, SPELL_FEL_CRYSTAL_COSMETIC, true);
 
@@ -186,5 +187,5 @@
             //Creature* pCrystal = ((Creature*)Unit::GetUnit(*m_creature, FelCrystals[i]));
             Creature* pCrystal = ((Creature*)Unit::GetUnit(*m_creature, *itr));
-            if(pCrystal && pCrystal->isAlive())
+            if( pCrystal && pCrystal->isAlive())
                 pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
         }
@@ -195,4 +196,11 @@
         DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
         DoPlaySoundToSet(m_creature, SOUND_AGGRO);
+
+        if( pInstance )
+        {
+            GameObject* EncounterDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
+            if( EncounterDoor )
+                EncounterDoor->SetGoState(1);               //Close the encounter door, open it in JustDied/Reset
+        }
     }
 
@@ -246,7 +254,12 @@
 
         pInstance->SetData(DATA_SELIN_EVENT, DONE);         // Encounter complete!
+
         GameObject* EncounterDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
-        if(EncounterDoor)
-            EncounterDoor->SetGoState(1);                   // Open the door
+        if( EncounterDoor )
+            EncounterDoor->SetGoState(0);                   // Open the encounter door
+
+        GameObject* ContinueDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_DOOR));
+        if( ContinueDoor )
+            ContinueDoor->SetGoState(0);                    // Open the door leading further in
 
         ShatterRemainingCrystals();
@@ -303,21 +316,25 @@
         }else
         {
-            if(IsDraining)
-                if(EmpowerTimer < diff)
-            {
-                IsDraining = false;
-                DrainingCrystal = false;
-                DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
-                DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);
-                Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
-                if(CrystalChosen && CrystalChosen->isAlive())
-                    // Use Deal Damage to kill it, not setDeathState.
-                    CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
-
-                CrystalGUID = 0;
-
-                m_creature->GetMotionMaster()->Clear();
-                m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
-            }else EmpowerTimer -= diff;
+            if( IsDraining )
+            {
+                if( EmpowerTimer < diff )
+                {
+                    IsDraining = false;
+                    DrainingCrystal = false;
+
+                    DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
+                    DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);
+
+                    Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
+                    if( CrystalChosen && CrystalChosen->isAlive() )
+                        // Use Deal Damage to kill it, not setDeathState.
+                        CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+                    CrystalGUID = 0;
+
+                    m_creature->GetMotionMaster()->Clear();
+                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+                }else EmpowerTimer -= diff;
+            }
         }
 
Index: /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
===================================================================
--- /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp (revision 6)
+++ /trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp (revision 28)
@@ -1003,5 +1003,5 @@
             }else Freezing_Trap_Timer -= diff;
 
-            if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUNDED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED))
+            if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED))
                 DoMeleeAttackIfReady();
         }else
Index: /trunk/src/bindings/scripts/ScriptMgr.cpp
===================================================================
--- /trunk/src/bindings/scripts/ScriptMgr.cpp (revision 12)
+++ /trunk/src/bindings/scripts/ScriptMgr.cpp (revision 28)
@@ -1,3 +1,3 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2006 - 2008 TrinityScript <https://scriptdev2.svn.sourceforge.net/>
  * This program is free software licensed under GPL version 2
  * Please see the included DOCS/LICENSE.TXT for more information */
@@ -5,8 +5,8 @@
 #include "precompiled.h"
 #include "Config/Config.h"
+#include "Database/DatabaseEnv.h"
+#include "Database/DBCStores.h"
+#include "ObjectMgr.h"
 #include "ProgressBar.h"
-#include "Database/DBCStores.h"
-#include "Database/DatabaseMysql.h"
-#include "ObjectMgr.h"
 #include "scripts/creature/mob_event_ai.h"
 
@@ -25,17 +25,17 @@
 Script *m_scripts[MAX_SCRIPTS];
 
-// Text Map for Event AI
-HM_NAMESPACE::hash_map<uint32, std::string> EventAI_Text_Map;
-
-// Script Text used as says / yells / text emotes / whispers in scripts.
-struct ScriptText
+DatabaseType TScriptDB;
+Config TScriptConfig;
+uint32 Locale;
+
+// String text additional data, used in TextMap
+struct StringTextData
 {
     uint32 SoundId;
     uint8  Type;
     uint32 Language;
-    std::string Text;
 };
 
-// Enums used by ScriptText::Type
+// Enums used by StringTextData::Type
 enum ChatType
 {
@@ -48,5 +48,9 @@
 };
 
-HM_NAMESPACE::hash_map<uint32, ScriptText> Script_TextMap;
+#define TEXT_SOURCE_RANGE   -100000                         //the amount of entries each text source has available
+
+// Text Maps
+HM_NAMESPACE::hash_map<uint32, std::string> EventAI_Text_Map;
+HM_NAMESPACE::hash_map<int32, StringTextData> TextMap;
 
 // Localized Text structure for storing locales (for EAI and SD2 scripts).
@@ -62,10 +66,9 @@
     std::string locale_8;
 };
+//*** End Global data ***
+
+//*** EventAI data ***
 HM_NAMESPACE::hash_map<uint32, Localized_Text> EventAI_LocalizedTextMap;
-HM_NAMESPACE::hash_map<uint32, Localized_Text> Script_LocalizedTextMap;
-
-//*** End Global data ***
-
-//*** EventAI data ***
+
 //Event AI structure. Used exclusivly by mob_event_ai.cpp (60 bytes each)
 std::list<EventAI_Event> EventAI_Event_List;
@@ -78,10 +81,5 @@
 
 uint32 EAI_ErrorLevel;
-
 //*** End EventAI data ***
-
-DatabaseMysql TScriptDB;
-Config TScriptConfig;
-uint32 Locale;
 
 void FillSpellSummary();
@@ -598,508 +596,585 @@
     //Get db string from file
     char const* dbstring = NULL;
-    if(!TScriptConfig.GetString("TScriptDatabaseInfo", &dbstring))
-        error_log("TSCR: Missing Trinity Script Database Info in configuration file");
-
-    //Initilize connection to DB
-    if(!dbstring || !TScriptDB.Initialize(dbstring))
-        error_db_log("TSCR: Unable to connect to Database");
+
+    if( !TScriptConfig.GetString("TScriptDatabaseInfo", &dbstring) )
+    {
+        error_log("TSCR: Missing Trinity Script database info from configuration file. Load database aborted.");
+        return;
+    }
+
+    //Initialize connection to DB
+    if( dbstring && TScriptDB.Initialize(dbstring) )
+        outstring_log("TSCR: TrinityScript database: %s",dbstring);
     else
     {
-        //***Preform all DB queries here***
-        QueryResult *result;
-
-        //Get Version information
-        result = TScriptDB.PQuery("SELECT `version`"
-            "FROM `script_db_version`");
-
-        if (result)
+        error_log("TSCR: Unable to connect to Database. Load database aborted.");
+        return;
+    }
+
+    //***Preform all DB queries here***
+    QueryResult *result;
+
+    //Get Version information
+    result = TScriptDB.PQuery("SELECT version FROM script_db_version");
+
+    if (result)
+    {
+        Field *fields = result->Fetch();
+        outstring_log("TSCR: Database version is: %s", fields[0].GetString());
+        outstring_log("");
+        delete result;
+
+    }else
+    {
+        error_log("TSCR: Missing `script_db_version` information.");
+        outstring_log("");
+    }
+
+    // Drop Existing Text Map, only done once and we are ready to add data from multiple sources.
+    TextMap.clear();
+
+    //TODO: Add load from eventai_texts here
+
+    // Load Script Text 
+    outstring_log("TSCR: Loading Script Texts...");
+    LoadMangosStrings(TScriptDB,"script_texts",TEXT_SOURCE_RANGE,(TEXT_SOURCE_RANGE*2)+1);
+
+    // Gather Additional data from Script Texts
+    result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM script_texts");
+
+    outstring_log("TSCR: Loading Script Texts additional data...");
+    if (result)
+    {
+        barGoLink bar(result->GetRowCount());
+        uint32 count = 0;
+
+        do
         {
+            bar.step();
+            Field* fields = result->Fetch();
+            StringTextData temp;
+
+            int32 i             = fields[0].GetInt32();
+            temp.SoundId        = fields[1].GetInt32();
+            temp.Type           = fields[2].GetInt32();
+            temp.Language       = fields[3].GetInt32();
+
+            if (i >= 0)
+            {
+                error_db_log("TSCR: Entry %i in table `script_texts` is not a negative value.",i);
+                continue;
+            }
+
+            if (i > TEXT_SOURCE_RANGE || i <= TEXT_SOURCE_RANGE*2)
+            {
+                error_db_log("TSCR: Entry %i in table `script_texts` is out of accepted entry range for table.",i);
+                continue;
+            }
+
+            if (temp.SoundId)
+            {
+                if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId))
+                    error_db_log("TSCR: Entry %i in table `script_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
+            }
+
+            if (!GetLanguageDescByID(temp.Language))
+                error_db_log("TSCR: Entry %i in table `script_texts` using Language %u but Language does not exist.",i,temp.Language);
+
+            if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
+                error_db_log("TSCR: Entry %i in table `script_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
+
+            TextMap[i] = temp;
+            ++count;
+        } while (result->NextRow());
+
+        delete result;
+
+        outstring_log("");
+        outstring_log(">> TSCR: Loaded %u additional Script Texts data.", count);
+    }else
+    {
+        barGoLink bar(1);
+        bar.step();
+        outstring_log("");
+        outstring_log(">> Loaded 0 additional Script Texts data. DB table `script_texts` is empty.");
+    }
+
+    // Load Custom Text 
+    outstring_log("TSCR: Loading Custom Texts...");
+    LoadMangosStrings(TScriptDB,"custom_texts",TEXT_SOURCE_RANGE*2,(TEXT_SOURCE_RANGE*3)+1);
+
+    // Gather Additional data from Custom Texts
+    result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM custom_texts");
+
+    outstring_log("TSCR: Loading Custom Texts additional data...");
+    if (result)
+    {
+        barGoLink bar(result->GetRowCount());
+        uint32 count = 0;
+
+        do
+        {
+            bar.step();
+            Field* fields = result->Fetch();
+            StringTextData temp;
+
+            int32 i             = fields[0].GetInt32();
+            temp.SoundId        = fields[1].GetInt32();
+            temp.Type           = fields[2].GetInt32();
+            temp.Language       = fields[3].GetInt32();
+
+            if (i >= 0)
+            {
+                error_db_log("TSCR: Entry %i in table `custom_texts` is not a negative value.",i);
+                continue;
+            }
+
+            if (i > TEXT_SOURCE_RANGE*2 || i <= TEXT_SOURCE_RANGE*3)
+            {
+                error_db_log("TSCR: Entry %i in table `custom_texts` is out of accepted entry range for table.",i);
+                continue;
+            }
+
+            if (temp.SoundId)
+            {
+                if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId))
+                    error_db_log("TSCR: Entry %i in table `custom_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
+            }
+
+            if (!GetLanguageDescByID(temp.Language))
+                error_db_log("TSCR: Entry %i in table `custom_texts` using Language %u but Language does not exist.",i,temp.Language);
+
+            if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
+                error_db_log("TSCR: Entry %i in table `custom_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
+
+            TextMap[i] = temp;
+            ++count;
+        } while (result->NextRow());
+
+        delete result;
+
+        outstring_log("");
+        outstring_log(">> Loaded %u additional Custom Texts data.", count);
+    }else
+    {
+        barGoLink bar(1);
+        bar.step();
+        outstring_log("");
+        outstring_log(">> Loaded 0 additional Custom Texts data. DB table `custom_texts` is empty.");
+    }
+
+    // Drop existing Event AI Localized Text hash map
+    EventAI_LocalizedTextMap.clear();
+
+    // Gather EventAI Localized Texts
+    result = TScriptDB.PQuery("SELECT id, locale_1, locale_2, locale_3, locale_4, locale_5, locale_6, locale_7, locale_8 "
+        "FROM eventai_localized_texts");
+
+    outstring_log("TSCR: Loading EventAI Localized Texts...");
+    if(result)
+    {
+        barGoLink bar(result->GetRowCount());
+        uint32 count = 0;
+
+        do
+        {
+            Localized_Text temp;
+            bar.step();
+
             Field *fields = result->Fetch();
-            outstring_log(" ");
-            outstring_log("TSCR: Database version is: %s", fields[0].GetString());
-            outstring_log(" ");
-            delete result;
-
-        }else error_db_log("TSCR: Missing script_db_version information.");
-
-        // Drop existing Event AI Localized Text hash map
-        EventAI_LocalizedTextMap.clear();
-
-        // Gather EventAI Localized Texts
-        result = TScriptDB.PQuery("SELECT `id`,`locale_1`,`locale_2`,`locale_3`,`locale_4`,`locale_5`,`locale_6`,`locale_7`,`locale_8`"
-            "FROM `eventai_localized_texts`");
-
-        if(result)
+
+            uint32 i = fields[0].GetInt32();
+
+            temp.locale_1 = fields[1].GetString();
+            temp.locale_2 = fields[2].GetString();
+            temp.locale_3 = fields[3].GetString();
+            temp.locale_4 = fields[4].GetString();
+            temp.locale_5 = fields[5].GetString();
+            temp.locale_6 = fields[6].GetString();
+            temp.locale_7 = fields[7].GetString();
+            temp.locale_8 = fields[8].GetString();
+
+            EventAI_LocalizedTextMap[i] = temp;
+            ++count;
+
+        }while(result->NextRow());
+
+        delete result;
+
+        outstring_log("");
+        outstring_log(">> Loaded %u EventAI Localized Texts", count);
+    }else
+    {
+        barGoLink bar(1);
+        bar.step();
+        outstring_log("");
+        outstring_log(">> Loaded 0 EventAI Localized Texts. DB table `eventai_localized_texts` is empty");
+    }
+
+    //Drop existing EventAI Text hash map
+    EventAI_Text_Map.clear();
+
+    //Gather EventAI Text Entries
+    result = TScriptDB.PQuery("SELECT id, text FROM eventai_texts");
+
+    outstring_log("TSCR: Loading EventAI_Texts...");
+    if (result)
+    {
+        barGoLink bar(result->GetRowCount());
+        uint32 Count = 0;
+
+        do
         {
-            outstring_log("TSCR: Loading EAI Localized Texts....");
-            barGoLink bar(result->GetRowCount());
-            uint32 count = 0;
-
-            do
+            bar.step();
+            Field *fields = result->Fetch();
+
+            uint32 i = fields[0].GetInt32();
+
+            std::string text = fields[1].GetString();
+
+            if (!strlen(text.c_str()))
+                error_db_log("TSCR: EventAI text %u is empty", i);
+
+            EventAI_Text_Map[i] = text;
+            ++Count;
+
+        }while (result->NextRow());
+
+        delete result;
+
+        outstring_log("");
+        outstring_log(">> Loaded %u EventAI texts", Count);
+    }else
+    {
+        barGoLink bar(1);
+        bar.step();
+        outstring_log("");
+        outstring_log(">> Loaded 0 EventAI texts. DB table `eventai_texts` is empty.");
+    }
+
+    //Gather event data
+    result = TScriptDB.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM eventai_summons");
+
+    //Drop Existing EventSummon Map
+    EventAI_Summon_Map.clear();
+
+    outstring_log("TSCR: Loading EventAI_Summons...");
+    if (result)
+    {
+        barGoLink bar(result->GetRowCount());
+        uint32 Count = 0;
+
+        do
+        {
+            bar.step();
+            Field *fields = result->Fetch();
+
+            EventAI_Summon temp;
+
+            uint32 i = fields[0].GetUInt32();
+            temp.position_x = fields[1].GetFloat();
+            temp.position_y = fields[2].GetFloat();
+            temp.position_z = fields[3].GetFloat();
+            temp.orientation = fields[4].GetFloat();
+            temp.SpawnTimeSecs = fields[5].GetUInt32();
+
+            //Add to map
+            EventAI_Summon_Map[i] = temp;
+            ++Count;
+        }while (result->NextRow());
+
+        delete result;
+
+        outstring_log("");
+        outstring_log(">> Loaded %u EventAI summon definitions", Count);
+    }else
+    {
+        barGoLink bar(1);
+        bar.step();
+        outstring_log("");
+        outstring_log(">> Loaded 0 EventAI Summon definitions. DB table `eventai_summons` is empty.");
+    }
+
+    //Gather event data
+    result = TScriptDB.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
+        "event_param1, event_param2, event_param3, event_param4, "
+        "action1_type, action1_param1, action1_param2, action1_param3, "
+        "action2_type, action2_param1, action2_param2, action2_param3, "
+        "action3_type, action3_param1, action3_param2, action3_param3 "
+        "FROM eventai_scripts");
+
+    //Drop Existing EventAI List
+    EventAI_Event_List.clear();
+
+    outstring_log("TSCR: Loading EventAI_Scripts...");
+    if (result)
+    {
+        barGoLink bar(result->GetRowCount());
+        uint32 Count = 0;
+
+        do
+        {
+            bar.step();
+            Field *fields = result->Fetch();
+
+            EventAI_Event temp;
+
+            temp.event_id = fields[0].GetUInt32();
+            uint32 i = temp.event_id;
+            temp.creature_id = fields[1].GetUInt32();
+            temp.event_type = fields[2].GetUInt16();
+            temp.event_inverse_phase_mask = fields[3].GetUInt32();
+            temp.event_chance = fields[4].GetUInt8();
+            temp.event_flags = fields[5].GetUInt8();
+            temp.event_param1 = fields[6].GetUInt32();
+            temp.event_param2 = fields[7].GetUInt32();
+            temp.event_param3 = fields[8].GetUInt32();
+            temp.event_param4 = fields[9].GetUInt32();
+
+            //Report any errors in event
+            if (temp.event_type >= EVENT_T_END)
+                error_db_log("TSCR: Event %u has incorrect event type. Maybe DB requires updated version of SD2.", i);
+
+            //No chance of this event occuring
+            if (temp.event_chance == 0)
+                error_db_log("TSCR: Event %u has 0 percent chance. Event will never trigger!", i);
+
+            //Chance above 100, force it to be 100
+            if (temp.event_chance > 100)
             {
-                Localized_Text temp;
-                bar.step();
-                
-                Field *fields = result->Fetch();
-
-                uint32 i = fields[0].GetInt32();
-
-                temp.locale_1 = fields[1].GetString();
-                temp.locale_2 = fields[2].GetString();
-                temp.locale_3 = fields[3].GetString();
-                temp.locale_4 = fields[4].GetString();
-                temp.locale_5 = fields[5].GetString();
-                temp.locale_6 = fields[6].GetString();
-                temp.locale_7 = fields[7].GetString();
-                temp.locale_8 = fields[8].GetString();
-
-                EventAI_LocalizedTextMap[i] = temp;
-                ++count;
-
-            }while(result->NextRow());
-
-            delete result;
-
-            outstring_log("");
-            outstring_log("TSCR: Loaded %u EventAI Localized Texts", count);
-        }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI Localized Texts. Database table `eventai_localized_texts` is empty");
-
-        // Drop Existing Script Localized Text Hash Map
-        Script_LocalizedTextMap.clear();
-
-        // Gather Script Localized Texts
-        result = TScriptDB.PQuery("SELECT `id`,`locale_1`,`locale_2`,`locale_3`,`locale_4`,`locale_5`,`locale_6`,`locale_7`,`locale_8`"
-            "FROM `script_localized_texts`");
-
-        if(result)
-        {
-            outstring_log("TSCR: Loading Script Localized Texts....");
-            barGoLink bar(result->GetRowCount());
-            uint32 count = 0;
-
-            do
+                error_db_log("TSCR: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
+                temp.event_chance = 100;
+            }
+
+            //Individual event checks
+            switch (temp.event_type)
             {
-                Localized_Text temp;
-                bar.step();
-
-                Field *fields = result->Fetch();
-
-                uint32 i = fields[0].GetInt32();
-
-                temp.locale_1 = fields[1].GetString();
-                temp.locale_2 = fields[2].GetString();
-                temp.locale_3 = fields[3].GetString();
-                temp.locale_4 = fields[4].GetString();
-                temp.locale_5 = fields[5].GetString();
-                temp.locale_6 = fields[6].GetString();
-                temp.locale_7 = fields[7].GetString();
-                temp.locale_8 = fields[8].GetString();
-
-                Script_LocalizedTextMap[i] = temp;
-                ++count;
-
-            }while(result->NextRow());
-
-            delete result;
-
-            outstring_log("");
-            outstring_log("TSCR: Loaded %u Script Localized Texts", count);
-        }else outstring_log("TSCR: WARNING >> Loaded 0 Script Localized Texts. Database table `script_localized_texts` is empty");
-
-        //Drop existing EventAI Text hash map
-        EventAI_Text_Map.clear();
-
-        //Gather EventAI Text Entries
-        result = TScriptDB.PQuery("SELECT `id`,`text` FROM `eventai_texts`");
-
-        if (result)
-        {
-            outstring_log( "TSCR: Loading EventAI_Texts...");
-            barGoLink bar(result->GetRowCount());
-            uint32 Count = 0;
-
-            do
+                case EVENT_T_HP:
+                case EVENT_T_MANA:
+                case EVENT_T_TARGET_HP:
+                    {
+                        if (temp.event_param2 > 100)
+                            error_db_log("TSCR: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
+
+                        if (temp.event_param1 <= temp.event_param2)
+                            error_db_log("TSCR: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
+
+                        if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4)
+                        {
+                            error_db_log("TSCR: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
+                            temp.event_flags &= ~EFLAG_REPEATABLE;
+                        }
+                    }
+                    break;
+
+                case EVENT_T_SPELLHIT:
+                    {
+                        if (temp.event_param1)
+                        {
+                            SpellEntry const* pSpell = GetSpellStore()->LookupEntry(temp.event_param1);
+                            if (!pSpell)
+                            {
+                                error_db_log("TSCR: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i);
+                                continue;
+                            }
+
+                            if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask)
+                                error_db_log("TSCR: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i);
+                        }
+
+                        //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0
+                        //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit()
+                        if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL)
+                            error_db_log("TSCR: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i);
+
+                        if (temp.event_param4 < temp.event_param3)
+                            error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                    }
+                    break;
+
+                case EVENT_T_RANGE:
+                case EVENT_T_OOC_LOS:
+                case EVENT_T_FRIENDLY_HP:
+                case EVENT_T_FRIENDLY_IS_CC:
+                case EVENT_T_FRIENDLY_MISSING_BUFF:
+                    {
+                        if (temp.event_param4 < temp.event_param3)
+                            error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                    }
+                    break;
+
+                case EVENT_T_TIMER:
+                case EVENT_T_TIMER_OOC:
+                    {
+                        if (temp.event_param2 < temp.event_param1)
+                            error_db_log("TSCR: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
+
+                        if (temp.event_param4 < temp.event_param3)
+                            error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                    }
+                    break;
+
+                case EVENT_T_KILL:
+                case EVENT_T_TARGET_CASTING:
+                    {
+                        if (temp.event_param2 < temp.event_param1)
+                            error_db_log("TSCR: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                    }
+                    break;
+
+                case EVENT_T_AGGRO:
+                case EVENT_T_DEATH:
+                case EVENT_T_EVADE:
+                case EVENT_T_SPAWNED:
+                    {
+                        if (temp.event_flags & EFLAG_REPEATABLE)
+                        {
+                            error_db_log("TSCR: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
+                            temp.event_flags &= ~EFLAG_REPEATABLE;
+                        }
+                    }
+                    break;
+            }
+
+            for (uint32 j = 0; j < MAX_ACTIONS; j++)
             {
-                bar.step();
-                Field *fields = result->Fetch();
-
-                uint32 i = fields[0].GetInt32();
-
-                std::string text = fields[1].GetString();
-
-                if (!strlen(text.c_str()))
-                    error_db_log("TSCR: EventAI text %u is empty", i);
-
-                EventAI_Text_Map[i] = text;
-                ++Count;
-
-            }while (result->NextRow());
-
-            delete result;
-
-            outstring_log("");
-            outstring_log("TSCR: >> Loaded %u EventAI_Texts", Count);
-
-        }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI_Texts. DB table `EventAI_Texts` is empty.");
-
-        //Gather event data
-        result = TScriptDB.PQuery("SELECT `id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`"
-            "FROM `eventai_summons`");
-
-        //Drop Existing EventSummon Map
-        EventAI_Summon_Map.clear();
-
-        if (result)
-        {
-            outstring_log( "TSCR: Loading EventAI_Summons...");
-            barGoLink bar(result->GetRowCount());
-            uint32 Count = 0;
-
-            do
-            {
-                bar.step();
-                Field *fields = result->Fetch();
-
-                EventAI_Summon temp;
-
-                uint32 i = fields[0].GetUInt32();
-                temp.position_x = fields[1].GetFloat();
-                temp.position_y = fields[2].GetFloat();
-                temp.position_z = fields[3].GetFloat();
-                temp.orientation = fields[4].GetFloat();
-                temp.SpawnTimeSecs = fields[5].GetUInt32();
-
-                //Add to map
-                EventAI_Summon_Map[i] = temp;
-                ++Count;
-
-            }while (result->NextRow());
-
-            delete result;
-            outstring_log("");
-            outstring_log("TSCR: >> Loaded %u EventAI_Summons", Count);
-
-        }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI_Summons. DB table `EventAI_Summons` is empty.");
-
-        //Gather event data
-        result = TScriptDB.PQuery("SELECT `id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`"
-            "FROM `eventai_scripts`");
-
-        //Drop Existing EventAI List
-        EventAI_Event_List.clear();
-
-        if (result)
-        {
-            outstring_log( "TSCR: Loading EventAI_Scripts...");
-            barGoLink bar(result->GetRowCount());
-            uint32 Count = 0;
-
-            do
-            {
-                bar.step();
-                Field *fields = result->Fetch();
-
-                EventAI_Event temp;
-
-                temp.event_id = fields[0].GetUInt32();
-                uint32 i = temp.event_id;
-                temp.creature_id = fields[1].GetUInt32();
-                temp.event_type = fields[2].GetUInt16();
-                temp.event_inverse_phase_mask = fields[3].GetUInt32();
-                temp.event_chance = fields[4].GetUInt8();
-                temp.event_flags = fields[5].GetUInt8();
-                temp.event_param1 = fields[6].GetUInt32();
-                temp.event_param2 = fields[7].GetUInt32();
-                temp.event_param3 = fields[8].GetUInt32();
-                temp.event_param4 = fields[9].GetUInt32();
-
-                //Report any errors in event
-                if (temp.event_type >= EVENT_T_END)
-                    error_db_log("TSCR: Event %u has incorrect event type. Maybe DB requires updated version of SD2.", i);
-
-                //No chance of this event occuring
-                if (temp.event_chance == 0)
-                    error_db_log("TSCR: Event %u has 0 percent chance. Event will never trigger!", i);
-                //Chance above 100, force it to be 100
-                if (temp.event_chance > 100)
+                temp.action[j].type = fields[10+(j*4)].GetUInt16();
+                temp.action[j].param1 = fields[11+(j*4)].GetUInt32();
+                temp.action[j].param2 = fields[12+(j*4)].GetUInt32();
+                temp.action[j].param3 = fields[13+(j*4)].GetUInt32();
+
+                //Report any errors in actions
+                switch (temp.action[j].type)
                 {
-                    error_db_log("TSCR: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
-                    temp.event_chance = 100;
-                }
-
-                //Individual event checks
-                switch (temp.event_type)
-                {
-                    case EVENT_T_HP:
-                    case EVENT_T_MANA:
-                    case EVENT_T_TARGET_HP:
+                    case ACTION_T_SAY:
+                    case ACTION_T_YELL:
+                    case ACTION_T_TEXTEMOTE:
+                        if (GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT)
+                            error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1);
+                        break;
+
+                    case ACTION_T_SOUND:
+                        if (!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1))
+                            error_db_log("TSCR: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
+                        break;
+
+                    case ACTION_T_RANDOM_SAY:
+                    case ACTION_T_RANDOM_YELL:
+                    case ACTION_T_RANDOM_TEXTEMOTE:
+                        if ((temp.action[j].param1 != 0xffffffff && GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT) ||
+                            (temp.action[j].param2 != 0xffffffff && GetEventAIText(temp.action[j].param2) == DEFAULT_TEXT) ||
+                            (temp.action[j].param3 != 0xffffffff && GetEventAIText(temp.action[j].param3) == DEFAULT_TEXT))
+                            error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1);
+                        break;
+
+                    case ACTION_T_CAST:
                         {
-                            if (temp.event_param2 > 100)
-                                error_db_log("TSCR: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
-
-                            if (temp.event_param1 <= temp.event_param2)
-                                error_db_log("TSCR: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
-
-                            if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4)
-                            {
-                                error_db_log("TSCR: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
-                                temp.event_flags &= ~EFLAG_REPEATABLE;
-                            }
+                            if (!GetSpellStore()->LookupEntry(temp.action[j].param1))
+                                error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1);
+
+                            if (temp.action[j].param2 >= TARGET_T_END)
+                                error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
                         }
                         break;
 
-                    case EVENT_T_SPELLHIT:
+                    case ACTION_T_REMOVEAURASFROMSPELL:
                         {
-                            if (temp.event_param1)
-                            {
-                                SpellEntry const* pSpell = GetSpellStore()->LookupEntry(temp.event_param1);
-                                if (!pSpell)
-                                {
-                                    error_db_log("TSCR: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i);
-                                    continue;
-                                }
-
-                                if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask)
-                                    error_db_log("TSCR: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i);
-                            }
-
-                            //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0
-                            //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit()
-                            if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL)
-                                error_db_log("TSCR: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i);
-
-                            if (temp.event_param4 < temp.event_param3)
-                                error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                            if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
+                                error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
+
+                            if (temp.action[j].param1 >= TARGET_T_END)
+                                error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
                         }
                         break;
 
-                    case EVENT_T_RANGE:
-                    case EVENT_T_OOC_LOS:
-                    case EVENT_T_FRIENDLY_HP:
-                    case EVENT_T_FRIENDLY_IS_CC:
-                    case EVENT_T_FRIENDLY_MISSING_BUFF:
+                    case ACTION_T_CASTCREATUREGO:
                         {
-                            if (temp.event_param4 < temp.event_param3)
-                                error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                            if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
+                                error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
+
+                            if (temp.action[j].param3 >= TARGET_T_END)
+                                error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
                         }
                         break;
 
-                    case EVENT_T_TIMER:
-                    case EVENT_T_TIMER_OOC:
+                    //2nd param target
+                    case ACTION_T_SUMMON_ID:
                         {
-                            if (temp.event_param2 < temp.event_param1)
-                                error_db_log("TSCR: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
-
-                            if (temp.event_param4 < temp.event_param3)
-                                error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
+                            if (EventAI_Summon_Map.find(temp.action[j].param3) == EventAI_Summon_Map.end())
+                                error_db_log("TSCR: Event %u Action %u summons missing EventAI_Summon %u", i, j+1, temp.action[j].param3);
+
+                            if (temp.action[j].param2 >= TARGET_T_END)
+                                error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
                         }
                         break;
 
-                    case EVENT_T_KILL:
-                    case EVENT_T_TARGET_CASTING:
-                        {
-                            if (temp.event_param2 < temp.event_param1)
-                                error_db_log("TSCR: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
-                        }
+                    case ACTION_T_SUMMON:
+                    case ACTION_T_THREAT_SINGLE_PCT:
+                    case ACTION_T_QUEST_EVENT:
+                    case ACTION_T_SET_UNIT_FLAG:
+                    case ACTION_T_REMOVE_UNIT_FLAG:
+                    case ACTION_T_SET_INST_DATA64:
+                        if (temp.action[j].param2 >= TARGET_T_END)
+                            error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
                         break;
 
-                    case EVENT_T_AGGRO:
-                    case EVENT_T_DEATH:
-                    case EVENT_T_EVADE:
-                    case EVENT_T_SPAWNED:
-                        {
-                            if (temp.event_flags & EFLAG_REPEATABLE)
-                            {
-                                error_db_log("TSCR: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
-                                temp.event_flags &= ~EFLAG_REPEATABLE;
-                            }
-                        }
+                    //3rd param target
+                    case ACTION_T_SET_UNIT_FIELD:
+                        if (temp.action[j].param3 >= TARGET_T_END)
+                            error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
                         break;
-                };
-
-                for (uint32 j = 0; j < MAX_ACTIONS; j++)
-                {
-                    temp.action[j].type = fields[10+(j*4)].GetUInt16();
-                    temp.action[j].param1 = fields[11+(j*4)].GetUInt32();
-                    temp.action[j].param2 = fields[12+(j*4)].GetUInt32();
-                    temp.action[j].param3 = fields[13+(j*4)].GetUInt32();
-
-                    //Report any errors in actions
-                    switch (temp.action[j].type)
-                    {
-                        case ACTION_T_SAY:
-                        case ACTION_T_YELL:
-                        case ACTION_T_TEXTEMOTE:
-                            if (GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT)
-                                error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1);
-                            break;
-
-                        case ACTION_T_SOUND:
-                            if (!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1))
-                                error_db_log("TSCR: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
-                            break;
-
-                        case ACTION_T_RANDOM_SAY:
-                        case ACTION_T_RANDOM_YELL:
-                        case ACTION_T_RANDOM_TEXTEMOTE:
-                            if ((temp.action[j].param1 != 0xffffffff && GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT) ||
-                                (temp.action[j].param2 != 0xffffffff && GetEventAIText(temp.action[j].param2) == DEFAULT_TEXT) ||
-                                (temp.action[j].param3 != 0xffffffff && GetEventAIText(temp.action[j].param3) == DEFAULT_TEXT))
-                                error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1);
-                            break;
-
-                        case ACTION_T_CAST:
-                            {
-                                if (!GetSpellStore()->LookupEntry(temp.action[j].param1))
-                                    error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1);
-
-                                if (temp.action[j].param2 >= TARGET_T_END)
-                                    error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
-                            }
-                            break;
-
-                        case ACTION_T_REMOVEAURASFROMSPELL:
-                            {
-                                if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
-                                    error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
-
-                                if (temp.action[j].param1 >= TARGET_T_END)
-                                    error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
-                            }
-                            break;
-
-                        case ACTION_T_CASTCREATUREGO:
-                            {
-                                if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
-                                    error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
-
-                                if (temp.action[j].param3 >= TARGET_T_END)
-                                    error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
-                            }
-                            break;
-
-                        //2nd param target
-                        case ACTION_T_SUMMON_ID:
-                            {
-                                if (EventAI_Summon_Map.find(temp.action[j].param3) == EventAI_Summon_Map.end())
-                                    error_db_log("TSCR: Event %u Action %u summons missing EventAI_Summon %u", i, j+1, temp.action[j].param3);
-
-                                if (temp.action[j].param2 >= TARGET_T_END)
-                                    error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
-                            }
-                            break;
-
-                        case ACTION_T_SUMMON:
-                        case ACTION_T_THREAT_SINGLE_PCT:
-                        case ACTION_T_QUEST_EVENT:
-                        case ACTION_T_SET_UNIT_FLAG:
-                        case ACTION_T_REMOVE_UNIT_FLAG:
-                        case ACTION_T_SET_INST_DATA64:
-                            if (temp.action[j].param2 >= TARGET_T_END)
-                                error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
-                            break;
-
-                        //3rd param target
-                        case ACTION_T_SET_UNIT_FIELD:
-                            if (temp.action[j].param3 >= TARGET_T_END)
-                                error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1);
-                            break;
-
-                        case ACTION_T_SET_PHASE:
-                            if (temp.action[j].param1 > 31)
-                                error_db_log("TSCR: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1);
-                            break;
-
-                        case ACTION_T_INC_PHASE:
-                            if (!temp.action[j].param1)
-                                error_db_log("TSCR: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
-                            break;
-
-                        case ACTION_T_KILLED_MONSTER:
-                            if (temp.event_type != EVENT_T_DEATH)
-                                outstring_log("TSCR WARNING: Event %u Action %u calling ACTION_T_KILLED_MONSTER outside of EVENT_T_DEATH", i, j+1);
-                            break;
-
-                        case ACTION_T_SET_INST_DATA:
-                            if (temp.action[j].param2 > 3)
-                                error_db_log("TSCR: Event %u Action %u attempts to set instance data above encounter state 3. Custom case?", i, j+1);
-                            break;
-
-                        default:
-                            break;
-                    }
-
-                    if (temp.action[j].type >= ACTION_T_END)
-                        error_db_log("TSCR: Event %u Action %u has incorrect action type. Maybe DB requires updated version of SD2.", i, j+1);
+
+                    case ACTION_T_SET_PHASE:
+                        if (temp.action[j].param1 > 31)
+                            error_db_log("TSCR: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1);
+                        break;
+
+                    case ACTION_T_INC_PHASE:
+                        if (!temp.action[j].param1)
+                            error_db_log("TSCR: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
+                        break;
+
+                    case ACTION_T_KILLED_MONSTER:
+                        if (temp.event_type != EVENT_T_DEATH)
+                            outstring_log("SD2 WARNING: Event %u Action %u calling ACTION_T_KILLED_MONSTER outside of EVENT_T_DEATH", i, j+1);
+                        break;
+
+                    case ACTION_T_SET_INST_DATA:
+                        if (temp.action[j].param2 > 3)
+                            error_db_log("TSCR: Event %u Action %u attempts to set instance data above encounter state 3. Custom case?", i, j+1);
+                        break;
+
+                    default:
+                        if (temp.action[j].type >= ACTION_T_END)
+                            error_db_log("TSCR: Event %u Action %u has incorrect action type. Maybe DB requires updated version of SD2.", i, j+1);
+                        break;
                 }
-
-                //Add to list
-                EventAI_Event_List.push_back(temp);
-                ++Count;
-
-            }while (result->NextRow());
-
-            delete result;
-            outstring_log("");
-            outstring_log("TSCR: >> Loaded %u EventAI_Events", Count);
-
-        }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI_Scripts. DB table `EventAI_Scripts` is empty.");
-
-        // Gather Script Text 
-        result = TScriptDB.PQuery("SELECT `id`, `sound`, `type`, `language`, `text`"
-            "FROM `script_texts`;");
-
-        // Drop Existing Script Text Map
-        Script_TextMap.clear();
-
-        if(result)
-        {
-            outstring_log("TSCR: Loading Script Text...");
-            barGoLink bar(result->GetRowCount());
-            uint32 count = 0;
-
-            do
-            {
-                bar.step();
-                Field* fields = result->Fetch();
-                ScriptText temp;
-
-                uint32 i            = fields[0].GetInt32();
-                temp.SoundId        = fields[1].GetInt32();
-                temp.Type           = fields[2].GetInt32();
-                temp.Language       = fields[3].GetInt32();
-                temp.Text           = fields[4].GetString();
-
-                if (temp.SoundId)
-                {
-                    if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId))
-                        error_db_log("TSCR: Id %u in table script_texts has soundid %u but sound does not exist.",i,temp.SoundId);
-                }
-
-                if(!strlen(temp.Text.c_str()))
-                    error_db_log("TSCR: Id %u in table script_texts has no text.", i);
-
-                Script_TextMap[i] = temp;
-                ++count;
-
-            }while(result->NextRow());
-
-            delete result;
-
-            outstring_log("");
-            outstring_log("TSCR: Loaded %u Script Texts", count);
-
-        }else outstring_log("TSCR WARNING >> Loaded 0 Script Texts. Database table `script_texts` is empty.");
-
-        //Free database thread and resources
-        TScriptDB.HaltDelayThread();
-
-        //***End DB queries***
+            }
+
+            //Add to list
+            EventAI_Event_List.push_back(temp);
+            ++Count;
+        } while (result->NextRow());
+
+        delete result;
+
+        outstring_log("");
+        outstring_log(">> Loaded %u EventAI scripts", Count);
+    }else
+    {
+        barGoLink bar(1);
+        bar.step();
+        outstring_log("");
+        outstring_log(">> Loaded 0 EventAI scripts. DB table `eventai_scripts` is empty.");
     }
+
+    //Free database thread and resources
+    TScriptDB.HaltDelayThread();
+
 }
 
 struct TSpellSummary {
-    uint8 Targets;    // set of enum SelectTarget
-    uint8 Effects;    // set of enum SelectEffect 
+    uint8 Targets;                                          // set of enum SelectTarget
+    uint8 Effects;                                          // set of enum SelectEffect 
 }extern *SpellSummary;
 
@@ -1120,4 +1195,6 @@
 void ScriptsInit()
 {
+    bool CanLoadDB = true;
+
     //Trinity Script startup
     outstring_log(" _____     _       _ _         ____            _       _");
@@ -1132,7 +1209,9 @@
     //Get configuration file
     if (!TScriptConfig.SetSource(_TRINITY_SCRIPT_CONFIG))
-        error_log("TSCR: Unable to open configuration file, Database will be unaccessible");
-    else outstring_log("TSCR: Using configuration file %s", _TRINITY_SCRIPT_CONFIG);
-
+    {
+        CanLoadDB = false;
+        error_log("TSCR: Unable to open configuration file. Database will be unaccessible. Configuration values will use default.");
+    }
+    else outstring_log("TSCR: Using configuration file %s",_TRINITY_SCRIPT_CONFIG);
 
     //Check config file version
@@ -1150,31 +1229,34 @@
 
     outstring_log("TSCR: Using locale %u", Locale);
+
+    EAI_ErrorLevel = TScriptConfig.GetIntDefault("EAIErrorLevel", 1);
+
+    switch (EAI_ErrorLevel)
+    {
+    case 0:
+        outstring_log("TSCR: EventAI Error Reporting level set to 0 (Startup Errors only)");
+        break;
+    case 1:
+        outstring_log("TSCR: EventAI Error Reporting level set to 1 (Startup errors and Runtime event errors)");
+        break;
+    case 2:
+        outstring_log("TSCR: EventAI Error Reporting level set to 2 (Startup errors, Runtime event errors, and Creation errors)");
+        break;
+    default:
+        outstring_log("TSCR: Unknown EventAI Error Reporting level. Defaulting to 1 (Startup errors and Runtime event errors)");
+        EAI_ErrorLevel = 1;
+        break;
+    }
+
     outstring_log("");
 
-    EAI_ErrorLevel = TScriptConfig.GetIntDefault("EAIErrorLevel", 1);
-
-    switch (EAI_ErrorLevel)
-    {
-        case 0:
-            outstring_log("TSCR: EventAI Error Reporting level set to 0 (Startup Errors only)");
-            break;
-
-        case 1:
-            outstring_log("TSCR: EventAI Error Reporting level set to 1 (Startup errors and Runtime event errors)");
-            break;
-
-        case 2:
-            outstring_log("TSCR: EventAI Error Reporting level set to 2 (Startup errors, Runtime event errors, and Creation errors)");
-            break;
-
-        default:
-            outstring_log("TSCR: Unknown EventAI Error Reporting level. Defaulting to 1 (Startup errors and Runtime event errors)");
-            EAI_ErrorLevel = 1;
-            break;
-    }
+    //Load database (must be called after TScriptConfig.SetSource). In case it failed, no need to even try load.
+    if (CanLoadDB)
+        LoadDatabase();
+
+    outstring_log("TSCR: Loading C++ scripts");
+    barGoLink bar(1);
+    bar.step();
     outstring_log("");
-
-    //Load database (must be called after TScriptConfig.SetSource)
-    LoadDatabase();
 
     nrscripts = 0;
@@ -1756,57 +1838,4 @@
 }
 
-const char* GetScriptLocalizedText(uint32 entry)
-{   
-    const char* temp = NULL;
-
-    HM_NAMESPACE::hash_map<uint32, Localized_Text>::iterator i = Script_LocalizedTextMap.find(entry);
-
-    if (i == Script_LocalizedTextMap.end())
-    {
-        error_log("TSCR: Script Localized Text %u not found", entry);
-        return DEFAULT_TEXT;
-    }
-
-    switch (Locale)
-    {
-        case 1:
-            temp =  (*i).second.locale_1.c_str();
-            break;
-
-        case 2:
-            temp =  (*i).second.locale_2.c_str();
-            break;
-
-        case 3:
-            temp =  (*i).second.locale_3.c_str();
-            break;
-
-        case 4:
-            temp =  (*i).second.locale_4.c_str();
-            break;
-
-        case 5:
-            temp =  (*i).second.locale_5.c_str();
-            break;
-
-        case 6:
-            temp =  (*i).second.locale_6.c_str();
-            break;
-
-        case 7:
-            temp =  (*i).second.locale_7.c_str();
-            break;
-
-        case 8:
-            temp =  (*i).second.locale_8.c_str();
-            break;
-    };
-
-    if (strlen(temp))
-        return temp;
-
-    return DEFAULT_TEXT;
-}
-
 const char* GetEventAIText(uint32 entry)
 {
@@ -1834,28 +1863,34 @@
 }
 
-void ProcessScriptText(uint32 id, WorldObject* pSource, Unit* target)
+void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
 {
     if (!pSource)
     {
-        error_log("TSCR: ProcessScriptText invalid Source pointer.");
+        error_log("TSCR: DoScriptText entry %i, invalid Source pointer.",textEntry);
         return;
     }
 
-    HM_NAMESPACE::hash_map<uint32, ScriptText>::iterator i = Script_TextMap.find(id);
-
-    if (i == Script_TextMap.end())
-    {
-        error_log("TSCR: ProcessScriptText could not find id %u.",id);
+    if (textEntry >= 0)
+    {
+        error_log("TSCR: DoScriptText attempts to process entry %i, but entry must be negative.",textEntry);
         return;
     }
 
+    HM_NAMESPACE::hash_map<int32, StringTextData>::iterator i = TextMap.find(textEntry);
+
+    if (i == TextMap.end())
+    {
+        error_log("TSCR: DoScriptText could not find text entry %i.",textEntry);
+        return;
+    }
+
     if((*i).second.SoundId)
     {
-        if(GetSoundEntriesStore()->LookupEntry((*i).second.SoundId))
+        if( GetSoundEntriesStore()->LookupEntry((*i).second.SoundId) )
         {
             pSource->SendPlaySound((*i).second.SoundId, false);
         }
         else
-            error_log("TSCR: ProcessScriptText id %u tried to process invalid soundid %u.",id,(*i).second.SoundId);
+            error_log("TSCR: DoScriptText entry %i tried to process invalid sound id %u.",textEntry,(*i).second.SoundId);
     }
 
@@ -1863,31 +1898,26 @@
     {
         case CHAT_TYPE_SAY:
-            pSource->MonsterSay((*i).second.Text.c_str(), (*i).second.Language, target ? target->GetGUID() : 0);
+            pSource->MonsterSay(textEntry, (*i).second.Language, target ? target->GetGUID() : 0);
             break;
-
         case CHAT_TYPE_YELL:
-            pSource->MonsterYell((*i).second.Text.c_str(), (*i).second.Language, target ? target->GetGUID() : 0);
+            pSource->MonsterYell(textEntry, (*i).second.Language, target ? target->GetGUID() : 0);
             break;
-
         case CHAT_TYPE_TEXT_EMOTE:
-            pSource->MonsterTextEmote((*i).second.Text.c_str(), target ? target->GetGUID() : 0);
+            pSource->MonsterTextEmote(textEntry, target ? target->GetGUID() : 0);
             break;
-
         case CHAT_TYPE_BOSS_EMOTE:
-            pSource->MonsterTextEmote((*i).second.Text.c_str(), target ? target->GetGUID() : 0, true);
+            pSource->MonsterTextEmote(textEntry, target ? target->GetGUID() : 0, true);
             break;
-
         case CHAT_TYPE_WHISPER:
             {
                 if (target && target->GetTypeId() == TYPEID_PLAYER)
-                    pSource->MonsterWhisper((*i).second.Text.c_str(), target->GetGUID());
-                else error_log("TSCR: ProcessScriptText id %u cannot whisper without target unit (TYPEID_PLAYER).", id);
+                    pSource->MonsterWhisper(textEntry, target->GetGUID());
+                else error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
             }break;
-
         case CHAT_TYPE_BOSS_WHISPER:
             {
                 if (target && target->GetTypeId() == TYPEID_PLAYER)
-                    pSource->MonsterWhisper((*i).second.Text.c_str(), target->GetGUID(), true);
-                else error_log("TSCR: ProcessScriptText id %u cannot whisper without target unit (TYPEID_PLAYER).", id);
+                    pSource->MonsterWhisper(textEntry, target->GetGUID(), true);
+                else error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry);
             }break;
     }
Index: /trunk/src/bindings/scripts/sql/scriptdev2_structure.sql
===================================================================
--- /trunk/src/bindings/scripts/sql/scriptdev2_structure.sql (revision 5)
+++ /trunk/src/bindings/scripts/sql/scriptdev2_structure.sql (revision 28)
@@ -74,29 +74,39 @@
 DROP TABLE IF EXISTS `script_texts`;
 CREATE TABLE `script_texts` (
-`id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier',
-`sound` int(11) unsigned NOT NULL default '0',
-`type` int(11) unsigned NOT NULL default '0',
-`language` int(11) unsigned NOT NULL default '0',
-`text` varchar(255) NOT NULL default '',
-`comment` varchar(255) NOT NULL default '',
-PRIMARY KEY  (`id`)
+  `entry` mediumint(8) NOT NULL,
+  `content_default` text NOT NULL,
+  `content_loc1` text,
+  `content_loc2` text,
+  `content_loc3` text,
+  `content_loc4` text,
+  `content_loc5` text,
+  `content_loc6` text,
+  `content_loc7` text,
+  `content_loc8` text,
+  `sound` mediumint(8) unsigned NOT NULL default '0',
+  `type` tinyint unsigned NOT NULL default '0',
+  `language` tinyint unsigned NOT NULL default '0',
+  `comment` text,
+  PRIMARY KEY  (`entry`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Texts';
 
-
-DROP TABLE IF EXISTS `script_localized_texts`;
-CREATE TABLE `script_localized_texts` (
-`id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier',
-`locale_1` varchar(255) NOT NULL default '',
-`locale_2` varchar(255) NOT NULL default '',
-`locale_3` varchar(255) NOT NULL default '',
-`locale_4` varchar(255) NOT NULL default '',
-`locale_5` varchar(255) NOT NULL default '',
-`locale_6` varchar(255) NOT NULL default '',
-`locale_7` varchar(255) NOT NULL default '',
-`locale_8` varchar(255) NOT NULL default '',
-`comment` varchar(255) NOT NULL default '' COMMENT 'Text Comment',
-PRIMARY KEY  (`id`)            
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Localized Script Text';
-
+DROP TABLE IF EXISTS `custom_texts`;
+CREATE TABLE `custom_texts` (
+  `entry` mediumint(8) NOT NULL,
+  `content_default` text NOT NULL,
+  `content_loc1` text,
+  `content_loc2` text,
+  `content_loc3` text,
+  `content_loc4` text,
+  `content_loc5` text,
+  `content_loc6` text,
+  `content_loc7` text,
+  `content_loc8` text,
+  `sound` mediumint(8) unsigned NOT NULL default '0',
+  `type` tinyint unsigned NOT NULL default '0',
+  `language` tinyint unsigned NOT NULL default '0',
+  `comment` text,
+  PRIMARY KEY  (`entry`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Custom Texts';
 
 DROP TABLE IF EXISTS `script_db_version`;
Index: /trunk/src/bindings/scripts/ScriptMgr.h
===================================================================
--- /trunk/src/bindings/scripts/ScriptMgr.h (revision 5)
+++ /trunk/src/bindings/scripts/ScriptMgr.h (revision 28)
@@ -1,5 +1,5 @@
 /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
-* This program is free software licensed under GPL version 2
-* Please see the included DOCS/LICENSE.TXT for more information */
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
 
 #ifndef SCRIPTMGR_H
@@ -22,12 +22,8 @@
 class WorldObject;
 
-#define MAX_SCRIPTS     1000            //72 bytes each (approx 71kb)
+#define MAX_SCRIPTS         1000                            //72 bytes each (approx 71kb)
+#define VISIBLE_RANGE       (166.0f)                        //MAX visible range (size of grid)
+#define DEFAULT_TEXT        "<Trinity Script Text Entry Missing!>"
 
-//MAX visible range (size of grid)
-#define VISIBLE_RANGE   (166.0f)
-
-#define DEFAULT_TEXT    "<Trinity Script Text Entry Missing!>"
-
-//
 struct Script
 {
@@ -41,5 +37,5 @@
 std::string Name;
 
-// -- Quest/gossip Methods to be scripted --
+// Quest/gossip Methods to be scripted
 bool (*pGossipHello         )(Player*, Creature*);
 bool (*pQuestAccept         )(Player*, Creature*, Quest const* );
@@ -62,5 +58,4 @@
 CreatureAI* (*GetAI)(Creature*);
 InstanceData* (*GetInstanceData)(Map*);
-// -----------------------------------------
 };
 
@@ -70,11 +65,10 @@
 // Localized Text function
 const char* GetEventAILocalizedText(uint32 entry);
-const char* GetScriptLocalizedText(uint32 entry);
 
 //EventAI text function
-const char* GetEventAIText(uint32 entry); // TODO: Locales
+const char* GetEventAIText(uint32 entry);                   // TODO: Locales
 
-// Script Text function
-void ProcessScriptText(uint32 id, WorldObject* pSource, Unit* target = NULL); // TODO: Locales
+//Generic scripting text function
+void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target = NULL);
 
 #if COMPILER == COMPILER_GNU
Index: /trunk/sql/mangos.sql
===================================================================
--- /trunk/sql/mangos.sql (revision 18)
+++ /trunk/sql/mangos.sql (revision 28)
@@ -211,5 +211,6 @@
 ('explorecheat',3,'Syntax: .explorecheat #flag\r\n\r\nReveal  or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\n\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'),
 ('flusharenapoints',3,'Syntax: .flusharenapoints\r\n\r\nUse it to distribute arena points based on arena team ratings, and start a new week.'),
-('gm',1,'Syntax: .gm on/off\r\n\r\nEnable or Disable GM MODE'),
+('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'),
+('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'),
 ('gm fly',3,'Syntax: .gm fly on/off\r\nEnable/disable gm fly mode.'),
 ('gm list',0,'Syntax: .gm list\r\n\r\nDisplay a list of available Game Masters.'),
@@ -353,5 +354,5 @@
 ('saveall',1,'Syntax: .saveall\r\n\r\nSave all characters in game.'),
 ('security',3,'Syntax: .security $name #level\r\n\r\nSet the security level of player $name to a level of #level.\r\n\r\n#level may range from 0 to 5.'),
-('sendmail',1,'Syntax: .sendmail #playername #subject #text\r\n\r\nSend a mail to a player. Note: subject may not contain spaces.'),
+('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'),
 ('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'),
 ('server idleshutdown',3,'Syntax: .server idleshutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'),
@@ -2138,4 +2139,6 @@
 (50,'You must be at least level %u and have item %s to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (51,'Hello! Ready for some training?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(52,'Invaid item count (%u) for item %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(53,'Mail can\'t have more %u item stacks',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (100,'Global notify: ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f\ngrid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
@@ -2340,4 +2343,8 @@
 (330,'No players found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (331,'Extended item cost %u not exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(332,'GM mode is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(333,'GM mode is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(334,'GM Chat Badge is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(335,'GM Chat Badge is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (401,'You change security level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
@@ -2579,20 +2586,35 @@
 (711,'Your group is too large for this battleground. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
 (712,'Your group is too large for this arena. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(713,'Your group has members not in your arena team. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(714,'Your group does not have enough players to join this match.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(715,'The Gold Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(716,'The Green Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(717, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(718, 'Your group has an offline member. Please remove him before joining.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(719, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(720, 'Your group has players from different battleground brakets. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(721, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(722, 'Someone in your party is Deserter. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(723, 'Someone in your party is already in three battleground queues. You cannot join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(724, 'You cannot teleport to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(725, 'You cannot summon players to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(726, 'You must be in GM mode to teleport to a player in a battleground.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(727, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
-(728, 'Arena testing turned %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+(713,'You must be level %u to join an arena team!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(714,'%s is not high enough level to join your team',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(715,'You don\'t meet Battleground level requirements',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(716,'Your arena team is full, %s cannot join it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(730,'Your group has members not in your arena team. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(731,'Your group does not have enough players to join this match.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(732,'The Gold Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(733,'The Green Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(734, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(735, 'Your group has an offline member. Please remove him before joining.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(736, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(737, 'Your group has players from different battleground brakets. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(738, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(739, 'Someone in your party is Deserter. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(740, 'Someone in your party is already in three battleground queues. You cannot join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(741, 'You cannot teleport to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(742, 'You cannot summon players to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(743, 'You must be in GM mode to teleport to a player in a battleground.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(744, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(745, 'Arena testing turned %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(800,'Invalid name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(801,'You do not have enough gold',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(802,'You do not have enough free slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(803,'Your partner does not have enough free bag slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(804,'You do not have permission to perform that function',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(805,'Unknown language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(806,'You don\'t know that language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(807,'Please provide character name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(808,'Player %s not found or offline',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
+(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+
 /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;
 UNLOCK TABLES;
Index: /trunk/sql/updates/10_instantiated_battlegrounds.sql
===================================================================
--- /trunk/sql/updates/10_instantiated_battlegrounds.sql (revision 9)
+++ /trunk/sql/updates/10_instantiated_battlegrounds.sql (revision 28)
@@ -16,23 +16,24 @@
 
 
-DELETE FROM mangos_string WHERE entry BETWEEN 711 AND 728;
+DELETE FROM mangos_string WHERE entry IN (711,712);
+DELETE FROM mangos_string WHERE entry BETWEEN 730 AND 745;
 INSERT INTO mangos_string (entry, content_default) VALUES
     (711,'Your group is too large for this battleground. Please regroup to join.'),
     (712,'Your group is too large for this arena. Please regroup to join.'),
-    (713,'Your group has members not in your arena team. Please regroup to join.'),
-    (714,'Your group does not have enough players to join this match.'),
-    (715,'The Gold Team wins!'),
-    (716,'The Green Team wins!'),
-    (717, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.'),
-    (718, 'Your group has an offline member. Please remove him before joining.'),
-    (719, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.'),
-    (720, 'Your group has players from different battleground brakets. You can\'t join as group.'),
-    (721, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.'),
-    (722, 'Someone in your party is Deserter. You can\'t join as group.'),
-    (723, 'Someone in your party is already in three battleground queues. You cannot join as group.'),
-    (724, 'You cannot teleport to a battleground or arena map.'),
-    (725, 'You cannot summon players to a battleground or arena map.'),
-    (726, 'You must be in GM mode to teleport to a player in a battleground.'),
-    (727, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.'),
-    (728, 'Arena testing turned %s');
+    (730,'Your group has members not in your arena team. Please regroup to join.'),
+    (731,'Your group does not have enough players to join this match.'),
+    (732,'The Gold Team wins!'),
+    (733,'The Green Team wins!'),
+    (734, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.'),
+    (735, 'Your group has an offline member. Please remove him before joining.'),
+    (736, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.'),
+    (737, 'Your group has players from different battleground brakets. You can\'t join as group.'),
+    (738, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.'),
+    (739, 'Someone in your party is Deserter. You can\'t join as group.'),
+    (740, 'Someone in your party is already in three battleground queues. You cannot join as group.'),
+    (741, 'You cannot teleport to a battleground or arena map.'),
+    (742, 'You cannot summon players to a battleground or arena map.'),
+    (743, 'You must be in GM mode to teleport to a player in a battleground.'),
+    (744, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.'),
+    (745, 'Arena testing turned %s');
     
Index: /unk/sql/updates/19_pack.sql
===================================================================
--- /trunk/sql/updates/19_pack.sql (revision 18)
+++  (revision )
@@ -1,4 +1,0 @@
-ALTER TABLE `quest_template` ADD COLUMN `Method` tinyint(3) unsigned NOT NULL default '2' AFTER `entry`;
-DELETE FROM mangos_string WHERE entry IN (331);
-INSERT INTO mangos_string VALUES
-(331,'Extended item cost %u not exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
Index: /trunk/sql/characters.sql
===================================================================
--- /trunk/sql/characters.sql (revision 10)
+++ /trunk/sql/characters.sql (revision 28)
@@ -177,5 +177,5 @@
   `trans_o` float NOT NULL default '0',
   `transguid` bigint(20) unsigned NOT NULL default '0',
-  `gmstate` tinyint(3) unsigned NOT NULL default '0',
+  `gmstate` int(11) unsigned NOT NULL default '0',
   `stable_slots` tinyint(1) unsigned NOT NULL default '0',
   `at_login` int(11) unsigned NOT NULL default '0',
