Index: src/shared/Database/DBCfmt.cpp
===================================================================
--- src/shared/Database/DBCfmt.cpp	(revision 5236)
+++ src/shared/Database/DBCfmt.cpp	(working copy)
@@ -47,7 +47,7 @@
 const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiii";
 const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
 const char LockEntryfmt[]="niiiiixxxiiiiixxxiixxxxxxxxxxxxxx";
-const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxx";
+const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxiix";
 const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxi";
 const char SkillLineAbilityfmt[]="xiniixxiixiixxi";
 const char SpellCastTimefmt[]="nixx";
Index: src/shared/Database/DBCStructure.h
===================================================================
--- src/shared/Database/DBCStructure.h	(revision 5236)
+++ src/shared/Database/DBCStructure.h	(working copy)
@@ -368,7 +368,10 @@
     int32       parent_map;                                 // 117 map_id of parent map
     //float start_x                                         // 118 enter x coordinate (if exist single entry)
     //float start_y                                         // 119 enter y coordinate (if exist single entry)
-                                                            // 120-122
+
+    uint32 resetTimeRaid;
+    uint32 resetTimeHeroic;
+                                                            //122
 };
 
 inline bool IsExpansionMap(MapEntry const* map)
Index: src/shared/Database/SQLStorage.cpp
===================================================================
--- src/shared/Database/SQLStorage.cpp	(revision 5236)
+++ src/shared/Database/SQLStorage.cpp	(working copy)
@@ -28,9 +28,9 @@
 #endif
 
 const char CreatureInfofmt[]="iiiiissiiiiiiiiiififfiiiiiiiiiiiffiiliiiiiiiiiiiiiiiisiillis";
-const char CreatureDataAddonInfofmt[]="iiiiiis";
+const char CreatureDataAddonInfofmt[]="iiiiiiis";
 const char CreatureModelfmt[]="iffii";
-const char CreatureInfoAddonInfofmt[]="iiiiiis";
+const char CreatureInfoAddonInfofmt[]="iiiiiiis";
 const char EquipmentInfofmt[]="iiiiiiiiii";
 const char GameObjectInfofmt[]="iiisiifiiiiiiiiiiiiiiiiiiiiiiiis";
 const char ItemPrototypefmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii";
Index: src/mangosd/mangosd.conf.in
===================================================================
--- src/mangosd/mangosd.conf.in	(revision 5236)
+++ src/mangosd/mangosd.conf.in	(working copy)
@@ -194,6 +194,10 @@
 # Default: 0 (false)
 Instance.IgnoreRaid = 0
 
+# Time reset non-raid and non-heroic instance
+# Default: 4
+Instance.ResetTimeHours = 4;
+
 #  quest level difference to hide for player low level quests: if player_level > quest_level + LowLevelQuestsHideDiff then quest ! mark not show for quest giver
 #          -1 (show all available quests marks) 
 # Default: 4 
@@ -407,6 +411,10 @@
 Rate.Mining.Amount = 1
 Rate.Mining.Next   = 1
 
+# Reset time instance Rates
+# Default: 1
+Rate.InstanceResetTime = 1
+
 # Talent Point rates
 # Default: 1
 Rate.Talent = 1
Index: src/game/Object.cpp
===================================================================
--- src/game/Object.cpp	(revision 5236)
+++ src/game/Object.cpp	(working copy)
@@ -869,6 +869,7 @@
 
     m_mapId             = 0;
     m_InstanceId        = 0;
+    m_instanceMode = INSTANCEMODE_NORMAL;
 
     m_name = "";
 
@@ -893,12 +894,12 @@
 
 uint32 WorldObject::GetZoneId() const
 {
-    return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY);
+    return MapManager::Instance().GetBaseMap(m_mapId, m_instanceMode)->GetZoneId(m_positionX,m_positionY);
 }
 
 uint32 WorldObject::GetAreaId() const
 {
-    return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY);
+    return MapManager::Instance().GetBaseMap(m_mapId, m_instanceMode)->GetAreaId(m_positionX,m_positionY);
 }
 
 InstanceData* WorldObject::GetInstanceData()
@@ -1047,9 +1048,13 @@
 
 void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
 {
-    float new_z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(x,y,z,true);
-    if(new_z > INVALID_HEIGHT)
-        z = new_z+ 0.05f;                                   // just to be sure that we are not a few pixel under the surface
+    if(VMAP::VMapFactory::createOrGetVMapManager()->isHeightCalcEnabled())
+    {
+        //float new_z = MapManager::Instance().GetBaseMap(GetMapId(), 0)->GetVMapHeight(x,y,z);
+         float new_z = MapManager::Instance().GetBaseMap(GetMapId(),0)->GetHeight(x,y,z,true);
+        if(new_z > VMAP_INVALID_HEIGHT)
+            z = new_z+ 0.05f;                               // just to be sure that we are not a few pixel under the surface
+    }
 }
 
 bool WorldObject::IsPositionValid() const
@@ -1186,7 +1191,7 @@
 
 Map const* WorldObject::GetBaseMap() const
 {
-    return MapManager::Instance().GetBaseMap(GetMapId());
+    return MapManager::Instance().GetBaseMap(GetMapId(), GetInstanceMode());
 }
 
 Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime)
Index: src/game/MapInstanced.h
===================================================================
--- src/game/MapInstanced.h	(revision 5236)
+++ src/game/MapInstanced.h	(working copy)
@@ -25,7 +25,7 @@
 {
     public:
 
-        MapInstanced(uint32 id, time_t, uint32 aInstanceId);
+        MapInstanced(uint32 id, time_t, uint32 aInstanceId, uint8 HeroicMod);
         ~MapInstanced() {}
 
         virtual void Update(const uint32&);
@@ -34,7 +34,7 @@
         virtual void UnloadAll(bool pForce);
 
         Map* GetInstance(const WorldObject* obj);
-        bool IsValidInstance(uint32 InstanceId);
+        void DestroyInstance(uint32 InstanceId);
 
         void AddGridMapReference(const GridPair &p) { GridMapReference[p.x_coord][p.y_coord]++; }
         void RemoveGridMapReference(const GridPair &p)
@@ -45,7 +45,7 @@
 
     private:
 
-        void CreateInstance(uint32 InstanceId, Map* &map);
+        void CreateInstance(uint32 InstanceId, Map* &map, const WorldObject* obj);
 
         typedef HM_NAMESPACE::hash_map< uint32, Map* > InstancedMaps;
 
Index: src/game/Creature.h
===================================================================
--- src/game/Creature.h	(revision 5236)
+++ src/game/Creature.h	(working copy)
@@ -241,6 +241,7 @@
     uint32 curmana;
     uint8 deathState;
     uint8 movementType;
+    uint32 instanceMode;
 };
 
 struct CreatureDataAddonAura
@@ -253,6 +254,7 @@
 struct CreatureDataAddon
 {
     uint32 guidOrEntry;
+    uint32 path_id;
     uint32 mount;
     uint32 bytes0;
     uint32 bytes1;
@@ -512,6 +514,8 @@
                 return m_charmInfo->GetCharmSpell(pos)->spellId;
         }
 
+        uint32 GetWaypointPath();
+
     protected:
         // vendor items
         typedef std::vector<CreatureItem> CreatureItems;
@@ -558,6 +562,7 @@
         bool m_regenHealth;
         bool m_AI_locked;
         uint32 m_equipmentId;
+
     private:
         GridReference<Creature> m_gridRef;
 };
Index: src/game/MovementHandler.cpp
===================================================================
--- src/game/MovementHandler.cpp	(revision 5236)
+++ src/game/MovementHandler.cpp	(working copy)
@@ -27,6 +27,8 @@
 #include "MapManager.h"
 #include "Transports.h"
 #include "BattleGround.h"
+#include "NameTables.h"
+#include "ObjectMgr.h"
 #include "WaypointMovementGenerator.h"
 
 void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ )
@@ -34,6 +36,7 @@
     sLog.outDebug( "WORLD: got MSG_MOVE_WORLDPORT_ACK." );
 
     MapEntry const* mEntry = sMapStore.LookupEntry(GetPlayer()->GetMapId());
+    MapInfo const* mInfo = objmgr.GetMapInformation(GetPlayer()->GetMapId());
     if(!mEntry || !MaNGOS::IsValidMapCoord(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY()))
     {
         LogoutPlayer(false);
@@ -85,6 +88,12 @@
     if(!_player->GetBaseMap()->IsMountAllowed())
         _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
 
+    if(mEntry->map_type == MAP_RAID && mInfo)
+    {
+        if(GetPlayer()->FindSaveInstance(GetPlayer()->GetMapId()) == 0)
+            GetPlayer()->SendRaidInstanceResetWarning(GetPlayer()->GetMapId(), mInfo->ResetDelayTime);//ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
+    }
+
     // battleground state preper
     if(_player->InBattleGround())
     {
@@ -252,6 +261,7 @@
 
                 float height = movementInfo.z;
                 target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
+                Map const *map = MapManager::Instance().GetBaseMap(target->GetMapId(), target->GetInstanceMode());
 
                 if (damage > 0)
                 {
@@ -504,3 +514,8 @@
     _player->SummonIfPossible();
 }
 
+
+
+
+
+
Index: src/game/Level1.cpp
===================================================================
--- src/game/Level1.cpp	(revision 5236)
+++ src/game/Level1.cpp	(working copy)
@@ -402,12 +402,6 @@
                     return true;
                 }
             }
-
-            // bind us to the players instance
-            BoundInstancesMap::iterator i = chr->m_BoundInstances.find(chr->GetMapId());
-                                                            // error, the player has no instance bound!!!
-            if (i == chr->m_BoundInstances.end()) return true;
-            _player->m_BoundInstances[chr->GetMapId()] = std::pair < uint32, uint32 >(i->second.first, i->second.second);
             _player->SetInstanceId(chr->GetInstanceId());
         }
 
@@ -2013,7 +2007,7 @@
         return true;
     }
 
-    Map const *map = MapManager::Instance().GetBaseMap(mapid);
+    Map const *map = MapManager::Instance().GetBaseMap(mapid, _player->GetInstanceMode());
     float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
     _player->SaveRecallPosition();
     _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
@@ -2102,7 +2096,7 @@
     // update to parent zone if exist (client map show only zones without parents)
     AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry;
 
-    Map const *map = MapManager::Instance().GetBaseMap(zoneEntry->mapid);
+    Map const *map = MapManager::Instance().GetBaseMap(zoneEntry->mapid, _player->GetInstanceMode());
 
     if(map->Instanceable())
     {
@@ -2161,7 +2155,7 @@
         return true;
     }
 
-    Map const *map = MapManager::Instance().GetBaseMap(mapid);
+    Map const *map = MapManager::Instance().GetBaseMap(mapid,_player->GetInstanceMode());
     float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
     _player->SaveRecallPosition();
     _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
Index: src/game/WaypointMovementGenerator.cpp
===================================================================
--- src/game/WaypointMovementGenerator.cpp	(revision 5236)
+++ src/game/WaypointMovementGenerator.cpp	(working copy)
@@ -16,339 +16,253 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/*
-creature_movement Table
-
-alter table creature_movement add `text1` varchar(255) default NULL;
-alter table creature_movement add `text2` varchar(255) default NULL;
-alter table creature_movement add `text3` varchar(255) default NULL;
-alter table creature_movement add `text4` varchar(255) default NULL;
-alter table creature_movement add `text5` varchar(255) default NULL;
-alter table creature_movement add `aiscript` varchar(255) default NULL;
-alter table creature_movement add `emote` int(10) unsigned default '0';
-alter table creature_movement add `spell` int(5) unsigned default '0';
-alter table creature_movement add `wpguid` int(11) default '0';
-
-*/
-
-#include <ctime>
-
+//Basic header
 #include "WaypointMovementGenerator.h"
+//Accessors
+#include "Database/DatabaseEnv.h"
 #include "ObjectMgr.h"
+#include "World.h"
+//Creature-specific headers
 #include "Creature.h"
-#include "DestinationHolderImp.h"
+#include "CreatureAI.h"
+//Player-Specific
+#include "Player.h"
+//Visual
+#include "ProgressBar.h"
 
-#include <cassert>
+WaypointStore sWaypointStore;
 
 //-----------------------------------------------//
-void
-WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
+void WaypointStore::Free()
 {
-    QueryResult *result = NULL;
-    sLog.outDebug("DEBUG: WaypointMovementGenerator::_load: GUID - %d", c.GetGUIDLow());
-    // Identify by GUID
-    result = WorldDatabase.PQuery("SELECT `position_x`, `position_y`, `position_z`, `orientation`, `model1`, `model2`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `aiscript` FROM `creature_movement` WHERE `id` = '%u' ORDER BY `point`", c.GetDBTableGUIDLow());
-    /*
-    if( result ) {
-    sLog.outDebug("DEBUG: Number of hits: %d", result->GetRowCount());
-    } else {
-    sLog.outDebug("DEBUG: Nothing found");
+    for(uint32 i = 0;i < records;++i)
+    {
+        if(data[i])
+            for(WaypointPath::iterator itr = data[i]->begin(); itr!= data[i]->end(); ++ itr)
+               delete (*itr);
+        data[i]->clear();
+        delete data[i];
     }
-    */
+   delete [] data;
+}
 
-    if( result )
+void WaypointStore::Load()
+{
+    QueryResult *result = WorldDatabase.PQuery("SELECT MAX(`id`) FROM `waypoint_data");
+    if(!result)
     {
-        unsigned int count = 0;
-        const unsigned int sz = result->GetRowCount();
-        i_path.Resize( sz );
-        i_delays.resize( sz );
-        i_wpBehaviour.resize( sz );
+        sLog.outError(" an error occured while loading the table `waypoint_data` ( maybe it doesn't exist ?)\n");
+        exit(1);                                            // Stop server at loading non exited table or not accessable table
+    }
 
-        do
+    records = (*result)[0].GetUInt32();
+    delete result;
+
+    result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`delay`,`move_flag`,`event_id`,`event_chance` FROM `waypoint_data` ORDER BY `id`, `point`");
+    if(!result)
+    {
+        sLog.outErrorDb("The table `creature_addon` is empty or corrupted");
+        return;
+    }
+
+    data = new WaypointPath*[records];
+    uint32 total_records = result->GetRowCount();
+
+    barGoLink bar( total_records);
+    Field *fields;
+    uint32 last_id = 0;
+    do
+    {
+        fields = result->Fetch();
+        uint32 id = fields[0].GetUInt32();
+        bar.step();
+        WaypointData *wp = new WaypointData;
+
+        if(last_id != id)
         {
-            //sLog.outDebug("DEBUG: _load");
-            Field *fields = result->Fetch();
-            i_path[count].x         = fields[0].GetFloat();
-            i_path[count].y         = fields[1].GetFloat();
-            i_path[count].z         = fields[2].GetFloat();
-            float orientation       = fields[3].GetFloat();
-            uint32 model1           = fields[4].GetUInt32();
-            uint32 model2           = fields[5].GetUInt32();
-            i_delays[count]         = fields[6].GetUInt16();
-            uint32 emote            = fields[7].GetUInt32();
-            uint32 spell            = fields[8].GetUInt32();
-            std::string text1       = fields[9].GetCppString();
-            std::string text2       = fields[10].GetCppString();
-            std::string text3       = fields[11].GetCppString();
-            std::string text4       = fields[12].GetCppString();
-            std::string text5       = fields[13].GetCppString();
-            std::string aiscript    = fields[14].GetCppString();
+            data[id] = new WaypointPath;
+        }
 
-            if( (emote != 0) || (spell != 0)
-                || !text1.empty() || !text2.empty() || !text3.empty() || !text4.empty() || !text5.empty()
-                || !aiscript.empty()
-                || (model1 != 0)  || (model2 != 0) || (orientation != 100))
-            {
-                WaypointBehavior *tmpWPB = new WaypointBehavior;
+        float x,y,z;
+        x = fields[2].GetFloat();
+        y = fields[3].GetFloat();
+        z = fields[4].GetFloat();
 
-                // sLog.outDebug("DEBUG: _load  ---  Adding WaypointBehavior");
+        MaNGOS::NormalizeMapCoord(x);
+        MaNGOS::NormalizeMapCoord(y);
 
-                tmpWPB->text[0] = text1;
-                tmpWPB->text[1] = text2;
-                tmpWPB->text[2] = text3;
-                tmpWPB->text[3] = text4;
-                tmpWPB->text[4] = text5;
-                tmpWPB->aiscript = aiscript;
-                tmpWPB->orientation = orientation;
-                tmpWPB->emote = emote;
-                tmpWPB->spell = spell;
-                tmpWPB->model1 = model1;
-                tmpWPB->model2 = model2;
-                tmpWPB->HasDone = false;
-                i_wpBehaviour[count] = tmpWPB;
-            }
-            else
-            {
-                i_wpBehaviour[count] = NULL;
-            }
+        wp->id = fields[1].GetUInt32();
+        wp->x = x;
+        wp->y = y;
+        wp->z = z;
+        wp->run = fields[5].GetBool();
+        wp->delay = fields[6].GetUInt32();
+        wp->event_id = fields[7].GetUInt32();
+        wp->event_chance = fields[8].GetUInt8();
 
-            if(!MaNGOS::IsValidMapCoord(i_path[count].x,i_path[count].y))
-            {
-                sLog.outErrorDb("ERROR: Creature (guidlow %d,entry %d) have invalid coordinates in his waypoint %d (X: %d, Y: %d).",
-                    c.GetGUIDLow(),c.GetEntry(),count,i_path[count].x,i_path[count].y
-                    );
+        data[id]->push_back(wp);
 
-                // prevent invalid coordinates using
-                MaNGOS::NormalizeMapCoord(i_path[count].x);
-                MaNGOS::NormalizeMapCoord(i_path[count].y);
-                i_path[count].z = MapManager::Instance ().GetBaseMap(c.GetMapId())->GetHeight(i_path[count].x,i_path[count].y, i_path[count].z);
-            }
-            // to prevent a misbehaviour inside "update"
-            // update is alway called with the next wp - but the wpSys needs the current
-            // so when the routine is called the first time, wpSys gets the last waypoint
-            // and this prevents the system from performing text/emote, etc
-            if( count == (sz-1) )
-            {
-                if( i_wpBehaviour[count] != NULL )
-                {
-                    i_wpBehaviour[count]->HasDone = true;
-                }
-            }
-            //if( i_delays[count] < 30 /* millisecond */ )
-            //    i_delays[count] = (rand() % 5000);
-            ++count;
+        last_id = id;
 
-        } while( result->NextRow() );
+    } while(result->NextRow()) ;
 
-        delete result;
+    delete result;
+}
 
-        assert( sz == count );
-    }
+WaypointData* CreateWaypoint(uint32 id, float x, float y, float z, bool run, uint32 delay, uint32 event_id, uint8 event_chance)
+{
+    WaypointData *wp = new WaypointData;
+    wp->id = id;
+    
+    MaNGOS::NormalizeMapCoord(x);
+    MaNGOS::NormalizeMapCoord(y);
+
+    wp->x = x;
+    wp->y = y;
+    wp->z = z;
+    
+    wp->run = run;
+    wp->delay = delay;
+    wp->event_id = event_id;
+    wp->event_chance = event_chance;
+
+    return wp;
 }
 
+template<class T>
 void
-WaypointMovementGenerator<Creature>::ClearWaypoints()
+WaypointMovementGenerator<T>::Initialize(T &u)
 {
-    for (std::vector<WaypointBehavior*>::iterator itr = i_wpBehaviour.begin(); itr != i_wpBehaviour.end(); ++itr)
-        delete (*itr);
-    i_wpBehaviour.clear();
+    i_currentNode = 0;
+    i_nextMoveTime.Reset(0);
+    u.StopMoving();
+    if(!path_id)
+        GeneratePathId(u);
+    waypoints = sWaypointStore.GetPath(path_id);
 }
 
+template<class T>
 void
-WaypointMovementGenerator<Creature>::Initialize()
+WaypointMovementGenerator<T>::Reset(T &u)
 {
-    QueryResult *result = WorldDatabase.Query("SELECT distinct(`id`) as uniqueid FROM `creature_movement`");
+    u.StopMoving();
+    
+    float x,y,z;
+    i_destinationHolder.GetLocationNow(x,y,z);
 
-    if( result )
-    {
-        do
-        {
-            Field *fields = result->Fetch();
-            si_waypointHolders.insert( fields[0].GetUInt32() );
-        }
-        while( result->NextRow() );
+    Traveller<T> traveller(u);
+    i_destinationHolder.GetDestination(x,y,z);
+    i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+}
 
-        delete result;
-    }
+template<class T>
+void
+WaypointMovementGenerator<T>::GeneratePathId(T &unit)
+{
+    path_id = 0;
 }
 
+template<>
+void
+WaypointMovementGenerator<Creature>::GeneratePathId(Creature &unit)
+{
+    path_id = unit.GetWaypointPath();
+}
+
+template<class T>
+void
+WaypointMovementGenerator<T>::SetMoveFlag(T &unit, bool flag)
+{
+    //I wonder how that should even work for players, empty for now
+}
+
+template<>
+void
+WaypointMovementGenerator<Creature>::SetMoveFlag(Creature &unit,bool flag)
+{
+    
+}
+
+template<class T>
+void
+WaypointMovementGenerator<T>::MovementInform(T &unit)
+{
+
+}
+
+template<>
+void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
+{
+    unit.AI()->MovementInform(path_id);
+}
+
+template<class T>
 bool
-WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
+WaypointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
 {
-    if(!&creature)
-        return true;
+    if(!&unit)
+        return false;
 
     // 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))
+    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
         return true;
 
-    // prevent crash at empty waypoint path.
-    if(i_path.Empty())
-    {
-        return true;
-    }
+    // Clear the generator if the path doesn't exist
+    if(!waypoints || !waypoints->size())
+        return false;
 
-    CreatureTraveller traveller(creature);
+    Traveller<T> traveller(unit);
 
-    /*
-    if( npcIsStopped[creature.GetGUID()] )
-    {
-        i_nextMoveTime.Update(40000);
-        i_destinationHolder.UpdateTraveller(traveller, ((diff)-40000), false);
-        npcIsStopped[creature.GetGUID()] = false;
-        return true;
-    }
-    */
     i_nextMoveTime.Update(diff);
     i_destinationHolder.UpdateTraveller(traveller, diff, false);
 
-    if( creature.IsStopped() )
-    {
-        uint32 wpB = i_currentNode > 0 ? i_currentNode-1 : i_wpBehaviour.size()-1;
-
-        if( i_wpBehaviour[wpB] != NULL )
-        {
-            struct WaypointBehavior *tmpBehavior = i_wpBehaviour[wpB];
-
-            if (!tmpBehavior->HasDone)
-            {
-                if(tmpBehavior->emote != 0)
-                {
-                    creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,tmpBehavior->emote);
-                }
-                if(!tmpBehavior->aiscript.empty())
-                {
-                    WPAIScript(creature, tmpBehavior->aiscript);
-                }
-                //sLog.outDebug("DEBUG: tmpBehavior->text[0] TEST");
-                if(!tmpBehavior->text[0].empty())
-                {
-                    //sLog.outDebug("DEBUG: tmpBehavior->text[0] != \"\"");
-                    // Only one text is set
-                    if( tmpBehavior->text[1].empty() )
-                    {
-                        //sLog.outDebug("DEBUG: tmpBehavior->text[1] == NULL");
-                        creature.Say(tmpBehavior->text[0].c_str(), 0, 0);
-                    }
-                    else
-                    {
-                        // Select one from max 5 texts (0 and 1 laready checked)
-                        int i = 2;
-                        for( ; i < 5; ++i )
-                            if( tmpBehavior->text[i].empty() )
-                                break;
-
-                        //sLog.outDebug("DEBUG: tmpBehavior->text[i] == \"\": %d", i);
-                        //sLog.outDebug("DEBUG: rand() % (i): %d", rand() % (i));
-
-                        creature.Say(tmpBehavior->text[rand() % i].c_str(), 0, 0);
-                    }
-                }
-                if(tmpBehavior->spell != 0)
-                {
-                    //sLog.outDebug("DEBUG: wpSys - spell");
-                    creature.CastSpell(&creature,tmpBehavior->spell, false);
-                }
-                if (tmpBehavior->orientation !=100)
-                {
-                    //sLog.outDebug("DEBUG: wpSys - orientation");
-                    creature.SetOrientation(tmpBehavior->orientation);
-                }
-                if(tmpBehavior->model1 != 0)
-                {
-                    //sLog.outDebug("DEBUG: wpSys - model1");
-                    creature.SetUInt32Value(UNIT_FIELD_DISPLAYID, tmpBehavior->model1);
-                }
-                tmpBehavior->HasDone = true;
-            }                                               // HasDone == false
-        }                                                   // wpBehaviour found
-    }                                                       // i_creature.IsStopped()
-
     if( i_nextMoveTime.Passed() )
     {
-        if( creature.IsStopped() )
+        if( unit.IsStopped() )
         {
-            assert( i_currentNode < i_path.Size() );
-            creature.addUnitState(UNIT_STAT_ROAMING);
-            const Path::PathNode &node(i_path(i_currentNode));
-            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
-            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
-            uint32 wpB = i_currentNode > 0 ? i_currentNode-1 : i_wpBehaviour.size()-1;
-
-            if( i_wpBehaviour[wpB] != NULL )
+            if(i_currentNode == waypoints->size() - 1) //If that's our last waypoint
             {
-                struct WaypointBehavior *tmpBehavior = i_wpBehaviour[wpB];
-                tmpBehavior->HasDone = false;
-                if(tmpBehavior->model2 != 0)
-                {
-                    creature.SetUInt32Value(UNIT_FIELD_DISPLAYID, tmpBehavior->model2);
-                }
-                if (tmpBehavior->orientation !=100)
-                {
-                    creature.SetOrientation(tmpBehavior->orientation);
-                }
-                creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
+                MovementInform(unit);
+                if(repeating) //If the movement is repeating
+                    i_currentNode = 0; //Start moving all over again
+                else
+                    return false; //Clear the waypoint movement
             }
+            else
+                i_currentNode++;
+
+            WaypointData const *nextWP = *(waypoints->begin()+i_currentNode);
+            SetMoveFlag(unit, nextWP->run);
+            unit.addUnitState(UNIT_STAT_ROAMING);
+            i_destinationHolder.SetDestination(traveller, nextWP->x, nextWP->y, nextWP->z);
+            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());            
         }
         else
         {
-            creature.StopMoving();
-            i_nextMoveTime.Reset(i_delays[i_currentNode]);
-            ++i_currentNode;
-            if( i_currentNode >= i_path.Size() )
-                i_currentNode = 0;
+            WaypointData *wp = *(waypoints->begin()+i_currentNode);
+            i_nextMoveTime.Reset(wp->delay);
+
+            if(wp->event_id && rand()%100 < wp->event_chance)
+                sWorld.ScriptsStart(sWaypointScripts, wp->event_id, &unit, NULL);
+
+            unit.StopMoving();
         }
     }
     return true;
 }
 
-void
-WaypointMovementGenerator<Creature>::WPAIScript(Creature &pCreature, std::string pAiscript)
-{
-    time_t curr;
-    tm local;
-    time(&curr);                                            // get current time_t value
-    local=*(localtime(&curr));                              //
-    int cT = ((local.tm_hour*100)+local.tm_min);
+template void WaypointMovementGenerator<Player>::Initialize(Player &);
+template void WaypointMovementGenerator<Creature>::Initialize(Creature &);
+template void WaypointMovementGenerator<Player>::Reset(Player &);
+template void WaypointMovementGenerator<Creature>::Reset(Creature &);
+template bool WaypointMovementGenerator<Player>::Update(Player &, const uint32 &);
+template bool WaypointMovementGenerator<Creature>::Update(Creature &, const uint32 &);
+template void WaypointMovementGenerator<Player>::GeneratePathId(Player &);
+template void WaypointMovementGenerator<Player>::MovementInform(Player &);
+template void WaypointMovementGenerator<Player>::SetMoveFlag(Player &, bool flag);
 
-    sLog.outDebug("WPAIScript: %s", pAiscript.c_str());
-
-    if( pAiscript == "guard-sw")                            //demo script for WP-AI System
-    {
-        // 1423 - SW guard
-        // 68   - SW city guard
-        if((pCreature.GetEntry() == 68) || (pCreature.GetEntry() == 1423) )
-        {
-            if(!( (cT < 1800) && (cT > 800) ))              //If time not smaller than 1800 and not bigger than 800 (24 hour format)
-            {                                               //try to set model of Off-hand (shield) to 0 (imo it doesn't work...)
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2, 234948100);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2 + 1, 4);
-
-                //set new Off-Hand Item as lamp
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 7557);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2, 385941508);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2 + 1, 7);
-            }                                               //else do it in other direction...
-            else
-            {
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2, 385941508);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2 + 1, 7);
-
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 2080);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2, 234948100);
-                pCreature.SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 2 + 1, 4);
-            }
-        }
-        sLog.outDebug("guard-sw");
-    }                                                       // guard-sw
-}                                                           // WPAIScript
-
-std::set<uint32> WaypointMovementGenerator<Creature>::si_waypointHolders;
-
 //----------------------------------------------------//
 void
 FlightPathMovementGenerator::LoadPath(Player &)
@@ -441,6 +355,57 @@
     player.FlightComplete();
 }
 
+
+//----- Point Movement Generator
+template<class T>
+bool
+PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
+{
+    if(!&unit)
+        return false;
+
+    if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
+        return true;
+
+    Traveller<T> traveller(unit);
+
+    i_destinationHolder.UpdateTraveller(traveller, diff, false);
+
+    if(i_destinationHolder.HasArrived())
+    {
+        unit.StopMoving();
+        MovementInform(unit);
+        return false;    
+    }
+
+    return true;
+}
+
+template<class T>
+void
+PointMovementGenerator<T>::Initialize(T &unit)
+{
+    unit.StopMoving();
+    Traveller<T> traveller(unit);
+    i_destinationHolder.SetDestination(traveller,x,y,z);
+}
+
+template<class T>
+void
+PointMovementGenerator<T>::MovementInform(T &unit)
+{
+
+}
+
+template<>
+void PointMovementGenerator<Creature>::MovementInform(Creature &unit)
+{
+    unit.AI()->MovementInform(id);
+}
+
+template void PointMovementGenerator<Player>::Initialize(Player &);
+template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &);
+
 //
 // Unique1's ASTAR Pathfinding Code... For future use & reference...
 //
Index: src/game/GameObject.h
===================================================================
--- src/game/GameObject.h	(revision 5236)
+++ src/game/GameObject.h	(working copy)
@@ -88,7 +88,9 @@
     float rotation3;
     int32  spawntimesecs;
     uint32 animprogress;
+    uint32 instanceMode;
     uint32 go_state;
+
 };
 
 // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
Index: src/game/Object.h
===================================================================
--- src/game/Object.h	(revision 5236)
+++ src/game/Object.h	(working copy)
@@ -64,6 +64,33 @@
     TYPEID_AREATRIGGER   = 9
 };
 
+enum INSTANCEMODE
+{
+    INSTANCEMODE_NORMAL = 0,
+    INSTANCEMODE_HEROIC = 1
+};
+
+enum MapDifficultyMod
+{
+    MAPDIFFICULTY_NORMAL           = 0,
+    MAPDIFFICULTY_HEROIC_SUPPORTED = 1
+};
+
+enum LevelRequirementVsMode
+{
+    LEVELREQUIREMENT_HEROIC = 70
+};
+
+struct MapInfo
+{
+    uint32 i_mapId;
+    uint32 ResetDelayTime;
+    uint32 map_type;
+    uint32 maxPlayers;
+    int32  parent_map;
+    uint32 supportMode;
+};
+
 uint32 GuidHigh2TypeId(uint32 guid_hi);
 
 enum TempSummonType
@@ -347,6 +374,8 @@
 
         uint32 GetInstanceId() const { return m_InstanceId; }
         void SetInstanceId(uint32 val) { m_InstanceId = val; }
+        void SetInstanceMode(uint8 mode) { m_instanceMode = mode; }
+        uint32 GetInstanceMode() const { return m_instanceMode; }
 
         // main visibility check function in normal case (ignore grey zone distance check)
         bool isVisibleFor(Player const* u) const { return isVisibleForInState(u,false); }
@@ -372,5 +401,6 @@
         bool mSemaphoreTeleport;
 
         uint32 m_InstanceId;
+        uint32 m_instanceMode;
 };
 #endif
Index: src/game/MapManager.h
===================================================================
--- src/game/MapManager.h	(revision 5236)
+++ src/game/MapManager.h	(working copy)
@@ -39,11 +39,12 @@
         Map* GetMap(uint32, const WorldObject* obj);
 
         // only const version for outer users
-        Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); }
+        Map const* GetBaseMap(uint32 id, uint8 mode) const { return const_cast<MapManager*>(this)->_GetBaseMap(id, mode); }
+        void DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode);
 
         inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const
         {
-            Map const* m = GetBaseMap(mapid);
+            Map const* m = GetBaseMap(mapid, 0);
             return m->GetAreaFlag(x, y);
         }
         inline uint32 GetAreaId(uint32 mapid, float x, float y) { return Map::GetAreaId(GetAreaFlag(mapid, x, y)); }
@@ -103,7 +104,7 @@
         MapManager(const MapManager &);
         MapManager& operator=(const MapManager &);
 
-        Map* _GetBaseMap(uint32 id);
+        Map* _GetBaseMap(uint32 id, const uint8 mode);
         Map* _findMap(uint32 id) const
         {
             MapMapType::const_iterator iter = i_maps.find(id);
Index: src/game/ConfusedMovementGenerator.cpp
===================================================================
--- src/game/ConfusedMovementGenerator.cpp	(revision 5236)
+++ src/game/ConfusedMovementGenerator.cpp	(working copy)
@@ -33,7 +33,7 @@
     z = unit.GetPositionZ();
     uint32 mapid=unit.GetMapId();
 
-    Map const* map = MapManager::Instance().GetBaseMap(mapid);
+    Map const* map = MapManager::Instance().GetBaseMap(mapid, unit.GetInstanceMode());
 
     i_nextMove = 1;
 
Index: src/game/Player.h
===================================================================
--- src/game/Player.h	(revision 5236)
+++ src/game/Player.h	(working copy)
@@ -453,12 +453,6 @@
     ERR_TAXINOTSTANDING             = 12
 };
 
-enum DungeonDifficulties
-{
-    DUNGEONDIFFICULTY_NORMAL = 0,
-    DUNGEONDIFFICULTY_HEROIC = 1
-};
-
 enum LootType
 {
     LOOT_CORPSE                 = 1,
@@ -771,7 +765,14 @@
     movementFlagsMask | MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT
 );
 
-typedef HM_NAMESPACE::hash_map< uint32, std::pair < uint32, uint32 > > BoundInstancesMap;
+struct SaveInstance
+{
+    uint32 InstanceId;
+    uint32 MapId;
+    time_t ResetTime;
+};
+ 
+typedef HM_NAMESPACE::hash_map< uint32, SaveInstance* > BoundInstancesMap;
 
 enum KillStates
 {
@@ -887,7 +888,7 @@
         void SendInitialPacketsBeforeAddToMap();
         void SendInitialPacketsAfterAddToMap();
         void SendTransferAborted(uint32 mapid, uint16 reason);
-        void SendRaidInstanceResetWarning(uint32 type, uint32 mapid, uint32 time);
+        void SendRaidInstanceResetWarning(uint32 mapid, uint32 time);
 
         bool CanInteractWithNPCs(bool alive = true) const;
 
@@ -1418,9 +1419,6 @@
         void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
         uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
 
-        void SetDungeonDifficulty(uint32 difficulty) { m_dungeonDifficulty = difficulty; }
-        uint32 GetDungeonDifficulty() { return m_dungeonDifficulty; }
-
         bool UpdateSkill(uint32 skill_id);
 
         bool UpdateSkillPro(uint16 SkillId, int32 Chance);
@@ -1491,7 +1489,10 @@
         void SendAutoRepeatCancel();
         void SendExplorationExperience(uint32 Area, uint32 Experience);
 
-        void SendDungeonDifficulty();
+        void SendInstanceMode(bool IsInGroup);
+        void ResetInstance(bool SendMgs);
+        void SendResetInstance(uint32 MapId);
+        void SendCannotReset(uint32 mapid);
 
         bool SetPosition(float x, float y, float z, float orientation, bool teleport = false);
         void SendMessageToSet(WorldPacket *data, bool self);// overwrite Object::SendMessageToSet
@@ -1832,6 +1833,15 @@
         uint32 m_HomebindTimer;
         bool m_InstanceValid;
         BoundInstancesMap m_BoundInstances;
+        uint32 FindSaveInstance(uint32 mapid);
+        void DeleteSaveInstance(uint32 InstanceId)
+        {
+            BoundInstancesMap::iterator itr = m_BoundInstances.find(InstanceId);
+            if(itr != m_BoundInstances.end())
+                m_BoundInstances.erase(itr);
+        }
+        void AddSaveInstance(uint32 InstanceId, uint32 mapId, time_t ResetTime);
+        void BuildRaidInfo();
 
         /*********************************************************/
         /***                   GROUP SYSTEM                    ***/
@@ -1949,7 +1959,6 @@
         uint32 m_nextSave;
         time_t m_speakTime;
         uint32 m_speakCount;
-        uint32 m_dungeonDifficulty;
 
         uint32 m_atLoginFlags;
 
Index: src/game/Group.h
===================================================================
--- src/game/Group.h	(revision 5236)
+++ src/game/Group.h	(working copy)
@@ -58,6 +58,13 @@
     GROUPTYPE_RAID   = 1
 };
 
+enum GroupMod
+{
+    GROUPMODE_NORMAL = 0,
+    GROUPMODE_HEROIC = 1
+}
+;
+
 class BattleGround;
 
 enum GroupUpdateFlags
@@ -252,6 +259,11 @@
         }
 
         void SetTargetIcon(uint8 id, uint64 guid);
+        void SetGroupMode(uint8 groupmode);
+        uint32 GetGroupMode() { return m_groupMode; }
+        bool InInstance(bool SendMsg);
+        bool InCombatToInstance(uint32 instanceId);
+        void ResetInstance(bool SendMsg);
 
         // -no description-
         //void SendInit(WorldSession *session);
@@ -332,6 +344,7 @@
         uint64              m_mainTank;
         uint64              m_mainAssistant;
         GroupType           m_groupType;
+        uint32              m_groupMode;
         BattleGround*       m_bgGroup;
         uint64              m_targetIcons[TARGETICONCOUNT];
         LootMethod          m_lootMethod;
Index: src/game/Map.h
===================================================================
--- src/game/Map.h	(revision 5236)
+++ src/game/Map.h	(working copy)
@@ -116,15 +116,12 @@
 class MANGOS_DLL_DECL Map : public GridRefManager<NGridType>, public MaNGOS::ObjectLevelLockable<Map, ZThread::Mutex>
 {
     public:
-        typedef std::list<Player*> PlayerList;
-
-        Map(uint32 id, time_t, uint32 aInstanceId);
+        Map(uint32 id, time_t, uint32 aInstanceId, uint8 HeroicMod);
         virtual ~Map();
 
         void Add(Player *);
         bool AddInstanced(Player *);
         void Remove(Player *, bool);
-        void RemoveInstanced(Player *);
         template<class T> void Add(T *);
         template<class T> void Remove(T *, bool);
 
@@ -201,7 +198,10 @@
         InstanceData* GetInstanceData() { return i_data; }
         uint32 GetInstanceId() { return i_InstanceId; }
         bool NeedsReset() { return Instanceable() && ( i_resetTime == 0 || i_resetTime <= time(NULL)); }
-        uint32 GetPlayersCount() const { return i_Players.size(); }
+        MapInfo const* GetMapInfo() { return (i_mapInfo); }
+        time_t GetResetTimeMap() { return i_resetTime; }
+        void SetResetTimeMap(time_t time) { i_resetTime = time; }
+        uint8 GetInstanceMode() { return (i_instanceMode); }
         void Reset();
         bool CanEnter(Player* player) const;
         const char* GetMapName() const;
@@ -217,6 +217,10 @@
                 i_mapEntry->MapID==560 || i_mapEntry->MapID==509 || i_mapEntry->MapID==269 );
         }
 
+        bool IsBattleArena() const { return(i_mapEntry && (i_mapEntry->map_type == MAP_ARENA)); }
+        bool IsBattleGround() const { return(i_mapEntry && (i_mapEntry->map_type == MAP_BATTLEGROUND)); }
+        bool IsBattleGroundOrArena() const { return(i_mapEntry && ((i_mapEntry->map_type == MAP_BATTLEGROUND) || (i_mapEntry->map_type == MAP_ARENA))); }
+
         virtual bool RemoveBones(uint64 guid, float x, float y);
         void InitResetTime();
 
@@ -290,15 +294,13 @@
         time_t i_gridExpiry;
 
         MapEntry const* i_mapEntry;
+        MapInfo const* i_mapInfo;
+        uint8 i_instanceMode;
         time_t i_resetTime;
-        uint32 i_resetDelayTime;
         uint32 i_InstanceId;
-        uint32 i_maxPlayers;
         InstanceData* i_data;
         std::string i_script;
 
-        PlayerList i_Players;
-
         // Type specific code for add/remove to/from grid
         template<class T>
             void AddToGrid(T*, NGridType *, Cell const&);
Index: src/game/Opcodes.h
===================================================================
--- src/game/Opcodes.h	(revision 5236)
+++ src/game/Opcodes.h	(working copy)
@@ -826,7 +826,7 @@
     CMSG_RESET_INSTANCES                            = 797,  // reset instances, empty
     SMSG_RESET_INSTANCES_SUCCESS                    = 798,  // uint32 mapid, chat message: %s has been reset.
     SMSG_RESET_INSTANCES_FAILED                     = 799,  // uint32 reason, uint32 mapid
-    SMSG_UNKNOWN_800                                = 800,  // uint32 mapid, instance related (save?)
+    SMSG_INSTANCE_SAVE                              = 800,  // uint32 mapid, nstance save from player
     MSG_RAID_ICON_TARGET                            = 801,  // uint8+uint8+uint64 guid or only uint8(0x01)
     MSG_RAID_READY_CHECK                            = 802,  // uint64+uint8
     // 803 not exist?
@@ -837,7 +837,7 @@
     SMSG_GM_SURVEY_REQUEST                          = 808,  // uint32, 1 - causes client get ticket request, 2 - hide, 3 - show
     MSG_SET_DUNGEON_DIFFICULTY                      = 809,  // uint32+uint32+uint32
     CMSG_GM_SURVEY_RESULTS                          = 810,  // script function named GMSurveySubmit()
-    SMSG_UNKNOWN_811                                = 811,  // uint32, 0x0, SMSG_INSTANCE_RESET_ACTIVATE ?
+    SMSG_INSTANCE_RESET_ACTIVATE                    = 811,  // instance can reset
     SMSG_UNKNOWN_812                                = 812,
     // 813 not exist?
     // 814 not exist?
Index: src/game/BattleGroundWS.h
===================================================================
--- src/game/BattleGroundWS.h	(revision 5236)
+++ src/game/BattleGroundWS.h	(working copy)
@@ -138,6 +138,7 @@
         void EventPlayerCapturedFlag(Player *Source);
         void EventPlayerDroppedFlag(Player *Source);
         void EventPlayerReturnedFlag(Player *Source);
+        void EventDropTimerReturnedFlag(uint32 Team);
         void EventPlayerPickedUpFlag(Player *Source);
 
         void RemovePlayer(Player *plr, uint64 guid);
Index: src/game/GameEvent.cpp
===================================================================
--- src/game/GameEvent.cpp	(revision 5236)
+++ src/game/GameEvent.cpp	(working copy)
@@ -405,7 +405,7 @@
             objmgr.AddCreatureToGrid(*itr, data);
 
             // Spawn if necessary (loaded grids only)
-            Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(data->mapid));
+            Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(data->mapid, data->instanceMode));
             // We use spawn coords to spawn
             if(!map->Instanceable() && !map->IsRemovalGrid(data->spawn_posX,data->spawn_posY))
             {
@@ -438,7 +438,7 @@
             objmgr.AddGameobjectToGrid(*itr, data);
             // Spawn if necessary (loaded grids only)
             // this base map checked as non-instanced and then only existed
-            Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(data->mapid));
+            Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(data->mapid, data->instanceMode));
             // We use current coords to unspawn, not spawn coords since creature can have changed grid
             if(!map->Instanceable() && !map->IsRemovalGrid(data->posX, data->posY))
             {
Index: src/game/Makefile.am
===================================================================
--- src/game/Makefile.am	(revision 5236)
+++ src/game/Makefile.am	(working copy)
@@ -148,6 +148,8 @@
 	Map.h \
 	MapInstanced.cpp \
 	MapInstanced.h \
+	MapInstancedSaveMgr.cpp \
+	MapInstancedSaveMgr.h \
 	MapManager.cpp \
 	MapManager.h \
 	MiscHandler.cpp \
@@ -256,7 +258,9 @@
 	FollowerRefManager.h \
 	GroupReference.cpp \
 	GroupReference.h \
-	GroupRefManager.h
+	GroupRefManager.h \
+        MapInstancedSaveMgr.cpp \
+        MapInstancedSaveMgr.h
 
 ## Link against shared library
 libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a
Index: src/game/MiscHandler.cpp
===================================================================
--- src/game/MiscHandler.cpp	(revision 5236)
+++ src/game/MiscHandler.cpp	(working copy)
@@ -949,32 +949,68 @@
 
     if(at)
     {
-        if(at->requiredItem)
+        bool required = false;
+        if(at->requiredItem || at->secondItem)
         {
-            uint32 ReqItem = at->requiredItem;
+            required = true;
+            uint32 ReqItem = 0;
+            if(at->requiredItem)
+                ReqItem = at->requiredItem;
+            else
+                ReqItem = at->secondItem;
             ItemPrototype const *pProto = objmgr.GetItemPrototype(ReqItem);
             // pProto != NULL checked and fixed (if need with error output) at server load and don't must be happens here
 
             // item and level or GM
-            if( (!pProto || GetPlayer()->HasItemCount(ReqItem, 1)) &&
+            if( (GetPlayer()->HasItemCount(at->requiredItem, 1) || GetPlayer()->HasItemCount(at->requiredItem, 1)) &&
                 (GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL))
                 || GetPlayer()->isGameMaster() )
                 GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,false);
             else
             {
                 std::stringstream msgstr;
-                SendAreaTriggerMessage(objmgr.GetMangosString(LANG_LEVEL_MINREQUIRED_AND_ITEM,GetSessionLocaleIndex()),(uint32)at->requiredLevel,pProto->Name1);
+
+                if(at->requiredFailedText.c_str() != NULL)
+                    msgstr << at->requiredFailedText.c_str();
+                else
+                    SendAreaTriggerMessage(objmgr.GetMangosString(LANG_LEVEL_MINREQUIRED_AND_ITEM,GetSessionLocaleIndex()),(uint32)at->requiredLevel,pProto->Name1);
             }
         }
-        else
+        if((at->heroicKey || at->heroicSecond) && GetPlayer()->GetInstanceMode() == INSTANCEMODE_HEROIC)
+         {
+            required = true;
+            uint32 HeroicKey = 0;
+            if(at->heroicKey)
+                HeroicKey = at->heroicKey;
+            else
+                HeroicKey = at->heroicSecond;
+
+            ItemPrototype const *pProto = objmgr.GetItemPrototype(HeroicKey);
+
+            if( (GetPlayer()->HasItemCount(at->heroicKey, 1) || GetPlayer()->HasItemCount(at->heroicSecond, 1)) && 
+                (GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL)) 
+                || GetPlayer()->isGameMaster() )
+                GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,false);
+            else
+                GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY2);
+        }
+        if(at->requiredQuest)
         {
-            if(GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL) || GetPlayer()->isGameMaster())
+            required = true;
+            uint32 ReqQuest = at->requiredQuest;
+            if((GetPlayer()->GetQuestRewardStatus(ReqQuest) && GetPlayer()->getLevel() >= at->requiredLevel)|| sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL) || GetPlayer()->isGameMaster())
                 GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,false);
             else
             {
                 SendAreaTriggerMessage(objmgr.GetMangosString(LANG_LEVEL_MINREQUIRED,GetSessionLocaleIndex()),(uint32)at->requiredLevel );
             }
         }
+        if(required)
+            return;
+        if(GetPlayer()->getLevel() >= at->requiredLevel || sWorld.getConfig(CONFIG_INSTANCE_IGNORE_LEVEL) || GetPlayer()->isGameMaster())
+            GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,true,false);
+        else
+              SendAreaTriggerMessage(objmgr.GetMangosString(LANG_LEVEL_MINREQUIRED,GetSessionLocaleIndex()),(uint32)at->requiredLevel );
     }
 }
 
@@ -1529,6 +1565,14 @@
         data << mapid;
         _player->GetSession()->SendPacket(&data);
     */
+    Group *pGroup = _player->GetGroup();
+    if(pGroup)
+    {
+        if(!pGroup->InInstance(true) && pGroup->IsLeader(_player->GetGUID()))
+            pGroup->ResetInstance(true);
+    }
+    else
+        _player->ResetInstance(true);
 }
 
 void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data )
@@ -1537,11 +1581,31 @@
 
     sLog.outDebug("MSG_SET_DUNGEON_DIFFICULTY");
 
-    uint32 difficulty;
-    recv_data >> difficulty;
+    uint32 mode;
+    recv_data >> mode;
 
-    GetPlayer()->SetDungeonDifficulty(difficulty);
-    GetPlayer()->SendDungeonDifficulty();
+    if(_player->getLevel() < LEVELREQUIREMENT_HEROIC)
+        return;
+    Group *pGroup = _player->GetGroup();
+    if(pGroup)
+    {
+        if(pGroup->IsLeader(_player->GetGUID()))
+        {
+            if(!pGroup->InInstance(true))
+            {
+                pGroup->SetGroupMode(mode);
+                pGroup->ResetInstance(false);
+            }
+            else
+                _player->SendInstanceMode(true);
+        }
+    }
+    else
+    {
+        _player->SetInstanceMode(mode);
+        _player->SendInstanceMode(false);
+        _player->ResetInstance(false);
+    }
 }
 
 void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data )
Index: src/game/GroupHandler.cpp
===================================================================
--- src/game/GroupHandler.cpp	(revision 5236)
+++ src/game/GroupHandler.cpp	(working copy)
@@ -27,6 +27,7 @@
 #include "Player.h"
 #include "Group.h"
 #include "ObjectAccessor.h"
+#include "MapManager.h"
 
 /* differeces from off:
     -you can uninvite yourself - is is useful
@@ -85,8 +86,18 @@
         SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY);
         return;
     }
+    if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
+    {
+        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE);
+        return;
+    }
+    // just ignore us
+    if(player->GetInstanceId() != 0 && player->GetInstanceMode() != GetPlayer()->GetInstanceMode())
+    {
+        SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
+        return;
+    }
 
-    // just ignore us
     if(player->HasInIgnoreList(GetPlayer()->GetGUID()))
     {
         SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU);
@@ -278,6 +289,11 @@
     }
 
     Player *player = objmgr.GetPlayer(guid);
+    if(!player)
+    {
+        sLog.outError("HandleGroupUninvite - error");
+        return;
+    }
 
     /** error handling **/
     if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
@@ -298,7 +314,15 @@
     if(player && player->GetGroupInvite())                  // uninvite invitee
         player->UninviteFromGroup();
     else                                                    // uninvite member
+    {
         Player::RemoveFromGroup(group,guid);
+        if(player)
+        {
+            player->ResetInstance(false);
+            if(MapManager::Instance().GetBaseMap(player->GetMapId(), player->GetInstanceMode())->Instanceable() && !player->isGameMaster())
+                player->m_InstanceValid = false; //âîò ìû âûêèäûâàåì ïåðñà èç ãðóïïû, äëÿ èíñòàíöèÿ äîëæíà ñòàíîâèòñÿ èíâàëèäíîé! äîëæåí ïîéòè òàéìåð îòñ÷¸òà 60ñåê.
+        }
+    }
 }
 
 void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
@@ -340,6 +364,9 @@
     SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), PARTY_RESULT_OK);
 
     GetPlayer()->RemoveFromGroup();
+    GetPlayer()->ResetInstance(false);
+    if(MapManager::Instance().GetBaseMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceMode())->Instanceable() && !GetPlayer()->isGameMaster())
+        GetPlayer()->m_InstanceValid = false;
 }
 
 void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
@@ -706,21 +733,7 @@
 
 /*!*/void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & /*recv_data*/ )
 {
-    //sLog.outDebug("Received opcode CMSG_REQUEST_RAID_INFO");
-
-    WorldPacket data(SMSG_RAID_INSTANCE_INFO, 4);
-    data << (uint32)0;                                      // count (max is 10)
-
-    /*data << (uint32)count;
-    for(int i=0; i<count; i++)
-    {
-        data << (uint32)mapid;
-        data << (uint32)time_left_in_seconds; // time to reset
-        data << (uint32)instanceid;
-        data << (uint32)0;      // unknown
-    }*/
-
-    GetPlayer()->GetSession()->SendPacket(&data);
+    _player->BuildRaidInfo();
 }
 
 /*void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
Index: src/game/World.h
===================================================================
--- src/game/World.h	(revision 5236)
+++ src/game/World.h	(working copy)
@@ -84,6 +84,7 @@
     CONFIG_INSTANCE_IGNORE_LEVEL,
     CONFIG_INSTANCE_IGNORE_RAID,
     CONFIG_BATTLEGROUND_CAST_DESERTER,
+    CONFIG_INSTANCE_RESET_TIME_HOUR,
     CONFIG_MAX_PRIMARY_TRADE_SKILL,
     CONFIG_MIN_PETITION_SIGNS,
     CONFIG_GM_WISPERING_TO,
@@ -163,6 +164,7 @@
     RATE_MINING_NEXT,
     RATE_TALENT,
     RATE_LOYALTY,
+    RATE_INSTANCE_RESET_TIME,
     MAX_RATES
 };
 
Index: src/game/GameObject.cpp
===================================================================
--- src/game/GameObject.cpp	(revision 5236)
+++ src/game/GameObject.cpp	(working copy)
@@ -428,6 +428,7 @@
     data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3);
     data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime;
     data.animprogress = GetUInt32Value (GAMEOBJECT_ANIMPROGRESS);
+    data.instanceMode = GetInstanceMode();
     data.go_state = GetUInt32Value (GAMEOBJECT_STATE);
 
     // updated in DB
@@ -446,7 +447,8 @@
         << GetFloatValue(GAMEOBJECT_ROTATION+3) << ", "
         << m_respawnDelayTime << ", "
         << GetUInt32Value (GAMEOBJECT_ANIMPROGRESS) << ", "
-        << GetUInt32Value (GAMEOBJECT_STATE) << ")";
+        << GetUInt32Value (GAMEOBJECT_STATE) << ", "
+        << (uint32)GetInstanceMode() << ")";
 
     WorldDatabase.BeginTransaction();
     WorldDatabase.PExecuteLog("DELETE FROM `gameobject` WHERE `guid` = '%u'", m_DBTableGuid);
@@ -482,6 +484,7 @@
     uint32 stored_guid = guid;
     if (InstanceId != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
     SetInstanceId(InstanceId);
+    SetInstanceMode(data->instanceMode);
 
     if (!Create(guid,entry, map_id, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) )
         return false;
Index: src/game/MapManager.cpp
===================================================================
--- src/game/MapManager.cpp	(revision 5236)
+++ src/game/MapManager.cpp	(working copy)
@@ -17,6 +17,7 @@
  */
 
 #include "MapManager.h"
+#include "MapInstancedSaveMgr.h"
 #include "Policies/SingletonImp.h"
 #include "Database/DatabaseEnv.h"
 #include "Log.h"
@@ -95,7 +96,7 @@
 }
 
 Map*
-MapManager::_GetBaseMap(uint32 id)
+MapManager::_GetBaseMap(uint32 id, const uint8 mode)
 {
     Map *m = _findMap(id);
 
@@ -106,11 +107,11 @@
         const MapEntry* entry = sMapStore.LookupEntry(id);
         if (entry && ((entry->map_type == MAP_INSTANCE) || (entry->map_type == MAP_RAID)))
         {
-            m = new MapInstanced(id, i_gridCleanUpDelay, 0);
+            m = new MapInstanced(id, i_gridCleanUpDelay, 0, mode);
         }
         else
         {
-            m = new Map(id, i_gridCleanUpDelay, 0);
+            m = new Map(id, i_gridCleanUpDelay, 0, mode);
         }
         i_maps[id] = m;
     }
@@ -121,7 +122,7 @@
 
 Map* MapManager::GetMap(uint32 id, const WorldObject* obj)
 {
-    Map *m = _GetBaseMap(id);
+    Map *m = _GetBaseMap(id, obj->GetInstanceMode());
 
     if (m && obj && m->Instanceable()) m = ((MapInstanced*)m)->GetInstance(obj);
 
@@ -130,12 +131,19 @@
 
 bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
 {
-    return GetBaseMap(mapid)->CanEnter(player);
+    return GetBaseMap(mapid, player->GetInstanceMode())->CanEnter(player);
 }
 
+void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode)
+{
+    Map *m = _GetBaseMap(mapid, mode);
+    if (m && m->Instanceable())
+        ((MapInstanced*)m)->DestroyInstance(instanceId);
+}
+
 void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y)
 {
-    bool remove_result = _GetBaseMap(mapid)->RemoveBones(guid, x, y);
+    bool remove_result = _GetBaseMap(mapid, 0)->RemoveBones(guid, x, y);
 
     if (!remove_result)
     {
@@ -206,10 +214,19 @@
 {
     i_MaxInstanceId = 0;
 
-    QueryResult *result = CharacterDatabase.Query( "SELECT MAX(`id`) FROM `instance`" );
+    QueryResult *result = CharacterDatabase.Query( "SELECT MAX(`instance`) FROM `character`" );
     if( result )
     {
         i_MaxInstanceId = result->Fetch()[0].GetUInt32();
         delete result;
     }
+    if(i_MaxInstanceId)
+        return;
+
+    result = CharacterDatabase.Query( "SELECT MAX(`id`) FROM `instance`" );
+    if( result )
+    {
+        i_MaxInstanceId = result->Fetch()[0].GetUInt32();
+        delete result;
+    }
 }
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 5236)
+++ src/game/Unit.cpp	(working copy)
@@ -42,6 +42,7 @@
 #include "MovementGenerator.h"
 #include "GridNotifiersImpl.h"
 #include "CellImpl.h"
+#include "MapInstancedSaveMgr.h"
 
 #include <math.h>
 
@@ -685,6 +686,8 @@
             // Call creature just died function
             if (((Creature*)pVictim)->AI())
                 ((Creature*)pVictim)->AI()->JustDied(this);
+            if (((Creature*)pVictim)->GetCreatureInfo()->rank == CREATURE_ELITE_WORLDBOSS && ((Creature*)pVictim)->GetInstanceId())
+                sInstanceSavingManager.SaveInstanceIdToDB(pVictim->GetInstanceId(), pVictim->GetMapId());//åñëè âû óáèëè áîññà â èíñòàíöèè òî ïðîèõîäèò ñýéâ!
         }
 
         //judge if GainXP, Pet kill like player kill,kill pet not like PvP
@@ -749,8 +752,8 @@
                         xp = PvP || IsNoDamageXPArea(player->GetAreaId()) ? 0 : MaNGOS::XP::Gain(member_with_max_level, pVictim);
 
                         // skip in check PvP case (for speed, not used)
-                        bool is_raid = PvP ? false : MapManager::Instance().GetBaseMap(player->GetMapId())->IsRaid() && pGroup->isRaidGroup();
-                        bool is_dungeon = PvP ? false : MapManager::Instance().GetBaseMap(player->GetMapId())->IsDungeon();
+                        bool is_raid = PvP ? false : MapManager::Instance().GetBaseMap(player->GetMapId(), player->GetInstanceMode())->IsRaid() && pGroup->isRaidGroup();
+                        bool is_dungeon = PvP ? false : MapManager::Instance().GetBaseMap(player->GetMapId(), player->GetInstanceMode())->IsDungeon();
                         float group_rate = MaNGOS::XP::xp_in_group_rate(count,is_raid);
 
                         for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
@@ -3382,12 +3385,12 @@
 
 bool Unit::IsInWater() const
 {
-    return MapManager::Instance().GetBaseMap(GetMapId())->IsInWater(GetPositionX(),GetPositionY(), GetPositionZ());
+    return MapManager::Instance().GetBaseMap(GetMapId(), 0)->IsInWater(GetPositionX(),GetPositionY(), GetPositionZ());
 }
 
 bool Unit::IsUnderWater() const
 {
-    return MapManager::Instance().GetBaseMap(GetMapId())->IsUnderWater(GetPositionX(),GetPositionY(),GetPositionZ());
+    return MapManager::Instance().GetBaseMap(GetMapId(), 0)->IsUnderWater(GetPositionX(),GetPositionY(),GetPositionZ());
 }
 
 void Unit::DeMorph()
Index: src/game/ObjectMgr.h
===================================================================
--- src/game/ObjectMgr.h	(revision 5236)
+++ src/game/ObjectMgr.h	(working copy)
@@ -80,12 +80,18 @@
 extern ScriptMapMap sQuestStartScripts;
 extern ScriptMapMap sSpellScripts;
 extern ScriptMapMap sButtonScripts;
+extern ScriptMapMap sWaypointScripts;
 extern ScriptMapMap sEventScripts;
 
 struct AreaTrigger
 {
     uint8  requiredLevel;
     uint32 requiredItem;
+    uint32 secondItem;
+    uint32 heroicKey;
+    uint32 heroicSecond;
+    uint32 requiredQuest;
+    std::string requiredFailedText;
     uint32 target_mapId;
     float  target_X;
     float  target_Y;
@@ -206,6 +212,8 @@
 
         typedef HM_NAMESPACE::hash_map<uint32, AreaTrigger> AreaTriggerMap;
 
+        typedef HM_NAMESPACE::hash_map<uint32, MapInfo> MapInfoList;
+
         typedef HM_NAMESPACE::hash_map<uint32, ReputationOnKillEntry> RepOnKillMap;
 
         typedef HM_NAMESPACE::hash_map<uint32, WeatherZoneChances> WeatherZoneMap;
@@ -404,6 +412,7 @@
         void LoadQuestStartScripts();
         void LoadEventScripts();
         void LoadSpellScripts();
+        void LoadWaypointScripts();
 
         bool LoadMangosStrings();
         void LoadMangosStringLocales();
@@ -414,6 +423,7 @@
         void LoadCreatureRespawnTimes();
         void LoadCreatureAddons();
         void LoadCreatureModelInfo();
+        void LoadWaypointData();
         void LoadEquipmentTemplates();
         void LoadGameObjectLocales();
         void LoadGameobjects();
@@ -437,6 +447,7 @@
         void LoadPageTexts();
 
         // instance system
+        void LoadMapInformation();
         void CleanupInstances();
         void PackInstances();
 
@@ -457,6 +468,16 @@
         std::string GeneratePetName(uint32 entry);
         uint32 GetBaseXP(uint32 level);
 
+        AreaTrigger const* GetGoBackTrigger(uint32 Map) const;
+
+        MapInfo const* GetMapInformation(uint32 mapid) const
+        {
+            MapInfoList::const_iterator itr = mMapInfo.find( mapid );
+            if( itr != mMapInfo.end( ) )
+                return &itr->second;
+            return NULL;
+        }
+
         void ReturnOrDeleteOldMails(bool serverUp);
 
         void SetHighestGuids();
@@ -644,6 +665,7 @@
         GameObjectForQuestSet mGameObjectForQuestSet;
         GossipTextMap       mGossipText;
         AreaTriggerMap      mAreaTriggers;
+        MapInfoList         mMapInfo;
 
         RepOnKillMap        mRepOnKill;
 
Index: src/game/World.cpp
===================================================================
--- src/game/World.cpp	(revision 5236)
+++ src/game/World.cpp	(working copy)
@@ -375,6 +375,7 @@
     rate_values[RATE_HONOR] = sConfig.GetFloatDefault("Rate.Honor",1);
     rate_values[RATE_MINING_AMOUNT] = sConfig.GetFloatDefault("Rate.Mining.Amount",1);
     rate_values[RATE_MINING_NEXT]   = sConfig.GetFloatDefault("Rate.Mining.Next",1);
+    rate_values[RATE_INSTANCE_RESET_TIME] = sConfig.GetFloatDefault("Rate.InstanceResetTime",1);
     rate_values[RATE_TALENT] = sConfig.GetFloatDefault("Rate.Talent",1);
     if(rate_values[RATE_TALENT] < 0)
     {
@@ -422,6 +423,7 @@
     m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", 0);
     m_configs[CONFIG_INSTANCE_IGNORE_RAID]  = sConfig.GetBoolDefault("Instance.IgnoreRaid", 0);
     m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", 1);
+    m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR]  = sConfig.GetIntDefault("Instance.ResetTimeHours", 4);
 
     m_configs[CONFIG_MAX_PRIMARY_TRADE_SKILL] = sConfig.GetIntDefault("MaxPrimaryTradeSkill", 2);
     m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9);
@@ -601,6 +603,10 @@
     LoadDBCStores(m_dataPath);
     DetectDBCLang();
 
+    ///- Load InstanceInfo
+    sLog.outString(" Loaded instance information...");
+    objmgr.LoadMapInformation();
+
     ///- Clean up and pack instances
     sLog.outString( "Cleaning up instances..." );
     objmgr.CleanupInstances();                              // must be called before `creature_respawn`/`gameobject_respawn` tables
@@ -767,6 +773,9 @@
     sLog.outString( "Loading BattleMasters..." );
     objmgr.LoadBattleMastersEntry();
 
+    sLog.outString( "Loading Waypoint Data..." );
+    objmgr.LoadWaypointData();
+
     ///- Handle outdated emails (delete/return)
     sLog.outString( "Returning old mails..." );
     objmgr.ReturnOrDeleteOldMails(false);
@@ -777,6 +786,7 @@
     objmgr.LoadQuestEndScripts();                           // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
     objmgr.LoadSpellScripts();                              // must be after load Creature/Gameobject(Template/Data)
     objmgr.LoadButtonScripts();                             // must be after load Creature/Gameobject(Template/Data)
+    objmgr.LoadWaypointScripts();
     objmgr.LoadEventScripts();                              // must be after load Creature/Gameobject(Template/Data)
 
     sLog.outString( "Initializing Scripts..." );
@@ -815,7 +825,6 @@
 
     ///- Initilize static helper structures
     AIRegistry::Initialize();
-    WaypointMovementGenerator<Creature>::Initialize();
     Player::InitVisibleBits();
     RedZone::Initialize();
 
Index: src/game/Level2.cpp
===================================================================
--- src/game/Level2.cpp	(revision 5236)
+++ src/game/Level2.cpp	(working copy)
@@ -610,6 +610,9 @@
         return false;
     }
 
+    MapInfo const* mInfo = objmgr.GetMapInformation(chr->GetMapId());
+    if(mInfo && mInfo->supportMode == MAPDIFFICULTY_HEROIC_SUPPORTED)
+        pCreature->SetInstanceMode(chr->GetInstanceMode());
     pCreature->SaveToDB();
 
     // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
@@ -3091,6 +3094,9 @@
         //sLog.outDebug("*** spawntimeSecs: %d", value);
     }
 
+    MapInfo const* mInfo = objmgr.GetMapInformation(chr->GetMapId());
+    if(mInfo && mInfo->supportMode == MAPDIFFICULTY_HEROIC_SUPPORTED)
+        pGameObj->SetInstanceMode(chr->GetInstanceMode());
     pGameObj->SaveToDB();
     MapManager::Instance().GetMap(pGameObj->GetMapId(), pGameObj)->Add(pGameObj);
 
Index: src/game/CharacterHandler.cpp
===================================================================
--- src/game/CharacterHandler.cpp	(revision 5236)
+++ src/game/CharacterHandler.cpp	(working copy)
@@ -58,9 +58,9 @@
 
     // NOTE: all fields in `character` must be read to prevent lost character data at next save in case wrong DB structure.
     // !!! NOTE: including unused `zone`,`online`
-    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM,            "SELECT `guid`,`account`,`data`,`name`,`race`,`class`,`position_x`,`position_y`,`position_z`,`map`,`orientation`,`taximask`,`cinematic`,`totaltime`,`leveltime`,`rest_bonus`,`logout_time`,`is_logout_resting`,`resettalents_cost`,`resettalents_time`,`trans_x`,`trans_y`,`trans_z`,`trans_o`, `transguid`,`gmstate`,`stable_slots`,`at_login`,`zone`,`online`,`pending_honor`,`last_honor_date`,`last_kill_date`,`taxi_path` FROM `character` WHERE `guid` = '%u'", GUID_LOPART(m_guid));
+    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM,            "SELECT `guid`,`account`,`data`,`name`,`race`,`class`,`position_x`,`position_y`,`position_z`,`map`,`orientation`,`taximask`,`cinematic`,`totaltime`,`leveltime`,`rest_bonus`,`logout_time`,`is_logout_resting`,`resettalents_cost`,`resettalents_time`,`trans_x`,`trans_y`,`trans_z`,`trans_o`, `transguid`,`gmstate`,`stable_slots`,`at_login`,`zone`,`online`,`pending_honor`,`last_honor_date`,`last_kill_date`,`taxi_path`,`instance`,`instancemode` FROM `character` WHERE `guid` = '%u'", GUID_LOPART(m_guid));
     res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP,           "SELECT `leaderGuid` FROM `group_member` WHERE `memberGuid`='%u'", GUID_LOPART(m_guid));
-    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES,  "SELECT `map`,`instance`,`leader` FROM `character_instance` WHERE `guid` = '%u'", GUID_LOPART(m_guid));
+    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES,  "SELECT `id`, `map`, `resettime` FROM `instance` WHERE `id` IN (SELECT `instance` FROM `character_instance` WHERE `guid` = '%u' AND `resettime` > '" I64FMTD "')", GUID_LOPART(m_guid), (uint64)time(NULL));
     res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS,           "SELECT `caster_guid`,`spell`,`effect_index`,`amount`,`maxduration`,`remaintime`,`remaincharges` FROM `character_aura` WHERE `guid` = '%u'", GUID_LOPART(m_guid));
     res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS,          "SELECT `spell`,`slot`,`active` FROM `character_spell` WHERE `guid` = '%u'", GUID_LOPART(m_guid));
     res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS,     "SELECT `quest`,`status`,`rewarded`,`explored`,`timer`,`mobcount1`,`mobcount2`,`mobcount3`,`mobcount4`,`itemcount1`,`itemcount2`,`itemcount3`,`itemcount4` FROM `character_queststatus` WHERE `guid` = '%u'", GUID_LOPART(m_guid));
@@ -395,7 +395,20 @@
     else
         SetPlayer(pCurrChar);
 
-    pCurrChar->SendDungeonDifficulty();
+    Group *group = pCurrChar->GetGroup();
+    if(group && pCurrChar->getLevel() >= LEVELREQUIREMENT_HEROIC)
+    {
+        pCurrChar->SetInstanceMode(group->GetGroupMode());
+        pCurrChar->SendInstanceMode(true);
+    }
+    else if(pCurrChar->GetInstanceId() != 0 && pCurrChar->GetInstanceMode() == INSTANCEMODE_HEROIC && pCurrChar->getLevel() >= LEVELREQUIREMENT_HEROIC)
+        pCurrChar->SendInstanceMode(false);
+    else
+    {
+        pCurrChar->SetInstanceMode(INSTANCEMODE_NORMAL);
+        if(pCurrChar->getLevel() >= LEVELREQUIREMENT_HEROIC)
+            pCurrChar->SendInstanceMode(false);
+    }
 
     WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 );
     data << pCurrChar->GetMapId();
@@ -517,7 +530,11 @@
 
     if (!MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->AddInstanced(pCurrChar))
     {
-        // TODO : Teleport to zone-in area
+        AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId());
+        if(at)
+            pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
+        else
+            pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation());
     }
 
     MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar);
@@ -531,10 +548,10 @@
     pCurrChar->SetInGameTime( getMSTime() );
 
     // announce group about member online (must be after add to player list to receive announce to self)
-    if(pCurrChar->GetGroup())
+    if(group)
     {
         //pCurrChar->groupInfo.group->SendInit(this); // useless
-        pCurrChar->GetGroup()->SendUpdate();
+        group->SendUpdate();
     }
 
     // friend status
Index: src/game/Group.cpp
===================================================================
--- src/game/Group.cpp	(revision 5236)
+++ src/game/Group.cpp	(working copy)
@@ -26,6 +26,7 @@
 #include "Group.h"
 #include "ObjectAccessor.h"
 #include "BattleGround.h"
+#include "MapManager.h"
 
 Group::Group()
 {
@@ -73,14 +74,22 @@
     if(!AddMember(guid, name))
         return false;
 
+    Player *player = objmgr.GetPlayer(guid);
+    if(player)
+    {
+        m_groupMode = player->GetInstanceMode();
+    }
+    else
+        m_groupMode = INSTANCEMODE_NORMAL;
+
     // store group in database
     CharacterDatabase.BeginTransaction();
     CharacterDatabase.PExecute("DELETE FROM `group` WHERE `leaderGuid`='%u'", GUID_LOPART(m_leaderGuid));
     CharacterDatabase.PExecute("DELETE FROM `group_member` WHERE `leaderGuid`='%u'", GUID_LOPART(m_leaderGuid));
-    CharacterDatabase.PExecute("INSERT INTO `group`(`leaderGuid`,`mainTank`,`mainAssistant`,`lootMethod`,`looterGuid`,`lootThreshold`,`icon1`,`icon2`,`icon3`,`icon4`,`icon5`,`icon6`,`icon7`,`icon8`,`isRaid`) "
-        "VALUES('%u','%u','%u','%u','%u','%u','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "',0)",
+    CharacterDatabase.PExecute("INSERT INTO `group`(`leaderGuid`,`mainTank`,`mainAssistant`,`lootMethod`,`looterGuid`,`lootThreshold`,`icon1`,`icon2`,`icon3`,`icon4`,`icon5`,`icon6`,`icon7`,`icon8`,`isRaid`,`groupmode`) "
+        "VALUES('%u','%u','%u','%u','%u','%u','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "',0,'%u')",
         GUID_LOPART(m_leaderGuid), GUID_LOPART(m_mainTank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod),
-        GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7]);
+        GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], m_groupMode);
 
     for(Group::member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
     {
@@ -94,8 +103,8 @@
 
 bool Group::LoadGroupFromDB(const uint64 &leaderGuid)
 {
-    //                                             0          1               2            3            4               5       6       7       8       9       10      11      12      13
-    QueryResult *result = CharacterDatabase.PQuery("SELECT `mainTank`,`mainAssistant`,`lootMethod`,`looterGuid`,`lootThreshold`,`icon1`,`icon2`,`icon3`,`icon4`,`icon5`,`icon6`,`icon7`,`icon8`,`isRaid` FROM `group` WHERE `leaderGuid`='%u'", GUID_LOPART(leaderGuid));
+    //                                             0          1               2            3            4               5       6       7       8       9       10      11      12      13       14
+    QueryResult *result = CharacterDatabase.PQuery("SELECT `mainTank`,`mainAssistant`,`lootMethod`,`looterGuid`,`lootThreshold`,`icon1`,`icon2`,`icon3`,`icon4`,`icon5`,`icon6`,`icon7`,`icon8`,`isRaid`,`groupmode` FROM `group` WHERE `leaderGuid`='%u'", GUID_LOPART(leaderGuid));
     if(!result)
         return false;
 
@@ -109,6 +118,7 @@
     }
 
     m_groupType  = (*result)[13].GetBool() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL;
+    m_groupMode = (*result)[14].GetUInt8();
     m_mainTank = (*result)[0].GetUInt64();
     m_mainAssistant = (*result)[1].GetUInt64();
     m_lootMethod = (LootMethod)(*result)[2].GetUInt8();
@@ -182,8 +192,14 @@
 
     Player *player = objmgr.GetPlayer(guid);
     if(player)
+    {
+        if(!IsLeader(player->GetGUID()) && player->getLevel() >= LEVELREQUIREMENT_HEROIC && player->GetInstanceMode() != GetGroupMode())
+        {
+            player->SetInstanceMode(m_groupMode); //åñëè ïðèíèìàåìûé ïëååð íå ëèäåð è åãî õåðîèê ìîä íå ñîâïàäàåò ñ õåðîèê ìîäîì â ãðóïïå òî ìåíÿåì åãî
+            player->SendInstanceMode(true);
+        }
         UpdatePlayerOutOfRange(player, GROUP_UPDATE_FULL);
-
+    }
     return true;
 }
 
@@ -807,7 +823,7 @@
         data << (uint8)m_lootMethod;                        // loot method
         data << m_looterGuid;                               // looter guid
         data << (uint8)m_lootThreshold;                     // loot threshold
-        data << (uint8)0;                                   // 2.1.0 unk
+        data << (uint8)m_groupMode;                         // Heroic Mod Group
 
         player->GetSession()->SendPacket( &data );
     }
@@ -862,6 +878,8 @@
     if(!guid)
         return false;
 
+    Player *player = objmgr.GetPlayer(guid);
+
     MemberSlot member;
     member.guid      = guid;
     member.name      = name;
@@ -869,11 +887,11 @@
     member.assistant = isAssistant;
     m_memberSlots.push_back(member);
 
-    Player *player = objmgr.GetPlayer(guid);
     if(player)
     {
         player->SetGroupInvite(NULL);
         player->SetGroup(this, group);
+        player->m_InstanceValid = true;
     }
 
     if(!isRaidGroup())                                      // reset targetIcons for non-raid-groups
@@ -923,7 +941,7 @@
         return;
 
     // instance system leader change process
-    if (m_leaderGuid != slot->guid)
+    /*if (m_leaderGuid != slot->guid)
     {
         // here we must unbind all instances bound to that leader on group members from the
         // leader, and rebind them on the players
@@ -1001,7 +1019,7 @@
             ss << ")) AND (`leader` = '" << GUID_LOPART(old_guid) << "')";
             CharacterDatabase.Execute(ss.str().c_str());
         }
-    }
+    }*/
 
     CharacterDatabase.BeginTransaction();
     CharacterDatabase.PExecute("UPDATE `group` SET `leaderGuid`='%u' WHERE `leaderGuid`='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_leaderGuid));
@@ -1127,3 +1145,70 @@
     // called from link()
     this->getTarget()->addLootValidatorRef(this);
 }
+
+void Group::SetGroupMode(uint8 groupmode)
+{
+    m_groupMode = groupmode;
+    CharacterDatabase.PExecute("UPDATE `group` SET `groupmode` = %u WHERE `leaderGuid`='%u'", m_groupMode, GUID_LOPART(m_leaderGuid));
+
+    Player *player;
+
+    for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
+    {
+        player = NULL;
+        player = itr->getSource();
+        if(!player || !player->GetSession() || player->getLevel() < LEVELREQUIREMENT_HEROIC)
+            continue;
+        player->SetInstanceMode(groupmode);
+        player->SendInstanceMode(true);
+    }
+}
+
+bool Group::InInstance(bool SendMess)
+{                  
+    Player *player;
+    bool resultIn = false;
+    for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
+    {
+        player = objmgr.GetPlayer(citr->guid);
+        if(player && player->GetInstanceId() != 0 && player->GetSession())
+        {
+            if(SendMess)
+                player->SendCannotReset(player->GetMapId());
+            resultIn = true;
+        }
+        else
+        {
+            QueryResult* result = CharacterDatabase.PQuery("SELECT `instance` FROM `character` WHERE `guid`='%u';", GUID_LOPART(citr->guid));
+            if((*result)[0].GetBool() ? 1 : 0)
+                resultIn = true;
+            delete result;
+        }
+    }
+    return resultIn;
+}
+
+bool Group::InCombatToInstance(uint32 instanceId)
+{
+    Player *pPlayer;
+    for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
+    {
+        pPlayer = NULL;
+        pPlayer = itr->getSource();
+        if(pPlayer && pPlayer->getAttackers().size() && pPlayer->GetInstanceId() == instanceId)
+            return true;
+    }
+    return false;
+}
+
+void Group::ResetInstance(bool SendMsg)
+{
+    Player *player;
+
+    for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
+    {
+        player = objmgr.GetPlayer(citr->guid);
+        if(player)
+            player->ResetInstance(SendMsg);
+    }
+}
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(revision 5236)
+++ src/game/Player.cpp	(working copy)
@@ -36,6 +36,7 @@
 #include "ChannelMgr.h"
 #include "MapManager.h"
 #include "MapInstanced.h"
+#include "MapInstancedSaveMgr.h"
 #include "GridNotifiers.h"
 #include "GridNotifiersImpl.h"
 #include "CellImpl.h"
@@ -141,8 +142,6 @@
     m_GuildIdInvited = 0;
     m_ArenaTeamIdInvited = 0;
 
-    m_dungeonDifficulty = DUNGEONDIFFICULTY_NORMAL;
-
     m_atLoginFlags = AT_LOGIN_NONE;
 
     m_dontMove = false;
@@ -334,7 +333,7 @@
         ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);
         if(!rEntry)
         {
-            sLog.outError("Race %u not found in DBÑ (Wrong DBC files?)",race);
+            sLog.outError("Race %u not found in DBï¿½ (Wrong DBC files?)",race);
             return false;
         }
 
@@ -1592,7 +1591,6 @@
         {
             // yes, we are going to be homebind, avoid this action :)
             SetInstanceId(0);                               // reset instance id
-            m_BoundInstances.erase(mapid);                  // unbind our instance binding
                                                             // obtain new map
             map = MapManager::Instance().GetMap(mapid, this);
         }
@@ -1618,11 +1616,8 @@
                 data << (uint32)mapid << (float)x << (float)y << (float)z << (float)orientation;
             }
             GetSession()->SendPacket( &data );
+            sInstanceSavingManager.BuildSavedInstancesForPlayer(this);
 
-            data.Initialize(SMSG_UNKNOWN_811, 4);
-            data << uint32(0);
-            GetSession()->SendPacket( &data );
-
             // remove from old map now
             if (oldmap) oldmap->Remove(this, false);
 
@@ -1848,7 +1843,7 @@
 bool Player::IsUnderWater() const
 {
     return IsInWater() &&
-        GetPositionZ() < (MapManager::Instance().GetBaseMap(GetMapId())->GetWaterLevel(GetPositionX(),GetPositionY())-2);
+        GetPositionZ() < (MapManager::Instance().GetBaseMap(GetMapId(), 0)->GetWaterLevel(GetPositionX(),GetPositionY())-2);
 }
 
 void Player::SetInWater(bool apply)
@@ -3322,7 +3317,7 @@
     CharacterDatabase.PExecute("DELETE FROM `character_aura` WHERE `guid` = '%u'",guid);
     CharacterDatabase.PExecute("DELETE FROM `character_gifts` WHERE `guid` = '%u'",guid);
     CharacterDatabase.PExecute("DELETE FROM `character_homebind` WHERE `guid` = '%u'",guid);
-    CharacterDatabase.PExecute("DELETE FROM `character_instance` WHERE `leader` = '%u'",guid);
+    CharacterDatabase.PExecute("DELETE FROM `character_instance` WHERE `guid` = '%u'",guid);
     CharacterDatabase.PExecute("DELETE FROM `character_inventory` WHERE `guid` = '%u'",guid);
     CharacterDatabase.PExecute("DELETE FROM `character_kill` WHERE `guid` = '%u'",guid);
     CharacterDatabase.PExecute("DELETE FROM `character_queststatus` WHERE `guid` = '%u'",guid);
@@ -4968,7 +4963,7 @@
     if (isInFlight())
         return;
 
-    uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY());
+    uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId(), 0)->GetAreaFlag(GetPositionX(),GetPositionY());
     if(areaFlag==0xffff)return;
     int offset = areaFlag / 32;
 
@@ -12445,8 +12440,8 @@
     bool delete_result = true;
     if(!result)
     {
-        //                                        0      1      2            3            4            5     6           7           8
-        result = CharacterDatabase.PQuery("SELECT `data`,`name`,`position_x`,`position_y`,`position_z`,`map`,`totaltime`,`leveltime`,`at_login` FROM `character` WHERE `guid` = '%u'",guid);
+        //                                        0      1      2            3            4            5     6           7           8          9
+        result = CharacterDatabase.PQuery("SELECT `data`,`name`,`position_x`,`position_y`,`position_z`,`map`,`totaltime`,`leveltime`,`at_login`,`instance` FROM `character` WHERE `guid` = '%u'",guid);
         if(!result) return false;
     }
     else delete_result = false;
@@ -12468,6 +12463,7 @@
 
     Relocate(fields[2].GetFloat(),fields[3].GetFloat(),fields[4].GetFloat());
     SetMapId(fields[5].GetUInt32());
+    SetInstanceId(fields[9].GetUInt32());
 
     m_Played_time[0] = fields[6].GetUInt32();
     m_Played_time[1] = fields[7].GetUInt32();
@@ -12562,7 +12558,7 @@
 bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
 {
     ////                                                     0      1         2      3      4      5       6            7            8            9     10            11         12          13          14          15           16            17                  18                  19                  20        21        22        23         24          25        26             27         [28]   [29]     30              31                32               33
-    //QueryResult *result = CharacterDatabase.PQuery("SELECT `guid`,`account`,`data`,`name`,`race`,`class`,`position_x`,`position_y`,`position_z`,`map`,`orientation`,`taximask`,`cinematic`,`totaltime`,`leveltime`,`rest_bonus`,`logout_time`,`is_logout_resting`,`resettalents_cost`,`resettalents_time`,`trans_x`,`trans_y`,`trans_z`,`trans_o`, `transguid`,`gmstate`,`stable_slots`,`at_login`,`zone`,`online`,`pending_honor`,`last_honor_date`,`last_kill_date`,`taxi_path` FROM `character` WHERE `guid` = '%u'", guid);
+    //QueryResult *result = CharacterDatabase.PQuery("SELECT `guid`,`account`,`data`,`name`,`race`,`class`,`position_x`,`position_y`,`position_z`,`map`,`orientation`,`taximask`,`cinematic`,`totaltime`,`leveltime`,`rest_bonus`,`logout_time`,`is_logout_resting`,`resettalents_cost`,`resettalents_time`,`trans_x`,`trans_y`,`trans_z`,`trans_o`, `transguid`,`gmstate`,`stable_slots`,`at_login`,`zone`,`online`,`pending_honor`,`last_honor_date`,`last_kill_date`,`taxi_path`,`instance`,`instancemode` FROM `character` WHERE `guid` = '%u'", guid);
     QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM);
 
     if(!result)
@@ -12642,6 +12638,8 @@
     uint32 transGUID = fields[24].GetUInt32();
     Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat());
     SetMapId(fields[9].GetUInt32());
+    SetInstanceId(fields[33].GetUInt32());
+    SetInstanceMode(fields[34].GetUInt8());
 
     _LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
 
@@ -13629,16 +13627,52 @@
         do
         {
             Field *fields = result->Fetch();
-            m_BoundInstances[fields[0].GetUInt32()] = std::pair< uint32, uint32 >(fields[1].GetUInt32(), fields[2].GetUInt32());
+            SaveInstance * inst = new SaveInstance;
+            inst->InstanceId = fields[0].GetUInt32();
+            inst->MapId = fields[1].GetUInt32();
+            inst->ResetTime = (time_t)fields[2].GetUInt64();
+            m_BoundInstances[fields[0].GetUInt32()] = inst;
         } while(result->NextRow());
         delete result;
     }
+}
 
-    // correctly set current instance (if needed)
-    BoundInstancesMap::iterator i = m_BoundInstances.find(GetMapId());
-    if (i != m_BoundInstances.end()) SetInstanceId(i->second.first); else SetInstanceId(0);
+void Player:: AddSaveInstance(uint32 InstanceId, uint32 mapId, time_t ResetTime)
+{
+    if(FindSaveInstance(mapId))
+        return;
+    SaveInstance * inst = new SaveInstance;
+    inst->InstanceId = InstanceId;
+    inst->MapId = mapId;
+    inst->ResetTime = ResetTime;
+    m_BoundInstances[InstanceId] = inst;
+    if(GetInstanceId() == InstanceId)
+    {
+        WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
+        data << uint32(0);
+        GetSession()->SendPacket(&data);
+    }
 }
 
+void Player::BuildRaidInfo()
+{
+    WorldPacket data(SMSG_RAID_INSTANCE_INFO, 4);;
+    uint32 counter = m_BoundInstances.size();
+    
+    data << counter;
+    for (BoundInstancesMap::iterator itr = m_BoundInstances.begin(); itr != m_BoundInstances.end(); itr++)
+    {
+        if(itr->second->ResetTime - time(NULL) < 0)
+            continue;
+        data << (itr->second->MapId);
+        data << (uint32)(itr->second->ResetTime - time(NULL));
+        data << itr->second->InstanceId;
+        data << uint32(counter);
+        counter -=1;
+    }
+    GetSession()->SendPacket(&data);
+}
+
 bool Player::_LoadHomeBind(QueryResult *result)
 {
     //QueryResult *result = CharacterDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid));
@@ -14331,15 +14365,44 @@
     GetSession()->SendPacket(&data);
 }
 
-void Player::SendDungeonDifficulty()
+void Player::SendInstanceMode(bool IsInGroup)
 {
     WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12);
-    data << m_dungeonDifficulty;
+    data << (uint32)GetInstanceMode();
     data << uint32(0x00000001);
-    data << uint32(0x00000000);
+    data << uint32(IsInGroup);
     GetSession()->SendPacket(&data);
 }
 
+void Player::SendCannotReset(uint32 mapid)
+{
+    WorldPacket data(SMSG_RESET_INSTANCE_FAILED_NOTIFY, 4);
+    data << uint32(mapid);
+    GetSession()->SendPacket(&data);
+}
+
+void Player::ResetInstance(bool SendMgs)
+{
+    sInstanceSavingManager.ResetSavedInstancesForPlayer(this, SendMgs);//SendMgs - ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½, ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½
+}
+
+void Player::SendResetInstance(uint32 MapId)
+{
+    WorldPacket data(SMSG_RESET_INSTANCES_SUCCESS, 4);
+    data << MapId;
+    GetSession()->SendPacket(&data);
+}
+
+uint32 Player::FindSaveInstance(uint32 mapid)
+{
+    for (BoundInstancesMap::iterator itr = m_BoundInstances.begin(); itr != m_BoundInstances.end(); itr++)
+    {
+        if( itr->second->MapId == mapid && itr->second->ResetTime > time_t(NULL))
+            return itr->first;
+    }
+    return 0;
+}
+
 /*********************************************************/
 /***              Update timers                        ***/
 /*********************************************************/
@@ -15382,7 +15445,7 @@
     CharacterDatabase.PExecute("DELETE FROM `character_instance` WHERE (`guid` = '%u')", GetGUIDLow());
     for(BoundInstancesMap::iterator i = m_BoundInstances.begin(); i != m_BoundInstances.end(); i++)
     {
-        CharacterDatabase.PExecute("INSERT INTO `character_instance` (`guid`,`map`,`instance`,`leader`) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), i->first, i->second.first, i->second.second);
+        CharacterDatabase.PExecute("INSERT INTO `character_instance` (`guid`,`map`,`instance`) VALUE ('%u', '%u', '%u');", (uint32)GetGUID(), i->second->MapId, i->second->InstanceId);
     }
 }
 
@@ -15997,8 +16060,17 @@
     GetSession()->SendPacket(&data);
 }
 
-void Player::SendRaidInstanceResetWarning(uint32 type, uint32 mapid, uint32 time)
+void Player::SendRaidInstanceResetWarning(uint32 mapid, uint32 time)
 {
+    uint32 type;//ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
+    if(time > 3600)                        // (ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½
+        type = RAID_INSTANCE_WELCOME;
+    else if(time > 900 && time <= 3600)    // (ï¿½ï¿½ 15ï¿½ï¿½ï¿½ ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½]
+        type = RAID_INSTANCE_WARNING_HOURS;
+    else if(time > 300 && time <= 900)     // (ï¿½ï¿½ 5ï¿½ï¿½ï¿½ ï¿½ï¿½ 15ï¿½ï¿½ï¿½]
+        type = RAID_INSTANCE_WARNING_MIN;
+    else                                   // ï¿½ï¿½ï¿½ï¿½ï¿½ 5ï¿½ï¿½ï¿½]
+        type = RAID_INSTANCE_WARNING_MIN_SOON;
     WorldPacket data(SMSG_INSTANCE_RESET_SCHEDULED, 4+4+4);
     data << uint32(type);
     data << uint32(mapid);
Index: src/game/RandomMovementGenerator.cpp
===================================================================
--- src/game/RandomMovementGenerator.cpp	(revision 5236)
+++ src/game/RandomMovementGenerator.cpp	(working copy)
@@ -41,7 +41,7 @@
     creature.GetRespawnDist(wander_distance);
     uint32 mapid=creature.GetMapId();
 
-    Map const* map = MapManager::Instance().GetBaseMap(mapid);
+    Map const* map = MapManager::Instance().GetBaseMap(mapid, creature.GetInstanceMode());
     // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid
     z2 = map->GetHeight(x,y,z, false);                      // use .map base surface height
     if( fabs( z2 - z ) < 5 )
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 5236)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -481,6 +481,8 @@
             float pos_y = m_target->GetPositionY();
             float pos_z = m_target->GetPositionZ();
             uint32 mapid = m_target->GetMapId();
+
+//            float pos_z = MapManager::Instance().GetBaseMap(mapid, 0)->GetHeight(pos_x,pos_y, m_target->GetPositionZ());
             // Control the max Distance; 28 for temp.
             if(m_target->IsWithinDistInMap(caster, 28))
             {
@@ -489,6 +491,8 @@
                 float z = pos_z;
                 m_target->UpdateGroundPositionZ(x,y,z);
 
+//                float z = MapManager::Instance().GetBaseMap(mapid, 0)->GetHeight(x,y, m_target->GetPositionZ());
+
                 // Control the target to not climb or drop when dz > |x|,x = 1.3 for temp.
                 // fixed me if it needs checking when the position will be in water?
                                                             //+vmaps
@@ -507,6 +511,8 @@
                     float z = pos_z;
                     m_target->UpdateGroundPositionZ(x,y,z);
 
+//                    z = MapManager::Instance().GetBaseMap(mapid, 0)->GetHeight(x,y, m_target->GetPositionZ());
+
                     if((z<=pos_z+1.3 && z>=pos_z-1.3) && m_target->IsWithinLOS(x,y,z))
                     {
                         m_target->SendMonsterMove(x,y,z,0,true,(diff*2));
Index: src/game/Spell.cpp
===================================================================
--- src/game/Spell.cpp	(revision 5236)
+++ src/game/Spell.cpp	(working copy)
@@ -3157,7 +3157,7 @@
                     return SPELL_FAILED_TARGET_IN_COMBAT;
 
                 // check if our map is instanceable
-                if( MapManager::Instance().GetBaseMap(m_caster->GetMapId())->Instanceable() && !m_caster->IsInMap(target) )
+                if( MapManager::Instance().GetBaseMap(m_caster->GetMapId(), m_caster->GetInstanceMode())->Instanceable() && !m_caster->IsInMap(target) )
                     return SPELL_FAILED_TARGET_NOT_IN_INSTANCE;
 
                 break;
@@ -3169,7 +3169,7 @@
                 float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
                 float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
                 // teleport a bit above terrainlevel to avoid falling below it
-                float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx,fy,m_caster->GetPositionZ(),true);
+                float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId(), 0)->GetHeight(fx,fy,m_caster->GetPositionZ(),true);
                 if(fz <= INVALID_HEIGHT)                    // note: this also will prevent use effect in instances without vmaps height enabled
                     return SPELL_FAILED_TRY_AGAIN;
 
Index: src/game/WaypointMovementGenerator.h
===================================================================
--- src/game/WaypointMovementGenerator.h	(revision 5236)
+++ src/game/WaypointMovementGenerator.h	(working copy)
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,34 +25,56 @@
  * packets for the players.
  */
 
+class Player;
+
+//Movement classes
 #include "MovementGenerator.h"
 #include "DestinationHolder.h"
 #include "Path.h"
 #include "Traveller.h"
 
-#include "Player.h"
-
-#include <vector>
-#include <set>
-
 #define FLIGHT_TRAVEL_UPDATE  100
 
 #define VISUAL_WAYPOINT 1
 
-struct WaypointBehavior
+struct WaypointData
 {
-    uint32 emote;
-    uint32 spell;
-    std::string text[5];
-    float orientation;
-    uint32 model1;
-    uint32 model2;
-    std::string aiscript;
-    bool HasDone;
+    uint32 id;
+    float x,y,z;
+    bool run;
+    uint32 delay;
+    uint32 event_id;
+    uint8 event_chance;
 };
 
+typedef std::vector<WaypointData*> WaypointPath;
+
+WaypointData* CreateWaypoint(uint32 id, float x, float y, float z, bool run, uint32 delay, uint32 event_id, uint8 event_chance);
+
+class WaypointStore
+{
+    private :
+        WaypointPath **data;
+        uint32 records;
+    public:
+        void Load();
+        void Free();
+        
+        WaypointPath * GetPath(uint32 id)
+        {
+            if(!id || id > records)
+                return NULL;
+            else
+                return data[id];
+        }
+
+        inline uint32 GetRecordsCount() { return records; }
+};
+
+extern WaypointStore sWaypointStore;
+
 template<class T>
-class MANGOS_DLL_DECL PathMovementBase
+class MANGOS_DLL_SPEC PathMovementBase
 {
     public:
         PathMovementBase() : i_currentNode(0) {}
@@ -60,68 +82,82 @@
 
         inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
 
-        // template pattern, not defined .. override required
         void LoadPath(T &);
         void ReloadPath(T &);
+	void WPAIScript();
         uint32 GetCurrentNode()
         {
             return i_currentNode;
         }
 
+        void Finalize(T &);
+
     protected:
         uint32 i_currentNode;
         DestinationHolder< Traveller<T> > i_destinationHolder;
         Path i_path;
 };
 
-/** WaypointMovementGenerator loads a series of way points
- * from the DB and apply it to the creature's movement generator.
- * Hence, the creature will move according to its predefined way points.
- */
+template<class T>
+void PathMovementBase<T>::WPAIScript() {}
 
 template<class T>
-class MANGOS_DLL_DECL WaypointMovementGenerator;
-
-template<>
-class MANGOS_DLL_DECL WaypointMovementGenerator<Creature>
-: public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >,
-public PathMovementBase<Creature>
+class MANGOS_DLL_SPEC WaypointMovementGenerator
+    : public MovementGeneratorMedium< T, WaypointMovementGenerator<T> >
 {
-    TimeTracker i_nextMoveTime;
-    std::vector<uint32> i_delays;
-    std::vector<WaypointBehavior *> i_wpBehaviour;
     public:
-        WaypointMovementGenerator(Creature &) : i_nextMoveTime(0) {}
-        ~WaypointMovementGenerator() { ClearWaypoints(); }
-        void WPAIScript(Creature &pCreature, std::string pAiscript);
-        void Initialize(Creature &u)
+        WaypointMovementGenerator(T &, uint32 _path_id = 0, bool _repeating = true) : 
+          i_nextMoveTime(0), path_id(_path_id), repeating(_repeating), custom_path(false) {}
+        ~WaypointMovementGenerator() 
         {
-            i_nextMoveTime.Reset(0);                        // TODO: check the lower bound (0 is probably too small)
-            u.StopMoving();
-            LoadPath(u);
+            if(custom_path)
+            {
+                for(WaypointPath::iterator itr = waypoints->begin(); itr!= waypoints->end();)
+                {
+                    delete (*itr);
+                    itr = waypoints->erase(itr);
+                }
+                delete waypoints;
+            }
         }
-        void Finalize(Creature &) {}
-        void Reset(Creature &u) { ReloadPath(u); }
-        bool Update(Creature &u, const uint32 &diff);
+        
+        void Initialize(T &);
+        void Finalize(T &) {}
+	void LoadPath(Creature &c);
+	void ClearWaypoints();
+        
+
+        void UseCustomPath(uint32 custom_id, WaypointPath *data)
+        {
+            custom_path = true;
+            path_id = custom_id;
+            waypoints = data;
+        }
+
+        void MovementInform(T &);
+
+        void GeneratePathId(T &);
+        void SetMoveFlag(T &, bool flag); //Will change it to real type once we have real movement types ...
+        void Reset(T &);
+        bool Update(T &, const uint32 &);
         MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; }
 
-        // now path movement implmementation
-        void LoadPath(Creature &c);
-        void ReloadPath(Creature &c) { ClearWaypoints(); LoadPath(c); }
-
-        // statics
-        static void Initialize(void);
     private:
-        void ClearWaypoints();
-        static std::set<uint32> si_waypointHolders;
+        uint32 i_currentNode;
+        DestinationHolder< Traveller<T> > i_destinationHolder;
+        TimeTracker i_nextMoveTime;
+        WaypointPath *waypoints;
+        uint32 path_id;
+        bool repeating, custom_path;
+	static std::set<uint32> si_waypointHolders;
 };
 
 /** FlightPathMovementGenerator generates movement of the player for the paths
  * and hence generates ground and activities for the player.
  */
-class MANGOS_DLL_DECL FlightPathMovementGenerator
-: public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
-public PathMovementBase<Player>
+class MANGOS_DLL_SPEC FlightPathMovementGenerator
+    : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, 
+      public PathMovementBase<Player>
 {
     uint32 i_pathId;
     std::vector<uint32> i_mapIds;
@@ -142,4 +178,29 @@
         uint32 GetPathAtMapEnd() const;
         inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
 };
+
+template<class T>
+class MANGOS_DLL_SPEC PointMovementGenerator
+    : public MovementGeneratorMedium< T, PointMovementGenerator<T> >
+{
+    public:
+        PointMovementGenerator(uint32 _id, float _x, float _y, float _z) : id(_id), 
+            x(_x), y(_y), z(_z), i_nextMoveTime(0) {}
+
+        void Initialize(T &);
+        void Finalize(T &) {}
+        void Reset(T &unit) { unit.StopMoving(); }
+        bool Update(T &, const uint32 &diff);
+
+        void MovementInform(T &);
+
+        MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; }
+
+    private:
+        TimeTracker i_nextMoveTime;
+        float x,y,z;
+        uint32 id;
+        DestinationHolder< Traveller<T> > i_destinationHolder;
+};
+
 #endif
Index: src/game/BattleGroundWS.cpp
===================================================================
--- src/game/BattleGroundWS.cpp	(revision 5236)
+++ src/game/BattleGroundWS.cpp	(working copy)
@@ -109,6 +109,22 @@
                 RespawnFlag(HORDE, true);
         }
     }
+
+    if(m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
+    {
+        m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff;
+
+        if(m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
+            EventDropTimerReturnedFlag(ALLIANCE);
+    }
+    if(m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
+    {
+        m_FlagsTimer[BG_TEAM_HORDE] -= diff;
+
+        if(m_FlagsTimer[BG_TEAM_HORDE] < 0)
+            EventDropTimerReturnedFlag(HORDE);
+
+    }
 }
 
 void BattleGroundWS::AddPlayer(Player *plr)
@@ -229,6 +245,7 @@
                 message = GetMangosString(LANG_BG_WS_DROPPED_HF);
                 type = CHAT_MSG_BG_SYSTEM_HORDE;
                 Source->CastSpell(Source, 23334, true);
+                m_FlagsTimer[BG_TEAM_HORDE] = 10000;
                 set = true;
             }
         }
@@ -245,6 +262,7 @@
                 message = GetMangosString(LANG_BG_WS_DROPPED_AF);
                 type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
                 Source->CastSpell(Source, 23336, true);
+                m_FlagsTimer[BG_TEAM_ALLIANCE] = 10000;
                 set = true;
             }
         }
@@ -265,6 +283,35 @@
     }
 }
 
+void BattleGroundWS::EventDropTimerReturnedFlag(uint32 Team)
+{
+    if(GetStatus() != STATUS_IN_PROGRESS)
+        return;
+
+    const char *message;
+
+    if(Team == ALLIANCE)
+    {
+        message = GetMangosString(LANG_BG_WS_RETURNED_AF);
+        UpdateFlagState(HORDE, 1);
+        RespawnFlag(ALLIANCE, false);
+        SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
+    }
+    else
+    {
+        message = GetMangosString(LANG_BG_WS_RETURNED_HF);
+        UpdateFlagState(ALLIANCE, 1);
+        RespawnFlag(HORDE, false);
+        SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
+    }
+
+    PlaySoundToAll(8192);
+
+    WorldPacket data;
+    ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, message, NULL);
+    SendPacketToAll(&data);
+}
+
 void BattleGroundWS::EventPlayerReturnedFlag(Player *Source)
 {
     if(GetStatus() != STATUS_IN_PROGRESS)
Index: src/game/ObjectGridLoader.cpp
===================================================================
--- src/game/ObjectGridLoader.cpp	(revision 5236)
+++ src/game/ObjectGridLoader.cpp	(working copy)
@@ -120,6 +120,8 @@
             delete obj;
             continue;
         }
+        if(obj->GetInstanceMode() != map->GetInstanceMode())
+            continue;
 
         obj->SetInstanceId(map->GetInstanceId());
         obj->GetGridRef().link(&m, obj);
Index: src/game/MapInstanced.cpp
===================================================================
--- src/game/MapInstanced.cpp	(revision 5236)
+++ src/game/MapInstanced.cpp	(working copy)
@@ -21,8 +21,9 @@
 #include "MapManager.h"
 #include "BattleGround.h"
 #include "VMapFactory.h"
+#include "MapInstancedSaveMgr.h"
 
-MapInstanced::MapInstanced(uint32 id, time_t expiry, uint32 aInstanceId) : Map(id, expiry, 0)
+MapInstanced::MapInstanced(uint32 id, time_t expiry, uint32 aInstanceId, uint8 HeroicMod) : Map(id, expiry, 0, HeroicMod)
 {
     // initialize instanced maps list
     m_InstancedMaps.clear();
@@ -40,22 +41,18 @@
 
     while (i != m_InstancedMaps.end())
     {
-        if (i->second->NeedsReset())
+        uint32 resetTime = uint32(i->second->GetResetTimeMap() - time(NULL)); //åñëè ïðèøëî âðåìÿ ðåñåòà òî óäàëåì êàðòó
+        if(resetTime == 3600 || resetTime == 900 || resetTime == 300 || resetTime == 61 || i->second->NeedsReset())
         {
-            if (i->second->GetPlayersCount() == 0)
+            if(sInstanceSavingManager.SendResetWarning(i->second->GetId(), i->second->GetInstanceId(), i->second->GetResetTimeMap() - time(NULL)))
             {
-                i->second->Reset();
-                // avoid doing ++ on invalid data
-                InstancedMaps::iterator i_old = i;
+                uint32 tempId = i->second->GetInstanceId();
                 ++i;
-                // erase map
-                delete i_old->second;
-                m_InstancedMaps.erase(i_old);
+                DestroyInstance(tempId);
             }
             else
             {
-                // shift reset time of the map
-                i->second->InitResetTime();
+                i->second->Update(t);
                 ++i;
             }
         }
@@ -117,19 +114,25 @@
 
     if (obj->GetTypeId() != TYPEID_PLAYER)
     {
-        sLog.outDebug("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) is requesting instance '%u' of map '%u', instantiating", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), InstanceId, GetId());
+        //sLog.outDebug("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) is requesting instance '%u' of map '%u', instantiating", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), InstanceId, GetId());
 
         if (InstanceId == 0)
         {
-            sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) requested base map instance of map '%u', this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), GetId());
+            //sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) requested base map instance of map '%u', this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), GetId());
             return(this);
         }
 
         // short instantiate process for world object
-        CreateInstance(InstanceId, map);
+        CreateInstance(InstanceId, map, obj);
         return(map);
     }
-
+    if (map) return(map);
+ 
+    if(InstanceId != 0)
+    {
+        CreateInstance(InstanceId, map, obj);//ýòî ñëó÷àé êîãäà ïëååð âûøåë èç èãðû â èíñòàíöèè è ïîêà åãî íå áûëî - ñåðâåð ñëåòåë, ïîìåùàåì ïëååðà â èíñòàíöèþ ñ òåì æå ID
+        if(map) return map;
+    }
     // here we do additionally verify, if the player is allowed in instance by leader
     // and if it has current instance bound correctly
     Player* player = (Player*)obj;
@@ -137,7 +140,24 @@
     // reset instance validation flag
     player->m_InstanceValid = true;
 
-    BoundInstancesMap::iterator i = player->m_BoundInstances.find(GetId());
+    if(GetMapInfo()->map_type == MAP_RAID || (GetMapInfo()->supportMode == MAPDIFFICULTY_HEROIC_SUPPORTED && player->GetInstanceMode() == INSTANCEMODE_HEROIC))
+    {
+        InstanceId = player->FindSaveInstance(GetId());
+        if(InstanceId)
+        {
+            map = _FindMap(InstanceId);
+            if(map)
+            {
+                if (player->GetPet()) player->GetPet()->SetInstanceId(InstanceId);//åñëè èíñàíöèÿ ñóùåñòâóåò(êòî òî èõ åãî æå ðåéäà óæå ñîçäàë å¸) òî âîçâðàùàåì å¸
+                return map;
+            }
+            if (player->GetPet()) player->GetPet()->SetInstanceId(InstanceId);
+            player->SetInstanceId(InstanceId);
+            CreateInstance(InstanceId, map, player);//åñëè íåò òî ñîçäàåì èíñòàíöèþ ñ ID èç åãî ñýéâà
+            return map;
+        }
+    }
+    /*BoundInstancesMap::iterator i = player->m_BoundInstances.find(GetId());
     if (i != player->m_BoundInstances.end())
     {
         // well, we have an instance bound, really, verify self or group leader
@@ -285,18 +305,45 @@
             }
             CharacterDatabase.CommitTransaction();
         }
+    }*/
+    Group *group = player->GetGroup();
+    if(group)
+    {
+        for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+        {
+            Player* Member = itr->getSource();
+            if(!Member)
+                continue;
+            if(Member->GetMapId() != GetId() || Member->GetGUID() == player->GetGUID())
+                continue;
+            InstanceId = Member->GetInstanceId();
+            if(!InstanceId)
+                continue;
+            map = _FindMap(InstanceId);
+            //if (player->GetPet()) player->GetPet()->SetInstanceId(InstanceId);
+            //player->SetInstanceId(InstanceId);
+            return (map);
+        }
     }
 
-    // set instance id for instantiating player
+    List_Instanced_Id *p = sInstanceSavingManager.GetInstanceForPlayer(GetId(), player);
+    if(p)
+    {
+        InstanceId = p->GetInstanceID();
+        map = _FindMap(InstanceId);
+        return (map);
+    }
+    InstanceId = MapManager::Instance().GenerateInstanceId();//ñîçäà¸ì íîâóþ èíñòàíöèþ
     if (player->GetPet()) player->GetPet()->SetInstanceId(InstanceId);
     player->SetInstanceId(InstanceId);
-
+    CreateInstance(InstanceId, map, player);
+    // set instance id for instantiating player
     return(map);
 }
 
-void MapInstanced::CreateInstance(uint32 InstanceId, Map* &map)
+void MapInstanced::CreateInstance(uint32 InstanceId, Map* &map, const WorldObject* obj)
 {
-    if (!IsValidInstance(InstanceId))
+    /*if (!IsValidInstance(InstanceId))
     {
         // instance is invalid, need to verify map presence
         if (map)
@@ -309,7 +356,7 @@
             delete map;
             map = NULL;
         }
-    }
+    }*/
 
     // verify, if we have the map created, and create it if needed
     if (!map)
@@ -317,23 +364,37 @@
         // map does not exist, create it
         Guard guard(*this);
 
-        map = new Map(GetId(), GetGridExpiry(), InstanceId);
+        map = new Map(GetId(), GetGridExpiry(), InstanceId, obj->GetInstanceMode());
         m_InstancedMaps[InstanceId] = map;
+        sInstanceSavingManager.SaveInstance(map);
+        if(obj->GetTypeId() == TYPEID_PLAYER)
+        {
+            Player* player = (Player*)obj;
+            sInstanceSavingManager.SavePlayerToInstance(player, map->GetId(), InstanceId);
+        }
     }
 }
 
-bool MapInstanced::IsValidInstance(uint32 InstanceId)
+void MapInstanced::DestroyInstance(uint32 InstanceId) //ëèêâèäàöèÿ èíñòàíöèè
 {
+    HM_NAMESPACE::hash_map< uint32, Map* >::iterator itr = m_InstancedMaps.find(InstanceId);
+    if(itr != m_InstancedMaps.end())
+    {
+        itr->second->Reset();
+        VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(itr->second->GetId());
+        // erase map
+        delete itr->second;
+        m_InstancedMaps.erase(itr);
+    }
+}
+
+/*bool MapInstanced::IsValidInstance(uint32 InstanceId)
+{
     // verify, if the map exists and needs to be reset
     Map* m = _FindMap(InstanceId);
 
     if (m && m->NeedsReset())
-    {
-        // check for real reset need (can only reset if no players)
-        if (m->GetPlayersCount() == 0) return(false);       // map exists, but needs reset
-        // shift reset time of the map to a bit later
-        m->InitResetTime();
-    }
+        return false; 
 
     // verify, if the map theoretically exists but not loaded
     QueryResult* result = CharacterDatabase.PQuery("SELECT '1' FROM `instance` WHERE (`id` = '%u') AND (`map` = '%u') AND (`resettime` > " I64FMTD ")", InstanceId, GetId(), (uint64)time(NULL));
@@ -344,5 +405,5 @@
     }
 
     // no map exists at all
-    return(false);
-}
+    return true;
+}*/
Index: src/game/Creature.cpp
===================================================================
--- src/game/Creature.cpp	(revision 5236)
+++ src/game/Creature.cpp	(working copy)
@@ -717,7 +717,7 @@
         QueryResult *result;
         Field *fields;
         uint32 mapid=GetMapId();
-        Map const* map=MapManager::Instance().GetBaseMap( mapid );
+        Map const* map=MapManager::Instance().GetBaseMap( mapid, GetInstanceMode() );
         uint16 areaflag=map->GetAreaFlag(GetPositionX(),GetPositionY());
         uint32 zoneid=map->GetZoneId(areaflag);
         std::string areaname= gossip->Option;
@@ -949,6 +949,7 @@
     data.curmana = GetPower(POWER_MANA);
     data.deathState = m_deathState;
     data.movementType = GetDefaultMovementType();
+    data.instanceMode = GetInstanceMode();
 
     // updated in DB
     WorldDatabase.BeginTransaction();
@@ -976,7 +977,8 @@
         << GetHealth() << ","                               //curhealth
         << GetPower(POWER_MANA) << ","                      //curmana
         << (uint32)(m_deathState) << ","                    //DeathState (0 or 65)
-        << GetDefaultMovementType() << ")";                 // default movement generator type
+        << GetDefaultMovementType() << ","                  // default movement generator type
+        << (uint32)GetInstanceMode() << ")";                //Heroic mode
 
     WorldDatabase.PExecuteLog( ss.str( ).c_str( ) );
 
@@ -1222,6 +1224,7 @@
 
     if (InstanceId != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
     SetInstanceId(InstanceId);
+    SetInstanceMode(data->instanceMode);
 
     uint16 team = 0;
     if(!Create(guid,data->mapid,data->posX,data->posY,data->posZ,data->orientation,data->id,team,data))
@@ -1670,7 +1673,7 @@
         return true;
 
     // we not need get instance map, base map provide all info
-    if(MapManager::Instance().GetBaseMap(GetMapId())->Instanceable())
+    if(MapManager::Instance().GetBaseMap(GetMapId(), GetInstanceMode())->Instanceable())
         return false;
 
     float rx,ry,rz;
@@ -1738,6 +1741,15 @@
     return true;
 }
 
+uint32 Creature::GetWaypointPath()
+{
+    CreatureDataAddon const *info = GetCreatureAddon();
+    if(!info)
+        return 0;
+    
+    return info->path_id;
+}
+
 /// Send a message to LocalDefense channel for players oposition team in the zone
 void Creature::SendZoneUnderAttackMessage(Player* attacker)
 {
Index: src/game/ObjectMgr.cpp
===================================================================
--- src/game/ObjectMgr.cpp	(revision 5236)
+++ src/game/ObjectMgr.cpp	(working copy)
@@ -37,6 +37,7 @@
 #include "GameEvent.h"
 #include "Spell.h"
 #include "Chat.h"
+#include "WaypointMovementGenerator.h"
 
 INSTANTIATE_SINGLETON_1(ObjectMgr);
 
@@ -44,6 +45,7 @@
 ScriptMapMap sQuestStartScripts;
 ScriptMapMap sSpellScripts;
 ScriptMapMap sButtonScripts;
+ScriptMapMap sWaypointScripts;
 ScriptMapMap sEventScripts;
 
 ObjectMgr::ObjectMgr()
@@ -85,6 +87,8 @@
 
     mAreaTriggers.clear();
 
+    mMapInfo.clear();
+
     for(PetLevelInfoMap::iterator i = petInfo.begin( ); i != petInfo.end( ); ++ i )
     {
         delete[] i->second;
@@ -722,8 +726,8 @@
     QueryResult *result = WorldDatabase.Query("SELECT `creature`.`guid`,`id`,`map`,`modelid`,"
     //    4             5            6            7            8             9               10          11
         "`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,"
-    //   12                 13                 14                 15                  16          17        18           19             20
-        "`spawn_position_x`,`spawn_position_y`,`spawn_position_z`,`spawn_orientation`,`curhealth`,`curmana`,`DeathState`,`MovementType`,`event` "
+    //   12                 13                 14                 15                  16          17        18           19             20             21
+        "`spawn_position_x`,`spawn_position_y`,`spawn_position_z`,`spawn_orientation`,`curhealth`,`curmana`,`DeathState`,`MovementType`,`instancemode`,`event` "
         "FROM `creature` LEFT OUTER JOIN `game_event_creature` ON `creature`.`guid`=`game_event_creature`.`guid`");
 
     if(!result)
@@ -767,7 +771,8 @@
         data.curmana        = fields[17].GetUInt32();
         data.deathState     = fields[18].GetUInt8();
         data.movementType   = fields[19].GetUInt8();
-        int16 gameEvent     = fields[20].GetInt16();
+        data.instanceMode   = fields[20].GetUInt8();
+        int16 gameEvent     = fields[21].GetInt16();
 
         if (gameEvent==0)                                   // if not this is to be managed by GameEvent System
             AddCreatureToGrid(guid, &data);
@@ -799,14 +804,21 @@
     cell_guids.creatures.erase(guid);
 }
 
+void ObjectMgr::LoadWaypointData()
+{
+    sWaypointStore.Load();
+
+    sLog.outString(">> Loaded %u waypoints\n\n", sWaypointStore.GetRecordsCount() );
+}
+
 void ObjectMgr::LoadGameobjects()
 {
     uint32 count = 0;
 
     //                                                         0      1    2     3            4            5            6
     QueryResult *result = WorldDatabase.Query("SELECT `gameobject`.`guid`,`id`,`map`,`position_x`,`position_y`,`position_z`,`orientation`,"
-    //   7           8           9           10          11               12             13        14
-        "`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`,`event` "
+    //   7           8           9           10          11               12             13        14             15
+        "`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`,`instancemode`,`event` "
         "FROM `gameobject` LEFT OUTER JOIN `game_event_gameobject` ON `gameobject`.`guid`=`game_event_gameobject`.`guid`");
 
     if(!result)
@@ -844,7 +856,8 @@
         data.spawntimesecs  = fields[11].GetInt32();
         data.animprogress   = fields[12].GetUInt32();
         data.go_state       = fields[13].GetUInt32();
-        int16 gameEvent     = fields[14].GetInt16();
+        data.instanceMode   = fields[14].GetUInt8();
+        int16 gameEvent     = fields[15].GetInt16();
 
         if (gameEvent==0)                                   // if not this is to be managed by GameEvent System
             AddGameobjectToGrid(guid, &data);
@@ -3188,6 +3201,18 @@
     }
 }
 
+void ObjectMgr::LoadWaypointScripts()
+{
+    objmgr.LoadScripts(sWaypointScripts, "waypoint_scripts");
+
+    for(ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr)
+    {
+        QueryResult *query = WorldDatabase.PQuery("SELECT * FROM `waypoint_scripts` WHERE `event_id` = %u", itr->first);
+        if(!query || !query->GetRowCount())
+            sLog.outErrorDb("There is no waypoint which links to the waypoint script %u", itr->first);
+    }
+}
+
 void ObjectMgr::LoadItemTexts()
 {
     QueryResult *result = CharacterDatabase.PQuery("SELECT `id`, `text` FROM `item_text`");
@@ -3969,8 +3994,8 @@
 
     uint32 count = 0;
 
-    //                                            0    1                2               3            4                   5                   6                    7
-    QueryResult *result = WorldDatabase.Query("SELECT `id`,`required_level`,`required_item`,`target_map`,`target_position_x`,`target_position_y`,`target_position_z`,`target_orientation` FROM `areatrigger_teleport`");
+    //                                                0    1                2               3             4            5               6                     7                      8            9                   10                  11                  12
+    QueryResult *result = WorldDatabase.Query("SELECT `id`,`required_level`,`required_item`,`second_item`,`heroic_key`,`heroic_second`,`required_quest_done`,`required_failed_text`,`target_map`,`target_position_x`,`target_position_y`,`target_position_z`,`target_orientation` FROM `areatrigger_teleport`");
     if( !result )
     {
 
@@ -3999,11 +4024,16 @@
 
         at.requiredLevel      = fields[1].GetUInt8();
         at.requiredItem       = fields[2].GetUInt32();
-        at.target_mapId       = fields[3].GetUInt32();
-        at.target_X           = fields[4].GetFloat();
-        at.target_Y           = fields[5].GetFloat();
-        at.target_Z           = fields[6].GetFloat();
-        at.target_Orientation = fields[7].GetFloat();
+        at.secondItem         = fields[3].GetUInt32();
+        at.heroicKey          = fields[4].GetUInt32();
+        at.heroicSecond       = fields[5].GetUInt32();
+        at.requiredQuest      = fields[6].GetUInt32();
+        at.requiredFailedText = fields[7].GetCppString();
+        at.target_mapId       = fields[8].GetUInt32();
+        at.target_X           = fields[9].GetFloat();
+        at.target_Y           = fields[10].GetFloat();
+        at.target_Z           = fields[11].GetFloat();
+        at.target_Orientation = fields[12].GetFloat();
 
         AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
         if(!atEntry)
@@ -4022,6 +4052,45 @@
             }
         }
 
+        if(at.secondItem)
+        {
+            ItemPrototype const *pProto = objmgr.GetItemPrototype(at.secondItem);
+            if(!pProto)
+            {
+                sLog.outError("Second item %u not exist for trigger %u, remove key requirement.", at.secondItem, Trigger_ID);
+                at.secondItem = 0;
+            }
+        }
+
+        if(at.heroicKey)
+        {
+            ItemPrototype const *pProto = objmgr.GetItemPrototype(at.heroicKey);
+            if(!pProto)
+            {
+                sLog.outError("Heroic key item %u not exist for trigger %u, remove key requirement.", at.heroicKey, Trigger_ID);
+                at.heroicKey = 0;
+            }
+        }
+
+        if(at.heroicSecond)
+        {
+            ItemPrototype const *pProto = objmgr.GetItemPrototype(at.heroicSecond);
+            if(!pProto)
+            {
+                sLog.outError("Heroic second key item %u not exist for trigger %u, remove key requirement.", at.heroicSecond, Trigger_ID);
+                at.heroicSecond = 0;
+            }
+        }
+
+        if(at.requiredQuest)
+        {
+            if(!mQuestTemplates[at.requiredQuest])
+            {
+                sLog.outErrorDb("Required Quest %u not exist for trigger %u, remove quest done requirement.",at.requiredQuest,Trigger_ID);
+                at.requiredQuest = 0;
+            }
+        }
+
         MapEntry const* mapEntry = sMapStore.LookupEntry(at.target_mapId);
         if(!mapEntry)
         {
@@ -4302,6 +4371,20 @@
     sLog.outString( ">> Loaded %u BaseXP definitions", count );
 }
 
+AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
+{
+    for (AreaTriggerMap::const_iterator itr = mAreaTriggers.begin(); itr != mAreaTriggers.end(); itr++)
+    {
+        if(itr->second.target_mapId == 0 || itr->second.target_mapId == 1 || itr->second.target_mapId == 530)
+        {
+            AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(itr->first);
+            if(atEntry && atEntry->mapid == Map)
+                return &itr->second;
+        }
+    }
+    return NULL;
+}
+
 uint32 ObjectMgr::GetBaseXP(uint32 level)
 {
     return mBaseXPTable[level] ? mBaseXPTable[level] : 0;
@@ -4503,6 +4586,65 @@
     sLog.outString(">> Loaded %u creature award reputation definitions", count);
 }
 
+void ObjectMgr::LoadMapInformation()
+{
+    uint32 infocount = 0;
+
+    mMapInfo.clear();
+    QueryResult* result = WorldDatabase.PQuery("SELECT `instance_template`.`map`,`instance_template`.`maxPlayers` FROM `instance_template` WHERE `map` > '1';");
+
+    if( !result )
+    {
+
+        barGoLink bar( 1 );
+
+        bar.step();
+
+        sLog.outString( "" );
+        sLog.outString( ">> Loaded %u Instance information definitions", infocount );
+        return;
+    }
+
+    barGoLink bar( result->GetRowCount() );
+
+    do
+    {
+        infocount++;
+
+        bar.step();
+
+        MapInfo mapinfo;
+        Field* fields = result->Fetch();
+        const MapEntry* entry = sMapStore.LookupEntry(fields[0].GetUInt32());
+
+        mapinfo.i_mapId = fields[0].GetUInt32();
+        mapinfo.maxPlayers = fields[1].GetUInt32();
+        mapinfo.map_type = entry->map_type;
+        if(entry->resetTimeHeroic && !(entry->resetTimeRaid))
+        {
+            mapinfo.supportMode = MAPDIFFICULTY_HEROIC_SUPPORTED;
+            mapinfo.ResetDelayTime = entry->resetTimeHeroic * (sWorld.getRate(RATE_INSTANCE_RESET_TIME));
+        }
+        else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
+        {
+            mapinfo.supportMode = MAPDIFFICULTY_NORMAL;
+            mapinfo.ResetDelayTime = entry->resetTimeRaid * (sWorld.getRate(RATE_INSTANCE_RESET_TIME));
+        }
+        else
+        {
+            mapinfo.supportMode = MAPDIFFICULTY_NORMAL;
+            mapinfo.ResetDelayTime = 3600 * (sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR)) * (sWorld.getRate(RATE_INSTANCE_RESET_TIME));
+        }
+        mMapInfo[fields[0].GetUInt32()] = mapinfo;
+
+    }while( result->NextRow());
+    delete result;
+
+    sLog.outString( "" );
+    sLog.outString( ">> Loaded %u Instance information definitions", infocount );
+
+}
+
 void ObjectMgr::CleanupInstances()
 {
     // this routine cleans up old instances from all the tables before server start
@@ -4567,6 +4709,18 @@
         delete result;
     }
 
+    // non saving character instance
+    result = CharacterDatabase.PQuery("SELECT `instance` FROM `character`");
+    if( result )
+    {
+        do
+        {
+            Field *fields = result->Fetch();
+            InstanceSet.insert(fields[0].GetUInt32());
+        }
+        while (result->NextRow());
+        delete result;
+    }
     // now remove all valid instances from instance list (it will become list of instances to delete)
     // instances considered valid:
     //   1) reset time > current time
@@ -4587,6 +4741,19 @@
         delete result;
     }
 
+    result = CharacterDatabase.PQuery("SELECT `character`.`instance` FROM `character` WHERE `character`.`instance` NOT IN (SELECT `instance`.`id` FROM `instance`)");
+    if( result )
+    {
+        do
+        {
+            Field *fields = result->Fetch();
+            if (InstanceSet.find(fields[0].GetUInt32()) != InstanceSet.end())
+                InstanceSet.erase(fields[0].GetUInt32());
+        }
+        while (result->NextRow());
+        delete result;
+    }
+
     delcount = InstanceSet.size();
 
     barGoLink bar( delcount + 1 );
@@ -4599,6 +4766,7 @@
         WorldDatabase.PExecute("DELETE FROM `gameobject_respawn` WHERE `instance