All pastes #994543 Raw Edit

Miscellany

public text v1 · immutable
#994543 ·published 2008-04-23 14:00 UTC
rendered paste body
Index: src/game/AggressorAI.cpp
===================================================================
--- src/game/AggressorAI.cpp	(revision 5687)
+++ src/game/AggressorAI.cpp	(working copy)
@@ -111,7 +111,6 @@
     i_creature.DeleteThreatList();
     i_victimGuid = 0;
     i_creature.CombatStop();
-
 }
 
 void
Index: src/game/Chat.cpp
===================================================================
--- src/game/Chat.cpp	(revision 5687)
+++ src/game/Chat.cpp	(working copy)
@@ -116,9 +116,13 @@
     static ChatCommand wpCommandTable[] =
     {
         { "show",           SEC_GAMEMASTER,     &ChatHandler::HandleWpShowCommand,              "", NULL },
-        { "add",            SEC_GAMEMASTER,     &ChatHandler::HandleWpAddCommand,               "", NULL },
-        { "modify",         SEC_GAMEMASTER,     &ChatHandler::HandleWpModifyCommand,            "", NULL },
-        { NULL,             0,                  NULL,                                           "", NULL }
+        { "addwp",          SEC_GAMEMASTER,     &ChatHandler::HandleWpAddCommand,               "", NULL },
+		{ "load",			SEC_GAMEMASTER,     &ChatHandler::HandleWpLoadPathCommand,          "", NULL },
+		{ "modify",         SEC_GAMEMASTER,     &ChatHandler::HandleWpModifyCommand,            "", NULL },
+		{ "event",			SEC_GAMEMASTER,     &ChatHandler::HandleWpEventCommand,				"", NULL },
+		{ "unload",			SEC_GAMEMASTER,     &ChatHandler::HandleWpUnLoadPathCommand,		"", NULL },
+		
+		{ NULL,             0,                  NULL,                                           "", NULL }
     };
 
     static ChatCommand debugCommandTable[] =
@@ -162,6 +166,7 @@
         { "all_scripts",    SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllScriptsCommand,    "", NULL },
         { "all_spell",      SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllSpellCommand,      "", NULL },
 
+        { "waypoint_scripts",			 SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTavernCommand,       "", NULL },
         { "areatrigger_tavern",          SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTavernCommand,       "", NULL },
         { "areatrigger_teleport",        SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTeleportCommand,     "", NULL },
         { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestAreaTriggersCommand,       "", NULL },
@@ -234,7 +239,16 @@
         { NULL,             0,                  NULL,                                           "", NULL }
     };
 
-    static ChatCommand resetCommandTable[] =
+    static ChatCommand formationCommandTable[] =
+	{
+		{ "setleader",       SEC_MODERATOR,		&ChatHandler::HandleCreateFormationCommand,		"", NULL },
+		{ "dismiss",      SEC_MODERATOR,		&ChatHandler::HandleDismissFormationCommand,	"", NULL },
+		{ "followangle",     SEC_MODERATOR,		&ChatHandler::HandleAngleFormationCommand,		"", NULL },
+		{ "followdist",		 SEC_MODERATOR,		&ChatHandler::HandleDistFormationCommand,		"", NULL },
+		{ NULL,             0,                  NULL,                                           "", NULL }
+	};
+	
+	static ChatCommand resetCommandTable[] =
     {
         { "honor",          SEC_ADMINISTRATOR,  &ChatHandler::HandleResetHonorCommand,          "", NULL },
         { "level",          SEC_ADMINISTRATOR,  &ChatHandler::HandleResetLevelCommand,          "", NULL },
@@ -366,8 +380,9 @@
         { "password",       SEC_PLAYER,         &ChatHandler::HandlePasswordCommand,            "", NULL },
         { "lockaccount",    SEC_PLAYER,         &ChatHandler::HandleLockAccountCommand,         "", NULL },
         { "respawn",        SEC_ADMINISTRATOR,  &ChatHandler::HandleRespawnCommand,             "", NULL },
-        { "wp",             SEC_GAMEMASTER,     NULL,                                           "", wpCommandTable },
-        { "flymode",        SEC_ADMINISTRATOR,  &ChatHandler::HandleFlyModeCommand,             "", NULL },
+        { "path",           SEC_GAMEMASTER,     NULL,                                           "", wpCommandTable },
+		{ "formation",      SEC_ADMINISTRATOR,  NULL,											"", formationCommandTable },
+		{ "flymode",        SEC_ADMINISTRATOR,  &ChatHandler::HandleFlyModeCommand,             "", NULL },
         { "sendmail",       SEC_MODERATOR,      &ChatHandler::HandleSendMailCommand,            "", NULL },
         { "rename",         SEC_GAMEMASTER,     &ChatHandler::HandleRenameCommand,              "", NULL },
         { "nametele",       SEC_MODERATOR,      &ChatHandler::HandleNameTeleCommand,            "", NULL },
@@ -383,8 +398,14 @@
         { "cast",           SEC_ADMINISTRATOR,  &ChatHandler::HandleCastCommand,                "", NULL },
         { "castback",       SEC_ADMINISTRATOR,  &ChatHandler::HandleCastBackCommand,            "", NULL },
         { "casttarget",     SEC_ADMINISTRATOR,  &ChatHandler::HandleCastTargetCommand,          "", NULL },
+
+		{ "loadpath", SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllPaths,				"", NULL },
+
         { "cometome",       SEC_ADMINISTRATOR,  &ChatHandler::HandleComeToMeCommand,            "", NULL },
 
+
+
+
         //! Development Commands
         { "setvalue",       SEC_ADMINISTRATOR,  &ChatHandler::HandleSetValue,                   "", NULL },
         { "getvalue",       SEC_ADMINISTRATOR,  &ChatHandler::HandleGetValue,                   "", NULL },
Index: src/game/Chat.h
===================================================================
--- src/game/Chat.h	(revision 5687)
+++ src/game/Chat.h	(working copy)
@@ -145,7 +145,8 @@
         bool HandleReloadAllScriptsCommand(const char* args);
         bool HandleReloadAllSpellCommand(const char* args);
 
-        bool HandleReloadAreaTriggerTavernCommand(const char* args);
+        bool HandleReloadWaypointScriptsCommand(const char* arg);
+		bool HandleReloadAreaTriggerTavernCommand(const char* args);
         bool HandleReloadAreaTriggerTeleportCommand(const char* args);
         bool HandleReloadEventScriptsCommand(const char* args);
         bool HandleReloadCommandCommand(const char* args);
@@ -179,10 +180,13 @@
         bool HandleReloadSpellScriptTargetCommand(const char* args);
         bool HandleReloadSpellScriptsCommand(const char* args);
         bool HandleReloadSpellTeleportCommand(const char* args);
+		bool HandleReloadAllPaths(const char* args);
+        
+		bool HandleAddHonorCommand(const char* args);
+
         bool HandleReloadSpellThreatsCommand(const char* args);
 
-        bool HandleAddHonorCommand(const char* args);
-        bool HandleHonorAddKillCommand(const char* args);
+		bool HandleHonorAddKillCommand(const char* args);
         bool HandleHonorFlushKillsCommand(const char* args);
         bool HandleUpdateHonorFieldsCommand(const char* args);
 
@@ -316,8 +320,15 @@
         bool HandleLockAccountCommand(const char* args);
         bool HandleRespawnCommand(const char* args);
         bool HandleWpAddCommand(const char* args);
-        bool HandleWpModifyCommand(const char* args);
-        bool HandleWpShowCommand(const char* args);
+        bool HandleWpLoadPathCommand(const char* args);
+		bool HandleWpUnLoadPathCommand(const char* args);
+		bool HandleWpModifyCommand(const char* args);
+        bool HandleWpEventCommand(const char* args);
+		bool HandleCreateFormationCommand(const char* args);
+		bool ChatHandler::HandleDismissFormationCommand(const char* args);
+		bool ChatHandler::HandleDistFormationCommand(const char* args);
+		bool ChatHandler::HandleAngleFormationCommand(const char* args);
+		bool HandleWpShowCommand(const char* args);
         bool HandleFlyModeCommand(const char* args);
         bool HandleSendOpcodeCommand(const char* args);
         bool HandleSellErrorCommand(const char* args);
Index: src/game/Creature.cpp
===================================================================
--- src/game/Creature.cpp	(revision 5687)
+++ src/game/Creature.cpp	(working copy)
@@ -61,6 +61,7 @@
     m_CreatureSpellCooldowns.clear();
     m_CreatureCategoryCooldowns.clear();
     m_GlobalCooldown = 0;
+	m_waypointID = 0;
 }
 
 Creature::~Creature()
@@ -150,9 +151,13 @@
     loot.clear();
     m_respawnTime = time(NULL) + m_respawnDelay;
 
-    float x,y,z;
-    GetRespawnCoord(x, y, z);
-    MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation(this,x,y,z,GetOrientation());
+    
+	if(!this->GetCurrentWaypointID())
+	{
+		float x,y,z;
+		GetRespawnCoord(x, y, z);
+		MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation(this,x,y,z,GetOrientation());
+	}
 }
 
 void Creature::Update(uint32 diff)
@@ -201,12 +206,21 @@
                 clearUnitState(UNIT_STAT_ALL_STATE);
                 i_motionMaster.Clear();
                 LoadCreaturesAddon(true);
-
+				
                 //Call AI respawn virtual function
                 i_AI->JustRespawned();
 
                 MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
-            }
+				
+				if(IsFollower())
+					{
+					uint32 guid = this->GetCreatureFormation()->leader;
+					uint32 entry = objmgr.GetCreatureData(guid)->id;
+					Creature* Leader = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, entry, HIGHGUID_UNIT), (Creature*)NULL);
+					if(Leader)
+						Leader->SetLinkedtoFormation(false);
+					}
+			}
             break;
         }
         case CORPSE:
@@ -1116,8 +1130,9 @@
         return false;
     }
 
-    Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
+	Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
 
+
     m_DBTableGuid = guidlow;
 
     SetUInt32Value(OBJECT_FIELD_ENTRY, Entry);
@@ -1249,7 +1264,8 @@
 
     m_DBTableGuid = stored_guid;
     LoadCreaturesAddon();
-    if(GetCreatureInfo()->rank > 0)
+	LoadCreatureFormation();
+	if(GetCreatureInfo()->rank > 0)
         this->m_corpseDelay *= 3;                           //if creature is elite, then remove corpse later
 
     m_respawnradius = data->spawndist;
@@ -1283,8 +1299,8 @@
 
     // checked at creature_template loading
     m_defaultMovementType = MovementGeneratorType(data->movementType);
-
-    AIM_Initialize();
+	
+	AIM_Initialize();
     return true;
 }
 
@@ -1713,7 +1729,10 @@
     if (cainfo->emote != 0)
         SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote);
 
-    if(cainfo->auras)
+    if (cainfo->path_id != 0)
+		m_path_id = cainfo->path_id;
+	
+	if(cainfo->auras)
     {
         for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura)
         {
@@ -1806,3 +1825,20 @@
             break;
     return i < CREATURE_MAX_SPELLS;                         //broke before end of iteration of known spells
 }
+
+
+CreatureFormation const* Creature::GetCreatureFormation() const
+{
+	CreatureFormation const* form = ObjectMgr::GetFormation(m_DBTableGuid);
+        return form;
+}
+
+//Load Formations
+bool Creature::LoadCreatureFormation()
+{
+CreatureFormation const *info = GetCreatureFormation();
+if(!info)
+        return false;
+	m_formation = true;
+		return m_formation;
+}
\ No newline at end of file
Index: src/game/Creature.h
===================================================================
--- src/game/Creature.h	(revision 5687)
+++ src/game/Creature.h	(working copy)
@@ -257,7 +257,8 @@
 struct CreatureDataAddon
 {
     uint32 guidOrEntry;
-    uint32 mount;
+    uint32 path_id;
+	uint32 mount;
     uint32 bytes0;
     uint32 bytes1;
     uint32 bytes2;
@@ -281,6 +282,14 @@
     INHAVIT_ANYWHERE = INHAVIT_GROUND | INHAVIT_WATER
 };
 
+struct CreatureFormation
+{
+uint32 follower;
+uint32 leader;
+float offset_angle;
+float offset_dist;
+};
+
 // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
 #if defined( __GNUC__ )
 #pragma pack()
@@ -303,7 +312,12 @@
 
     public:
 
-        explicit Creature( WorldObject *instantiator );
+        bool IsFollower(){return m_formation;}
+		bool LoadCreatureFormation();
+		
+		CreatureFormation const* GetCreatureFormation() const;
+		
+		explicit Creature( WorldObject *instantiator );
         virtual ~Creature();
 
         void AddToWorld();
@@ -320,7 +334,11 @@
 
         void Update( uint32 time );                         // overwrited Unit::Update
         void GetRespawnCoord(float &x, float &y, float &z) const { x = respawn_cord[0]; y = respawn_cord[1]; z = respawn_cord[2]; }
-        void GetRespawnDist(float &d) const { d = m_respawnradius; }
+        
+		void SetCoordsBeforeBattle(float x, float y, float z) { last_cord[0] = x; last_cord[1] = y; last_cord[2] = z; }
+        void GetCoordsBeforeBattle(float &x, float &y, float &z) const { x = last_cord[0]; y = last_cord[1]; z = last_cord[2]; }
+		
+		void GetRespawnDist(float &d) const { d = m_respawnradius; }
         uint32 GetEquipmentId() const { return m_equipmentId; }
 
         bool isPet() const { return m_isPet; }
@@ -375,9 +393,11 @@
         bool HasSpellCooldown(uint32 spell_id) const;
         bool HasCategoryCooldown(uint32 spell_id) const;
 
-        bool HasSpell(uint32 spellID) const;
-
-        bool UpdateStats(Stats stat);
+		bool HasSpell(uint32 spellID) const;
+		uint32 GetCurrentWaypointID(){return m_waypointID;}
+		void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
+		
+		bool UpdateStats(Stats stat);
         bool UpdateAllStats();
         void UpdateResistances(uint32 school);
         void UpdateArmor();
@@ -520,8 +540,17 @@
             else
                 return m_charmInfo->GetCharmSpell(pos)->spellId;
         }
-
-    protected:
+		
+		bool isLinkedtoFormation(){return m_link;}
+		void SetLinkedtoFormation(bool link) {m_link = link;}
+	
+		uint32 Creature::GetWaypointPath(){return m_path_id;}
+		void LoadPath(uint32 pathid) { m_path_id = pathid; }
+		
+		bool IsStoppedByEvent(){return m_wpevent;}
+		void SetStoppedByEvent(bool wpevent) {m_wpevent = wpevent;}
+		
+	protected:
         // vendor items
         typedef std::vector<CreatureItem> CreatureItems;
         CreatureItems m_vendor_items;
@@ -552,8 +581,9 @@
         uint32 m_NPCTextId;                                 // cached value
 
         float respawn_cord[3];
-
-        uint8 m_emoteState;
+		float last_cord[3];
+        
+		uint8 m_emoteState;
         bool m_isPet;                                       // set only in Pet::Pet
         bool m_isTotem;                                     // set only in Totem::Totem
         void RegenerateMana();
@@ -568,7 +598,12 @@
         bool m_regenHealth;
         bool m_AI_locked;
         bool m_isDeadByDefault;
-    private:
+		uint32 m_waypointID;
+		bool m_formation;
+		bool m_link;
+		bool m_wpevent;
+		uint32 m_path_id;
+	private:
         GridReference<Creature> m_gridRef;
 };
 #endif
Index: src/game/CreatureAI.h
===================================================================
--- src/game/CreatureAI.h	(revision 5687)
+++ src/game/CreatureAI.h	(working copy)
@@ -79,11 +79,15 @@
         // Called when the creature is attacked
         virtual void AttackedBy(Unit * /*attacker*/) {}
 
-        // Called when creature is spawned or respawned (for reseting variables)
+		// Called when creature reach any waypoint
+		virtual void MovementInform(uint32) {}
+
+		// Called when creature is spawned or respawned (for reseting variables)
         virtual void JustRespawned() {}
+		
+		// Called at waypoint reached or point movement finished
+        virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
 
-        // Called at waypoint reached or point movement finished
-        virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
 };
 
 struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
Index: src/game/GameEvent.cpp
===================================================================
--- src/game/GameEvent.cpp	(revision 5687)
+++ src/game/GameEvent.cpp	(working copy)
@@ -146,7 +146,7 @@
 
             if(max_event_id + event_id >= mGameEventCreatureGuids.size())
             {
-                sLog.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
+                sLog.outErrorDb("`creature_game_event` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
                 continue;
             }
 
@@ -160,7 +160,52 @@
         delete result;
     }
 
-    mGameEventGameobjectGuids.resize((max_event_id * 2) + 1);
+	///////////////////////////////wp event
+    mWpEvent.resize((max_event_id * 2) + 1);
+    //                                   1              2
+    result = WorldDatabase.Query("SELECT creature.guid, waypoint_event.event "
+        "FROM creature JOIN waypoint_event ON creature.guid = waypoint_event.guid");
+
+    count = 0;
+    if( !result )
+    {
+        barGoLink bar2(1);
+        bar2.step();
+
+        sLog.outString();
+        sLog.outString(">> Loaded %u creatures in waypoint events", count );
+    }
+    else
+    {
+
+        barGoLink bar2( result->GetRowCount() );
+        do
+        {
+            Field *fields = result->Fetch();
+
+            bar2.step();
+
+            uint32 guid    = fields[0].GetUInt32();
+            int16 event_id = fields[1].GetInt16();
+
+            if(max_event_id + event_id >= mWpEvent.size())
+            {
+                sLog.outErrorDb("`waypoint_event` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
+                continue;
+            }
+
+            ++count;
+            GuidList& crelist = mWpEvent[max_event_id + event_id];
+            crelist.push_back(guid);
+
+        } while( result->NextRow() );
+        sLog.outString();
+        sLog.outString( ">> Loaded %u creatures in waypoint events", count );
+        delete result;
+    }
+////////////////////////////	
+	
+	mGameEventGameobjectGuids.resize((max_event_id * 2) + 1);
     //                                   1                2
     result = WorldDatabase.Query("SELECT gameobject.guid, game_event_gameobject.event "
         "FROM gameobject JOIN game_event_gameobject ON gameobject.guid=game_event_gameobject.guid");
@@ -361,6 +406,9 @@
     ChangeEquipOrModel(event_id, false);
     // Remove quests that are events only to non event npc
     UpdateEventQuests(event_id, false);
+	//Make creatures stop moving
+	WaypointEvent(event_id, false);
+
 }
 
 void GameEvent::ApplyNewEvent(uint16 event_id)
@@ -386,6 +434,8 @@
     ChangeEquipOrModel(event_id, true);
     // Add quests that are events only to non event npc
     UpdateEventQuests(event_id, true);
+	//Make creatures move
+	WaypointEvent(event_id, true);
 }
 
 void GameEvent::GameEventSpawn(int16 event_id)
@@ -605,6 +655,43 @@
     }
 }
 
+void GameEvent::WaypointEvent(uint16 event_id, bool Activate)
+{
+ 
+	for (GuidList::iterator itr = mWpEvent[max_event_id + event_id].begin();itr != mWpEvent[max_event_id + event_id].end();++itr)
+    
+  {
+        
+		CreatureData const* data = objmgr.GetCreatureData(*itr);
+        if(!data)
+            continue;
+	  
+		Creature* pCreature;
+		pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT), (Creature*)NULL);
+        if (pCreature)
+        {
+            if (Activate)
+            {
+				WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, pCreature->GetGUIDLow());
+				
+				pCreature->SetStoppedByEvent(false);
+				pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+				pCreature->GetMotionMaster()->Initialize();
+				pCreature->Say("Event Started",0,0);
+			}
+            else
+            {
+				WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, pCreature->GetGUIDLow());
+				
+				pCreature->SetStoppedByEvent(true);
+				pCreature->SetDefaultMovementType(IDLE_MOTION_TYPE);
+				pCreature->GetMotionMaster()->Initialize();
+				pCreature->Say("Event Stopped",0,0);
+			}
+        }
+    }
+}
+
 GameEvent::GameEvent()
 {
     isSystemInit = false;
Index: src/game/GameEvent.h
===================================================================
--- src/game/GameEvent.h	(revision 5687)
+++ src/game/GameEvent.h	(working copy)
@@ -64,7 +64,8 @@
         void ChangeEquipOrModel(int16 event_id, bool activate);
         void UpdateEventQuests(uint16 event_id, bool Activate);
         uint32 NextCheck(uint16 entry);
-    protected:
+		void WaypointEvent(uint16 event_id, bool Activate);
+	protected:
         typedef std::vector<GameEventData> GameEventDataMap;
         typedef std::list<uint32> GuidList;
         typedef std::vector<GuidList> GameEventGuidMap;
@@ -79,7 +80,8 @@
         GameEventGuidMap  mGameEventCreatureGuids;
         GameEventGuidMap  mGameEventGameobjectGuids;
         GameEventDataMap  mGameEvent;
-        ActiveEvents m_ActiveEvents;
+        GameEventGuidMap  mWpEvent;
+		ActiveEvents m_ActiveEvents;
         bool isSystemInit;
         uint16 max_event_id;
 };
Index: src/game/HomeMovementGenerator.cpp
===================================================================
--- src/game/HomeMovementGenerator.cpp	(revision 5687)
+++ src/game/HomeMovementGenerator.cpp	(working copy)
@@ -47,10 +47,14 @@
         return;
 
     float x, y, z;
-    owner.GetRespawnCoord(x, y, z);
+	
+	if(!owner.GetCurrentWaypointID())
+		owner.GetRespawnCoord(x, y, z);
+	else
+		owner.GetCoordsBeforeBattle(x, y, z);
+    
+	CreatureTraveller traveller(owner);
 
-    CreatureTraveller traveller(owner);
-
     uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
     modifyTravelTime(travel_time);
     owner.clearUnitState(UNIT_STAT_ALL_STATE);
Index: src/game/Level2.cpp
===================================================================
--- src/game/Level2.cpp	(revision 5687)
+++ src/game/Level2.cpp	(working copy)
@@ -1049,7 +1049,7 @@
 
     uint32 point;
 
-    QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
+    QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",lowguid);
     if( result )
     {
         point = (*result)[0].GetUInt32()+1;
@@ -1061,7 +1061,7 @@
 
     Player* player = m_session->GetPlayer();
 
-    WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z,waittime) VALUES ('%u','%u','%f', '%f', '%f','%u')",
+    WorldDatabase.PExecuteLog("INSERT INTO waypoint_data(id,point,position_x,position_y,position_z,delay) VALUES ('%u','%u','%f', '%f', '%f','%u')",
         lowguid, point, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), wait);
 
     // update movement type
@@ -1203,7 +1203,7 @@
     if( doNotDelete == false )
     {
         //sLog.outError("DEBUG: doNotDelete == false");
-        WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id = '%u'",lowguid);
+        WorldDatabase.PExecuteLog("DELETE FROM waypoint_data WHERE id = '%u'",lowguid);
     }
     WorldDatabase.CommitTransaction();
     if(pCreature)
@@ -1828,185 +1828,606 @@
     return true;
 }
 
-/**
- * Add a waypoint to a creature.
- *
- * The user can either select an npc or provide its GUID.
- *
- * The user can even select a visual waypoint - then the new waypoint
- * is placed *after* the selected one - this makes insertion of new
- * waypoints possible.
- *
- * eg:
- * .wp add 12345
- * -> adds a waypoint to the npc with the GUID 12345
- *
- * .wp add
- * -> adds a waypoint to the currently selected creature
- *
- *
- * @param args if the user did not provide a GUID, it is NULL
- *
- * @return true - command did succeed, false - something went wrong
- */
+/////WAYPOINT COMMANDS
+
 bool ChatHandler::HandleWpAddCommand(const char* args)
 {
     sLog.outDebug("DEBUG: HandleWpAddCommand");
 
     // optional
-    char* guid_str = NULL;
+    char* path_number = NULL;
+	uint32 pathid = 0;
+    
+    if(*args)
+		path_number = strtok((char*)args, " ");
+	
+    uint32 point = 0;
+    Creature* target = getSelectedCreature();
+	
+	if (!path_number)
+		{
+		if(target)
+			pathid = target->GetWaypointPath();
+				else	
+				{
+					QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(id) FROM waypoint_data");
+					uint32 maxpathid = result->Fetch()->GetInt32(); 
+					pathid = maxpathid+1;
+					sLog.outDebug("DEBUG: HandleWpAddCommand - New path started.");
+					SendSysMessage("New path started.");
+            
+				}
+		}
+		else
+			pathid = atoi(path_number);
+	
+	// path_id -> ID of the Path
+    // point   -> number of the waypoint (if not 0)
+	
+	if(!pathid)
+	{
+		sLog.outDebug("DEBUG: HandleWpAddCommand - Current creature haven't loaded path.");
+		SendSysMessage("Current creature haven't loaded path.");
+		return true;
+	}
+	
+	sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
 
-    if(*args)
+    QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",pathid);
+    if( result )
     {
-        guid_str = strtok((char*)args, " ");
+        point = (*result)[0].GetUInt32()+1;
+        delete result;
     }
+    else
+        point = 1;
 
-    uint32 lowguid = 0;
-    uint32 point = 0;
-    Unit* target = getSelectedCreature();
-    // Did player provide a GUID?
-    if (!guid_str)
-    {
-        sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
+	Player* player = m_session->GetPlayer();
 
-        // No GUID provided
-        // -> Player must have selected a creature
+    WorldDatabase.PExecuteLog("INSERT INTO waypoint_data (id,point,position_x,position_y,position_z) VALUES ('%u','%u','%f', '%f', '%f')",
+        pathid, point, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
 
-        if(!target)
+	Creature* wpCreature = new Creature(player);
+        if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), player->GetMapId(),
+            player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), VISUAL_WAYPOINT,0))
         {
-            SendSysMessage(LANG_SELECT_CREATURE);
-            return true;
+            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
+            delete wpCreature;
+            return false;
         }
-        if (target->GetEntry() == VISUAL_WAYPOINT )
-        {
-            sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
+        WorldDatabase.PExecute("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);
 
-            QueryResult *result =
-                WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
-                target->GetGUIDLow() );
-            if(!result)
-            {
-                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
-                // User selected a visual spawnpoint -> get the NPC
-                // Select NPC GUID
-                // Since we compare float values, we have to deal with
-                // some difficulties.
-                // Here we search for all waypoints that only differ in one from 1 thousand
-                // (0.001) - There is no other way to compare C++ floats with mySQL floats
-                // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
-                const char* maxDIFF = "0.01";
-                result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
-                    target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
-                if(!result)
-                {
-                    PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
-                    return true;
-                }
-            }
-            do
-            {
-                Field *fields = result->Fetch();
-                lowguid = fields[0].GetUInt32();
-                point   = fields[1].GetUInt32();
-            }while( result->NextRow() );
-            delete result;
-        }
-        else
-        {
-            lowguid = target->GetGUIDLow();
-        }
+        wpCreature->SaveToDB();
+        // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
+        wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), player->GetInstanceId());
+        MapManager::Instance().GetMap(wpCreature->GetMapId(), wpCreature)->Add(wpCreature);
+	
+		if(target)
+		{
+				if(pathid = target->GetWaypointPath())
+				{
+					wpCreature->SetDisplayId(target->GetDisplayId());
+					wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+				}
+		}
+	
+		PSendSysMessage("PathID: %u: Waypoint %u created. ",pathid, point);
 
-    }
-    else
-    {
-        sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
+    return true;
+}                                                           // HandleWpAddCommand
 
-        // GUID provided
-        // Warn if player also selected a creature
-        // -> Creature selection is ignored <-
-        if(target)
-        {
-            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
-        }
-        lowguid = atoi((char*)guid_str);
-    }
-    // lowguid -> GUID of the NPC
-    // point   -> number of the waypoint (if not 0)
-    sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
+bool ChatHandler::HandleWpLoadPathCommand(const char *args)
+{
 
-    Creature* pCreature = NULL;
+	if(!*args)
+		return false;
+	
+	// optional
+    char* path_number = NULL;
 
-    /* impossible without entry
-    if(lowguid)
-        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
-    */
+	if(*args)
+    {
+        path_number = strtok((char*)args, " ");
+    }
 
-    // attempt check creature existence by DB data
-    if(!pCreature)
-    {
-        CreatureData const* data = objmgr.GetCreatureData(lowguid);
-        if(!data)
+uint32 pathid = 0;
+    uint32 guidlow = 0;
+    Creature* target = getSelectedCreature();
+    
+	// Did player provide a path_id?
+    if (!path_number)
+		sLog.outDebug("DEBUG: HandleWpLoadPathCommand - No path number provided");
+	
+    if(!target)
+		{
+            SendSysMessage(LANG_SELECT_CREATURE);
+            return true;
+        }
+	if(target->GetEntry() == 1)
         {
-            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+            SendSysMessage("You want to load path to a waypoint? Aren't you?");
             return true;
         }
-    }
+	
+	
+	pathid = atoi(path_number);
+	if(!pathid)
+	{
+	SendSysMessage("No vallid path number provided.");
+	return true;
+	}
+	
+	guidlow = target->GetGUIDLow();
+	
+	QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE guid = '%u'",guidlow);
+    
+	if( result )
+    {
+        WorldDatabase.PExecute("UPDATE creature_addon SET path_id = '%u' WHERE guid = '%u'", pathid, guidlow);
+		delete result;
+	}
+    else
+		WorldDatabase.PExecute("INSERT INTO creature_addon(guid,path_id) VALUES ('%u','%u')", guidlow, pathid);
+	
+	WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow);
+    
+	target->LoadPath(pathid);
+	
+	target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+    
+	target->GetMotionMaster()->Initialize();
+        
+	target->Say("Path loaded.",0,0);
+		
+	return true;   
+}
 
-    sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
+bool ChatHandler::HandleReloadAllPaths(const char* args)
+{
+if(!*args)
+	return false;
 
-    QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
-    if( result )
+uint32 id = atoi(args);
+	
+if(!id)
+	return false;
+
+PSendSysMessage("Loading Path: %u", id);
+	sWaypointStore.UpdatePath(id);
+		return true;
+}
+
+bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)
+{
+uint32 guidlow = 0;
+Creature* target = getSelectedCreature();
+
+if(!target)
+{
+	SendSysMessage("You must select target.");
+	return true;
+}
+
+if(target->GetCreatureAddon())
+{
+	if(target->GetCreatureAddon()->path_id != 0)
+	{
+		WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = %u", target->GetGUIDLow());
+		target->UpdateWaypointID(0);
+		WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow);
+		target->LoadPath(0);
+		target->SetDefaultMovementType(IDLE_MOTION_TYPE);
+		target->GetMotionMaster()->TargetedHome();
+		target->Say("Path unloaded.",0,0);
+		return true;
+	}
+	SendSysMessage("Target have no loaded path.");
+	return true;
+}
+SendSysMessage("Target have no loaded path.");
+return true;
+}
+
+bool ChatHandler::HandleWpEventCommand(const char* args)
+{
+if(!*args)
+     return false;
+
+	char* show_str = strtok((char*)args, " ");
+	
+	std::string show = show_str;
+    
+	// Check
+    if( (show != "add") && (show != "mod") && (show != "del") && (show != "listid")) return false;
+	
+	
+	if(show == "add")
+	{
+	uint32 id = 0;
+	char* arg_id = strtok(NULL, " ");	
+	
+	if(arg_id)
+		uint32 id = atoi(arg_id);
+	
+	if(id)
+	{
+		QueryResult *result = WorldDatabase.PQuery( "SELECT `id` FROM waypoint_scripts WHERE guid = %u", id);
+    
+		if( !result )
+		{
+        WorldDatabase.PExecute("INSERT INTO waypoint_scripts(guid)VALUES(%u)", id);
+		PSendSysMessage("Wp Event: New waypoint event added: %u", id);
+		}
+		else
+		{
+		PSendSysMessage("Wp Event: You have choosed an existing waypoint script guid: %u", id);
+		delete result;
+		}
+	}
+	else
+	{
+		QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(guid) FROM waypoint_scripts");
+		id = result->Fetch()->GetUInt32();
+		WorldDatabase.PExecute("INSERT INTO waypoint_scripts(guid)VALUES(%u)", id+1);
+		PSendSysMessage("Wp Event: New waypoint event added: %u", id+1);
+	}	
+	
+	return true;
+	}
+	
+	
+	if(show == "listid")
+	{
+	uint32 id;
+	char* arg_id = strtok(NULL, " ");
+	
+	if(!arg_id)
+	{
+	SendSysMessage("Wp Event: You must provide waypoint script id.");
+	return true;
+	}
+	
+	id = atoi(arg_id);
+	
+	uint32 a2, a3, a4, a5, a6;
+	float a8, a9, a10, a11;
+	char const* a7;
+	
+	QueryResult *result = WorldDatabase.PQuery( "SELECT `guid`, `delay`, `command`, `datalong`, `datalong2`, `datatext`, `x`, `y`, `z`, `o` FROM waypoint_scripts WHERE id = %u", id);
+	
+	if( !result )
+	{
+		PSendSysMessage("Wp Event: No waypoint scripts found on id: %u", id);
+		return true;
+	}
+	
+	Field *fields; 
+
+	do
+	{
+		fields = result->Fetch();
+		a2 = fields[0].GetUInt32();
+		a3 = fields[1].GetUInt32();
+		a4 = fields[2].GetUInt32();
+		a5 = fields[3].GetUInt32();
+		a6 = fields[4].GetUInt32();
+		a7 = fields[5].GetString();
+		a8 = fields[6].GetFloat();
+		a9 = fields[7].GetFloat();
+		a10 = fields[8].GetFloat();
+		a11 = fields[9].GetFloat();
+		
+		PSendSysMessage("id: %u, guid: %u, delay: %u, command: %u, datalong: %u, datalong2: %u, datatext: %s, posx: %f, posy: %f, posz: %f, orientation: %f", id, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+	}while(result->NextRow());
+	
+	delete result;
+	}
+	
+	if(show == "del")
+	{
+	
+	char* arg_id = strtok(NULL, " ");	
+	uint32 id = atoi(arg_id);
+	
+	QueryResult *result = WorldDatabase.PQuery( "SELECT `guid` FROM waypoint_scripts WHERE guid = %u", id);
+    
+	if( result )
     {
-        point = (*result)[0].GetUInt32()+1;
-        delete result;
-    }
+        WorldDatabase.PExecuteLog("DELETE FROM waypoint_scripts WHERE guid = %u", id);
+       PSendSysMessage("Wp Event: Waypoint script removed: %u", id);
+	   delete result;
+	}
     else
-        point = 1;
+		PSendSysMessage("Wp Event: ERROR: you have selected a non existing script: %u", id);
+		
+	return true;
+	}
+	
+	
+	if(show == "mod")
+	{
+	char* arg_1 = strtok(NULL," ");
+	
+	if(!arg_1)
+	{
+		SendSysMessage("ERROR: Waypoint script guid not present.");
+		return true;
+	}
+	
+	uint32 id = atoi(arg_1);
 
-    Player* player = m_session->GetPlayer();
+	if(!id)
+	{
+		SendSysMessage("ERROR: No vallid waypoint script id not present.");
+		return true;
+	}
 
-    WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z,orientation) VALUES ('%u','%u','%f', '%f', '%f', '%f')",
-        lowguid, point, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation());
+	char* arg_2 = strtok(NULL," ");
+	
+	if(!arg_2)
+		{	SendSysMessage("ERROR: No argument present.");
+	return true;}
+	
+	
+	std::string arg_string  = arg_2;
+	
+	
+if( (arg_string != "setid") && (arg_string != "delay") && (arg_string != "command")
+&& (arg_string != "datalong") && (arg_string != "datalong2") && (arg_string != "datatext") && (arg_string != "posx")
+&& (arg_string != "posy") && (arg_string != "posz") && (arg_string != "orientation")
+) {	SendSysMessage("ERROR: No valid argument present.");
+	return true;}
 
-    // update movement type
-    WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
-    if(pCreature)
+char* arg_3;
+std::string arg_str_2 = arg_2;
+
+if(arg_str_2 != "datatext")
+ arg_3 = strtok(NULL," ");
+	else arg_3 = strtok(NULL,"<>");
+
+if(!arg_3)
+{SendSysMessage("ERROR: No additional argument present.");
+	return true;}
+
+float coord;
+
+	if(arg_str_2 == "setid")
+	{	
+		uint32 newid = atoi(arg_3);
+		PSendSysMessage("Wp Event: Wypoint scipt guid: %u id changed: %u", newid, id);
+		WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET id='%u' WHERE guid='%u'",
+        newid, id); return true;
+	}
+	else 
+	{
+
+	QueryResult *result = WorldDatabase.PQuery("SELECT id FROM waypoint_scripts WHERE guid='%u'",id);
+
+	if(!result)
+	{
+		SendSysMessage("ERROR: You have selected an non existing waypoint script guid.");
+		return true;
+	}
+
+	delete result;
+
+if(arg_str_2 == "posx")
+{	
+	coord = atof(arg_3);
+	WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET x='%f' WHERE guid='%u'",
+        coord, id); 
+	PSendSysMessage("Waypoint script: %u position_x updated.", id);
+	return true;
+}else if(arg_str_2 == "posy")
+{
+	coord = atof(arg_3);
+	WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET y='%f' WHERE guid='%u'",
+        coord, id); 
+	PSendSysMessage("Waypoint script: %u position_y updated.", id);
+	return true;
+} else if(arg_str_2 == "posz")
+{
+	coord = atof(arg_3);
+	WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET z='%f' WHERE guid='%u'",
+		coord, id); 
+	PSendSysMessage("Waypoint script: %u position_z updated.", id);
+	return true;
+} else if(arg_str_2 == "orientation")
+{
+	coord = atof(arg_3);
+	WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET o='%f' WHERE guid='%u'",
+        coord, id); 
+	PSendSysMessage("Waypoint script: %u orientation updated.", id);
+	return true;
+} else if(arg_str_2 == "datatext")
+{
+		std::string arg_str_3 = arg_3;
+        
+		if(arg_str_3 == "NULL")
+		{
+			WorldDatabase.PExecute("UPDATE waypoint_scripts SET %s= NULL WHERE guid='%u'", arg_2, id);
+			PSendSysMessage("Waypoint script: %u datatext updated.", id);
+			return true;
+		}
+		WorldDatabase.escape_string(arg_str_3);
+        WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET %s='%s' WHERE guid='%u'",
+        arg_2, arg_str_3.c_str(), id);
+		PSendSysMessage("Waypoint script: %u datatext updated.", id);
+		return true;
+}else
+{
+		std::string arg_str_3 = arg_3;
+        WorldDatabase.escape_string(arg_str_3);
+        WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET %s='%s' WHERE guid='%u'",
+        arg_2, arg_str_3.c_str(), id);
+}
+}
+	PSendSysMessage("Waypoint script: %u: %s updated.", id,arg_2);
+}
+return true;
+}
+
+bool ChatHandler::HandleDistFormationCommand(const char* args)
+{
+if(!*args)
+	{        
+	SendSysMessage("No formation dist provided.");
+	return true;
+	}
+uint32 dist = atoi(args);
+Creature *target = getSelectedCreature(); 
+	
+if(!dist)
+	{        
+	SendSysMessage("No valid formation dist provided.");
+	return true;
+	}
+
+QueryResult *result = WorldDatabase.PQuery("SELECT follower FROM creature_formations WHERE follower='%u'", target->GetGUIDLow());
+
+if(!result)
+	{
+		QueryResult *result = WorldDatabase.PQuery("SELECT leader FROM creature_formations WHERE leader='%u'", target->GetGUIDLow());
+	
+	if(!result)
+		SendSysMessage("Current creature is not in formation.");
+		else 
+		{
+			WorldDatabase.PExecute("UPDATE creature_formations SET dist='%u' WHERE leader='%u'",dist,target->GetGUIDLow());
+			delete result;
+		}
+	}
+	else 
+	{
+		WorldDatabase.PExecute("UPDATE creature_formations SET dist='%u' WHERE follower='%u'", dist,target->GetGUIDLow());
+		delete result;
+	}
+SendSysMessage("Creature formation dist updated.");
+
+
+return true;
+}
+
+bool ChatHandler::HandleAngleFormationCommand(const char* args)
+{
+if(!*args)
+	{        
+	SendSysMessage("No formation angle provided.");
+	return true;
+	}
+uint32 angle = atof(args);
+Creature *target = getSelectedCreature(); 
+	
+if(!angle)
+	{        
+	SendSysMessage("No valid formation angle provided.");
+	return true;
+	}
+
+QueryResult *result = WorldDatabase.PQuery("SELECT follower FROM creature_formations WHERE follower='%u'", target->GetGUIDLow());
+
+if(!result)
+	{
+		QueryResult *result = WorldDatabase.PQuery("SELECT leader FROM creature_formations WHERE leader='%u'", target->GetGUIDLow());
+	
+	if(!result)
+		SendSysMessage("Current creature is not in formation.");
+		else 
+		{
+			WorldDatabase.PExecute("UPDATE creature_formations SET angle='%u' WHERE leader='%u'", angle,target->GetGUIDLow());
+			delete result;
+		}
+	}
+	else 
+	{
+		WorldDatabase.PExecute("UPDATE creature_formations SET angle='%u' WHERE follower='%u'", angle,target->GetGUIDLow());
+		delete result;
+	}
+SendSysMessage("Creature formation angle updated.");
+return true;
+}
+
+bool ChatHandler::HandleCreateFormationCommand(const char* args)
+{
+if(!*args)
+	{        
+	SendSysMessage("No leader GUID provided.");
+	return true;
+	}	
+
+uint32 LeaderGuid = atoi(args);
+Creature *target = getSelectedCreature(); 
+
+if (!LeaderGuid)
     {
-        pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
-        pCreature->GetMotionMaster()->Initialize();
-        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
-        {
-            pCreature->setDeathState(JUST_DIED);
-            pCreature->RemoveCorpse();
-            pCreature->Respawn();
-        }
+        SendSysMessage("No vallid leader GUID provided.");
+		return true;
+    }	
+
+if(!target)
+	{
+        SendSysMessage("No follower selected.");
+		return true;
     }
 
-    PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
+QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid='%u'", LeaderGuid);
 
-    return true;
-}                                                           // HandleWpAddCommand
+	if(!result)
+	{
+		SendSysMessage("ERROR: You have selected GUID of non existing creature.");
+		return true;
+	} 
+	else delete result;
 
-/**
- * .wp modify emote | spell | text | del | move | add
- *
- * add -> add a WP after the selected visual waypoint
- *        User must select a visual waypoint and then issue ".wp modify add"
- *
- * emote <emoteID>
- *   User has selected a visual waypoint before.
- *   <emoteID> is added to this waypoint. Everytime the
- *   NPC comes to this waypoint, the emote is called.
- *
- * emote <GUID> <WPNUM> <emoteID>
- *   User has not selected visual waypoint before.
- *   For the waypoint <WPNUM> for the NPC with <GUID>
- *   an emote <emoteID> is added.
- *   Everytime the NPC comes to this waypoint, the emote is called.
- *
- *
- * info <GUID> <WPNUM> -> User did not select a visual waypoint and
- */
+QueryResult *result1 = WorldDatabase.PQuery("SELECT follower FROM creature_formations WHERE follower='%u'", LeaderGuid);
+
+if(!result1)
+	{
+		WorldDatabase.PExecute("INSERT INTO creature_formations(leader,follower) VALUES('%u','%u')", LeaderGuid,target->GetGUIDLow());
+	} 
+	else 
+	{
+		delete result1;
+		WorldDatabase.PExecute("UPDATE creature_formations SET leader='%u' WHERE follower='%u'", LeaderGuid,target->GetGUIDLow());
+	}
+SendSysMessage("Formation created successfuly.");	
+return true;
+}
+
+bool ChatHandler::HandleDismissFormationCommand(const char* args)
+{
+	
+Creature *target = getSelectedCreature(); 
+
+if(!target)
+	{
+        SendSysMessage("No creature selected.");
+		return true;
+    }
+
+QueryResult *result = WorldDatabase.PQuery("SELECT follower FROM creature_formations WHERE follower='%u'", target->GetGUIDLow());
+
+if(!result)
+	{
+		QueryResult *result = WorldDatabase.PQuery("SELECT leader FROM creature_formations WHERE leader='%u'", target->GetGUIDLow());
+	
+	if(!result)
+		SendSysMessage("Current creature is not in formation.");
+		else 
+		{
+			QueryResult *result = WorldDatabase.PQuery("DELETE * FROM creature_formations WHERE leader='%u'", target->GetGUIDLow());
+			delete result;
+		}
+	}
+	else 
+	{
+		WorldDatabase.PExecute("DELETE FROM creature_formations WHERE follower='%u'", target->GetGUIDLow());
+		delete result;
+	}
+SendSysMessage("Formation dismissed successfuly.");	
+return true;
+}
+
 bool ChatHandler::HandleWpModifyCommand(const char* args)
 {
     sLog.outDebug("DEBUG: HandleWpModifyCommand");
@@ -2024,11 +2445,9 @@
     std::string show = show_str;
     // Check
     // Remember: "show" must also be the name of a column!
-    if( (show != "emote") && (show != "spell") && (show != "aiscript")
-        && (show != "text1") && (show != "text2") && (show != "text3") && (show != "text4") && (show != "text5")
-        && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
-        && (show != "model1") && (show != "model2") && (show != "orientation")
-        && (show != "import") && (show != "export") )
+    if( (show != "delay") && (show != "event_id") && (show != "event_chance")
+        && (show != "flag") && (show != "del") && (show != "move") && (show != "wpadd")
+       )
     {
         return false;
     }
@@ -2039,10 +2458,10 @@
     // Did user provide a GUID
     // or did the user select a creature?
     // -> variable lowguid is filled with the GUID of the NPC
-    uint32 lowguid = 0;
+    uint32 pathid = 0;
     uint32 point = 0;
     uint32 wpGuid = 0;
-    Unit* target = getSelectedCreature();
+    Creature* target = getSelectedCreature();
 
     if(target)
     {
@@ -2051,39 +2470,30 @@
         // The visual waypoint
         Creature* wpCreature = NULL;
 
-        wpGuid = target->GetGUIDLow();
+		wpGuid = target->GetGUIDLow();
 
         // Did the user select a visual spawnpoint?
         if(wpGuid)
-            wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
 
-        // attempt check creature existence by DB data
+            wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+
+		// attempt check creature existence by DB data
         if(!wpCreature)
         {
-            CreatureData const* data = objmgr.GetCreatureData(wpGuid);
-            if(!data)
-            {
+			QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE path_id = '%u'",wpGuid);
+            if(!result)
+			{
                 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, wpGuid);
                 return true;
             }
         }
-        // User did select a visual waypoint?
-        // Check the creature
-        if (wpCreature->GetEntry() != VISUAL_WAYPOINT )
-        {
-            if( (show != "export") && (show != "import") )
-            {
-                PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
-                return true;
-            }
-            lowguid = wpGuid;
-            arg_str = strtok((char*)NULL, " ");
-        }
-        else
-        {
+    // User did select a visual waypoint?
+    // Check the creature
+    if (wpCreature->GetEntry() == VISUAL_WAYPOINT )
+       {
             QueryResult *result =
-                WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
-                target->GetGUIDLow() );
+                WorldDatabase.PQuery( "SELECT id, point FROM waypoint_data WHERE wpguid = %u",
+				wpGuid);
             if(!result)
             {
                 sLog.outDebug("DEBUG: HandleWpModifyCommand - No waypoint found - used 'wpguid'");
@@ -2096,7 +2506,7 @@
                 // (0.001) - There is no other way to compare C++ floats with mySQL floats
                 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
                 const char* maxDIFF = "0.01";
-                result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
+                result = WorldDatabase.PQuery( "SELECT id, point FROM waypoint_data WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
                     wpCreature->GetPositionX(), maxDIFF, wpCreature->GetPositionY(), maxDIFF, wpCreature->GetPositionZ(), maxDIFF);
                 if(!result)
                 {
@@ -2109,8 +2519,8 @@
             do
             {
                 Field *fields = result->Fetch();
-                lowguid = fields[0].GetUInt32();
-                point   = fields[1].GetUInt32();
+                pathid = fields[0].GetUInt32();
+                point  = fields[1].GetUInt32();
             }while( result->NextRow() );
 
             // Cleanup memory
@@ -2118,14 +2528,9 @@
             delete result;
             // We have the waypoint number and the GUID of the "master npc"
             // Text is enclosed in "<>", all other arguments not
-            if( show.find("text") != std::string::npos )
-            {
-                arg_str = strtok((char*)NULL, "<>");
-            }
-            else
-            {
-                arg_str = strtok((char*)NULL, " ");
-            }
+            
+            arg_str = strtok((char*)NULL, " ");
+            
         }
     }
     else
@@ -2134,18 +2539,10 @@
         char* guid_str = strtok((char*)NULL, " ");
         char* point_str = strtok((char*)NULL, " ");
 
-        // Text is enclosed in "<>", all other arguments not
-        if( show.find("text") != std::string::npos )
+        arg_str = strtok((char*)NULL, " ");
+        
+		if( !guid_str )
         {
-            arg_str = strtok((char*)NULL, "<>");
-        }
-        else
-        {
-            arg_str = strtok((char*)NULL, " ");
-        }
-
-        if( !guid_str )
-        {
             SendSysMessage(LANG_WAYPOINT_NOGUID);
             return false;
         }
@@ -2154,7 +2551,7 @@
             SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
             return false;
         }
-        if( (show != "del") && (show != "move") && (show != "add") )
+        if( (show != "del") && (show != "move") )
         {
             if( !arg_str )
             {
@@ -2162,15 +2559,15 @@
                 return false;
             }
         }
-        lowguid = atoi((char*)guid_str);
-        PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
+        pathid = atoi((char*)guid_str);
+        PSendSysMessage("DEBUG: GUID provided: %d", pathid);
         point    = atoi((char*)point_str);
         PSendSysMessage("DEBUG: wpNumber provided: %d", point);
 
         // Now we need the GUID of the visual waypoint
         // -> "del", "move", "add" command
 
-        QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u'", lowguid, point);
+        QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM waypoint_data WHERE id = '%u' AND point = '%u'", pathid, point);
         if(result)
         {
             do
@@ -2184,12 +2581,12 @@
         }
         else
         {
-            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
+            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, pathid, point);
             // Select waypoint number from database
-            QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='%d' AND id = '%u'", point, lowguid);
+            QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM waypoint_data WHERE point='%d' AND id = '%u'", point, pathid);
             if(!result)
             {
-                PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+                PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid);
                 return true;
             }
 
@@ -2229,7 +2626,7 @@
     sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
 
     // Check for argument
-    if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add") && (show != "aiscript"))
+    if((show != "del") && (show != "move"))
     {
         if( arg_str == NULL )
         {
@@ -2237,97 +2634,12 @@
             return false;
         }
     }
-    // wpGuid  -> GUID of the waypoint creature
-    // lowguid -> GUID of the NPC
-    // point   -> waypoint number
-
-    // Special functions:
-    // add - move - del -> no args commands
-    // Add a waypoint after the selected visual
-    if(show == "add" && target)
-    {
-        PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
-
-        // Get the creature for which we read the waypoint
-        /* impossible without entry
-        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_GUID(lowguid, HIGHGUID_UNIT));
-        */
-        Creature* npcCreature = (Creature*)target;
-
-        if( !npcCreature )
-        {
-            PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
-            return true;
-        }
-        else
-        {
-            // obtain real GUID for DB operations
-            lowguid = npcCreature->GetDBTableGUIDLow();
-        }
-        sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
-
-        // What to do:
-        // Add the visual spawnpoint (DB only)
-        // Adjust the waypoints
-        // Respawn the owner of the waypoints
-        sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- SELECT MAX(`point`)");
-        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
-        uint32 maxPoint = 0;
-        if( result )
-        {
-            maxPoint = (*result)[0].GetUInt32();
-            delete result;
-        }
-        for( uint32 i=maxPoint; i>point; i-- )
-        {
-            WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point+1 WHERE id='%u' AND point='%u'", lowguid, i);
-        }
-
-        Player* chr = m_session->GetPlayer();
-        WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z) VALUES ('%u','%u','%f', '%f', '%f')",
-            lowguid, point+1, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
-
-        if(npcCreature)
-        {
-            npcCreature->GetMotionMaster()->Initialize();
-            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
-            {
-                npcCreature->setDeathState(JUST_DIED);
-                npcCreature->RemoveCorpse();
-                npcCreature->Respawn();
-            }
-        }
-
-        Creature* wpCreature = new Creature(chr);
-        if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(),
-            chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation(), VISUAL_WAYPOINT,0))
-        {
-            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
-            delete wpCreature;
-            return false;
-        }
-        WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point+1);
-
-        wpCreature->SaveToDB();
-        // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
-        wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
-        MapManager::Instance().GetMap(wpCreature->GetMapId(), wpCreature)->Add(wpCreature);
-
-        PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
-        return true;
-    }                                                       // add
-
+    
     if(show == "del" && target)
     {
-        PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
+        PSendSysMessage("DEBUG: wp modify del, PathID: %u", pathid);
 
-        // Get the creature for which we read the waypoint
-        /* impossible without entry
-        Creature* npcCreature  = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid, HIGHGUID_UNIT));
-        */
-        Creature* npcCreature = (Creature*)target;
-
-        // wpCreature
+		// wpCreature
         Creature* wpCreature = NULL;
         if( wpGuid != 0 )
         {
@@ -2337,55 +2649,22 @@
             ObjectAccessor::Instance().AddObjectToRemoveList(wpCreature);
         }
 
-        // What to do:
-        // Remove the visual spawnpoint
-        // Adjust the waypoints
-        // Respawn the owner of the waypoints
+		WorldDatabase.PExecuteLog("DELETE FROM waypoint_data WHERE id='%u' AND point='%u'",
+            pathid, point);
+        WorldDatabase.PExecuteLog("UPDATE waypoint_data SET point=point-1 WHERE id='%u' AND point>'%u'",
+            pathid, point);
 
-        WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u' AND point='%u'",
-            lowguid, point);
-        WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point-1 WHERE id='%u' AND point>'%u'",
-            lowguid, point);
-
-        if(npcCreature)
-        {
-            // Any waypoints left?
-            QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
-            if(!result2)
-            {
-                npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
-            }
-            else
-            {
-                npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
-                delete result2;
-            }
-            npcCreature->GetMotionMaster()->Initialize();
-            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
-            {
-                npcCreature->setDeathState(JUST_DIED);
-                npcCreature->RemoveCorpse();
-                npcCreature->Respawn();
-            }
-        }
-
         PSendSysMessage(LANG_WAYPOINT_REMOVED);
         return true;
     }                                                       // del
 
     if(show == "move" && target)
     {
-        PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
+        PSendSysMessage("DEBUG: wp move, PathID: %u", pathid);
 
         Player *chr = m_session->GetPlayer();
         {
-            // Get the creature for which we read the waypoint
-            /* impossible without entry
-            Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
-            */
-            Creature* npcCreature = (Creature*)target;
-
-            // wpCreature
+			// wpCreature
             Creature* wpCreature = NULL;
             // What to do:
             // Move the visual spawnpoint
@@ -2406,263 +2685,42 @@
                     return false;
                 }
                 wpCreature2->SaveToDB();
-                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
-                wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), chr->GetInstanceId());
-                MapManager::Instance().GetMap(npcCreature->GetMapId(), npcCreature)->Add(wpCreature2);
-                //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
+				wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), chr->GetInstanceId());
+                MapManager::Instance().GetMap(chr->GetMapId(), chr)->Add(wpCreature2);
+                
             }
 
-            WorldDatabase.PExecuteLog("UPDATE creature_movement SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'",
-                chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), lowguid, point );
+            WorldDatabase.PExecuteLog("UPDATE waypoint_data SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'",
+                chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), pathid, point );
 
-            if(npcCreature)
-            {
-                npcCreature->GetMotionMaster()->Initialize();
-                if(npcCreature->isAlive())                  // dead creature will reset movement generator at respawn
-                {
-                    npcCreature->setDeathState(JUST_DIED);
-                    npcCreature->RemoveCorpse();
-                    npcCreature->Respawn();
-                }
-            }
             PSendSysMessage(LANG_WAYPOINT_CHANGED);
         }
         return true;
     }                                                       // move
 
-    if(show == "export")
-    {
-        PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
-
-        std::ofstream outfile;
-        outfile.open (arg_str);
-
-        QueryResult *result = WorldDatabase.PQuery(
-        //          0      1           2           3           4            5       6       7         8      9      10     11     12     13     14     15
-            "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
-
-        if( result )
-        {
-            do
-            {
-                Field *fields = result->Fetch();
-
-                outfile << "insert into creature_movement ";
-                outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) values ";
-
-                //sLog.outDebug("( ");
-                outfile << "( ";
-                //sLog.outDebug("id");
-                outfile << fields[16].GetUInt32();          // id
-                outfile << ", ";
-                //sLog.outDebug("point");
-                outfile << fields[0].GetUInt32();           // point
-                outfile << ", ";
-                //sLog.outDebug("position_x");
-                outfile << fields[1].GetFloat();            // position_x
-                outfile << ", ";
-                //sLog.outDebug("position_y");
-                outfile << fields[2].GetFloat();            // position_y
-                outfile << ", ";
-                //sLog.outDebug("position_z");
-                outfile << fields[3].GetUInt32();           // position_z
-                outfile << ", ";
-                //sLog.outDebug("orientation");
-                outfile << fields[4].GetUInt32();           // orientation
-                outfile << ", ";
-                //sLog.outDebug("model1");
-                outfile << fields[5].GetUInt32();           // model1
-                outfile << ", ";
-                //sLog.outDebug("model2");
-                outfile << fields[6].GetUInt32();           // model2
-                outfile << ", ";
-                //sLog.outDebug("waittime");
-                outfile << fields[7].GetUInt16();           // waittime
-                outfile << ", ";
-                //sLog.outDebug("emote");
-                outfile << fields[8].GetUInt32();           // emote
-                outfile << ", ";
-                //sLog.outDebug("spell");
-                outfile << fields[9].GetUInt32();           // spell
-                outfile << ", ";
-                //sLog.outDebug("text1");
-                const char *tmpChar = fields[10].GetString();
-                if( !tmpChar )
-                {
-                    outfile << "NULL";                      // text1
-                }
-                else
-                {
-                    outfile << "'";
-                    outfile << tmpChar;                     // text1
-                    outfile << "'";
-                }
-                outfile << ", ";
-                //sLog.outDebug("text2");
-                tmpChar = fields[11].GetString();
-                if( !tmpChar )
-                {
-                    outfile << "NULL";                      // text2
-                }
-                else
-                {
-                    outfile << "'";
-                    outfile << tmpChar;                     // text2
-                    outfile << "'";
-                }
-                outfile << ", ";
-                //sLog.outDebug("text3");
-                tmpChar = fields[12].GetString();
-                if( !tmpChar )
-                {
-                    outfile << "NULL";                      // text3
-                }
-                else
-                {
-                    outfile << "'";
-                    outfile << tmpChar;                     // text3
-                    outfile << "'";
-                }
-                outfile << ", ";
-                //sLog.outDebug("text4");
-                tmpChar = fields[13].GetString();
-                if( !tmpChar )
-                {
-                    outfile << "NULL";                      // text4
-                }
-                else
-                {
-                    outfile << "'";
-                    outfile << tmpChar;                     // text4
-                    outfile << "'";
-                }
-                outfile << ", ";
-                //sLog.outDebug("text5");
-                tmpChar = fields[14].GetString();
-                if( !tmpChar )
-                {
-                    outfile << "NULL";                      // text5
-                }
-                else
-                {
-                    outfile << "'";
-                    outfile << tmpChar;                     // text5
-                    outfile << "'";
-                }
-                outfile << ");\n ";
-
-            } while( result->NextRow() );
-            delete result;
-
-            PSendSysMessage(LANG_WAYPOINT_EXPORTED);
-        }
-        else
-        {
-            PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
-            outfile << GetMangosString(LANG_WAYPOINT_NOTHINGTOEXPORT);
-        }
-        outfile.close();
-
-        return true;
-    }
-    if(show == "import")
-    {
-        PSendSysMessage("DEBUG: wp import, GUID: %u", lowguid);
-
-        std::string line;
-        std::ifstream infile (arg_str);
-        if (infile.is_open())
-        {
-            while (! infile.eof() )
-            {
-                getline (infile,line);
-                //cout << line << endl;
-                QueryResult *result = WorldDatabase.PQuery(line.c_str());
-                delete result;
-            }
-            infile.close();
-        }
-        PSendSysMessage(LANG_WAYPOINT_IMPORTED);
-
-        return true;
-    }
-
-    // Create creature - npc that has the waypoint
-    Creature* npcCreature = NULL;
-
-    /* FIXME: impossible withput entry
-    if(lowguid)
-        npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
-    */
-
-    // attempt check creature existance by DB
-    if(!npcCreature)
-    {
-        if(!objmgr.GetCreatureData(lowguid))
-        {
-            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
-            return true;
-        }
-    }
-
     const char *text = arg_str;
 
     if( text == 0 )
     {
         // show_str check for present in list of correct values, no sql injection possible
-        WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s=NULL WHERE id='%u' AND point='%u'",
-            show_str, lowguid, point);
+        WorldDatabase.PExecuteLog("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'",
+            show_str, pathid, point);
     }
     else
     {
         // show_str check for present in list of correct values, no sql injection possible
         std::string text2 = text;
         WorldDatabase.escape_string(text2);
-        WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s='%s' WHERE id='%u' AND point='%u'",
-            show_str, text2.c_str(), lowguid, point);
+        WorldDatabase.PExecuteLog("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'",
+            show_str, text2.c_str(), pathid, point);
     }
+	
+	PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
 
-    if(npcCreature)
-    {
-        npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
-        npcCreature->GetMotionMaster()->Initialize();
-        if(npcCreature->isAlive())                          // dead creature will reset movement generator at respawn
-        {
-            npcCreature->setDeathState(JUST_DIED);
-            npcCreature->RemoveCorpse();
-            npcCreature->Respawn();
-        }
-    }
-    PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
-
     return true;
 }
 
-/**
- * .wp show info | on | off
- *
- * info -> User has selected a visual waypoint before
- *
- * info <GUID> <WPNUM> -> User did not select a visual waypoint and
- *                        provided the GUID of the NPC and the number of
- *                        the waypoint.
- *
- * on -> User has selected an NPC; all visual waypoints for this
- *       NPC are added to the world
- *
- * on <GUID> -> User did not select an NPC - instead the GUID of the
- *              NPC is provided. All visual waypoints for this NPC
- *              are added from the world.
- *
- * off -> User has selected an NPC; all visual waypoints for this
- *        NPC are removed from the world.
- *
- * on <GUID> -> User did not select an NPC - instead the GUID of the
- *              NPC is provided. All visual waypoints for this NPC
- *              are removed from the world.
- *
- *
- */
+
 bool ChatHandler::HandleWpShowCommand(const char* args)
 {
     sLog.outDebug("DEBUG: HandleWpShowCommand");
@@ -2679,20 +2737,16 @@
     // second arg: GUID (optional, if a creature is selected)
     char* guid_str = strtok((char*)NULL, " ");
     sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
-    //if (!guid_str) {
-    //    return false;
-    //}
-
-    // Did user provide a GUID
-    // or did the user select a creature?
-    // -> variable lowguid is filled with the GUID
+    
+    uint32 pathid = 0;
+	Creature* target = getSelectedCreature();
     uint32 lowguid = 0;
-    Unit* target = getSelectedCreature();
-    // Did player provide a GUID?
+	
+	// Did player provide a PathID?
     if (!guid_str)
     {
         sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
-        // No GUID provided
+        // No PathID provided
         // -> Player must have selected a creature
 
         if(!target)
@@ -2700,20 +2754,20 @@
             SendSysMessage(LANG_SELECT_CREATURE);
             return true;
         }
-        lowguid = target->GetGUIDLow();
-    }
+		pathid = target->GetWaypointPath();
+	}
     else
     {
-        sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
-        // GUID provided
+        sLog.outDebug("DEBUG: HandleWpShowCommand: PathID provided");
+        // PathID provided
         // Warn if player also selected a creature
         // -> Creature selection is ignored <-
         if(target)
         {
             SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
         }
-        lowguid = atoi((char*)guid_str);
-    }
+        pathid = atoi((char*)guid_str);
+	}
 
     sLog.outDebug("DEBUG: HandleWpShowCommand: danach");
 
@@ -2722,114 +2776,71 @@
 
     Creature* pCreature = NULL;
 
-    sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
+	sLog.outDebug("DEBUG: HandleWpShowCommand: PathID: %u", pathid);
+    
+	sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
 
-    /* imposiible without entry
-    if(lowguid)
-        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
-    */
-
-    sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", pCreature );
-    // attempt check creature existance by DB
-    if(!pCreature)
-    {
-        if(!objmgr.GetCreatureData(lowguid))
-        {
-            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
-            return true;
-        }
-    }
-
-    sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
     //PSendSysMessage("wpshow - show: %s", show);
 
     // Show info for the selected waypoint
     if(show == "info")
-    {
-        PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
-
-        // Check if the user did specify a visual waypoint
-        if( pCreature->GetEntry() != VISUAL_WAYPOINT )
+	{
+        
+		// Check if the user did specify a visual waypoint
+        if( target->GetEntry() != VISUAL_WAYPOINT )
         {
             PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
             return true;
         }
 
-        //PSendSysMessage("wp on, GUID: %u", lowguid);
-
-        //pCreature->GetPositionX();
-
-        QueryResult *result =
-            WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
-            pCreature->GetGUID() );
-        if(!result)
+		QueryResult *result = WorldDatabase.PQuery( "SELECT id, point, delay, move_flag, event_id, event_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow());
+            
+		if(!result)
         {
-            // Since we compare float values, we have to deal with
-            // some difficulties.
-            // Here we search for all waypoints that only differ in one from 1 thousand
-            // (0.001) - There is no other way to compare C++ floats with mySQL floats
-            // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
-            const char* maxDIFF = "0.01";
-            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, pCreature->GetGUID());
-
-            result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
-                pCreature->GetPositionX(), maxDIFF, pCreature->GetPositionY(), maxDIFF, pCreature->GetPositionZ(), maxDIFF);
-            if(!result)
-            {
-                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
-                return true;
-            }
+			SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM);
+            return true;      
         }
-        do
+		
+		SendSysMessage("DEBUG: wp show info:");
+		
+		do
         {
             Field *fields = result->Fetch();
-            uint32 creGUID          = fields[0].GetUInt32();
-            uint32 point            = fields[1].GetUInt32();
-            int waittime            = fields[2].GetUInt32();
-            uint32 emote            = fields[3].GetUInt32();
-            uint32 spell            = fields[4].GetUInt32();
-            const char * text1      = fields[5].GetString();
-            const char * text2      = fields[6].GetString();
-            const char * text3      = fields[7].GetString();
-            const char * text4      = fields[8].GetString();
-            const char * text5      = fields[9].GetString();
-            uint32 model1           = fields[10].GetUInt32();
-            uint32 model2           = fields[11].GetUInt32();
+            pathid					= fields[0].GetUInt32();
+			uint32 point            = fields[1].GetUInt32();
+			uint32 delay            = fields[2].GetUInt32();
+			uint32 flag				= fields[3].GetUInt32();
+            uint32 ev_id			= fields[4].GetUInt32();
+			uint32 ev_chance        = fields[5].GetUInt32();
 
-            // Get the creature for which we read the waypoint
-            Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
+			PSendSysMessage("Show info: for current point: %u, Path ID: %u", point, pathid);
+			PSendSysMessage("Show info: delay: %u", delay);
+			PSendSysMessage("Show info: Move flag: %u", flag);
+			PSendSysMessage("Show info: Waypoint event: %u", ev_id);
+			PSendSysMessage("Show info: Event chance: %u", ev_chance);
+            }while( result->NextRow() );
 
-            PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
-            PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
-            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
-            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
-            PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
-            PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
-            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
-            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
-            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
-            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
-            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
-
-        }while( result->NextRow() );
-        // Cleanup memory
+		// Cleanup memory
         delete result;
         return true;
     }
 
     if(show == "on")
-    {
-        PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
-
-        QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
-        if(!result)
+	{
+         QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM waypoint_data WHERE id = '%u'", pathid);
+        
+		if(!result)
         {
-            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+			PSendSysMessage("Path no found.", pathid);
             return true;
         }
-        // Delete all visuals for this NPC
-        QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
-        if(result2)
+        
+		PSendSysMessage("DEBUG: wp on, PathID: %u", pathid);
+		
+		// Delete all visuals for this NPC
+        QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid);
+        
+		if(result2)
         {
             bool hasError = false;
             do
@@ -2852,8 +2863,10 @@
                 }
 
             }while( result2->NextRow() );
-            delete result2;
-            if( hasError )
+            
+			delete result2;
+            
+			if( hasError )
             {
                 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
                 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
@@ -2882,19 +2895,25 @@
                 delete result;
                 return false;
             }
-            wpCreature->SetVisibility(VISIBILITY_OFF);
-            sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
+			
+			sLog.outDebug("DEBUG: UPDATE waypoint_data SET wpguid = '%u");
             // set "wpguid" column to the visual waypoint
-            WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
+            WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);
 
             wpCreature->SaveToDB();
             // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
             wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
             MapManager::Instance().GetMap(wpCreature->GetMapId(), wpCreature)->Add(wpCreature);
-            //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
+            if(target)
+			{
+				wpCreature->SetDisplayId(target->GetDisplayId());
+				wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+			}
+			//MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
         }while( result->NextRow() );
 
-        // Cleanup memory
+        SendSysMessage("Showing the current creature's path.");
+		// Cleanup memory
         delete result;
         return true;
     }
@@ -2903,10 +2922,10 @@
     {
         PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
 
-        QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
+        QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM waypoint_data WHERE point='1' AND id = '%u'",pathid);
         if(!result)
         {
-            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid);
             return true;
         }
 
@@ -2931,7 +2950,13 @@
         pCreature->SaveToDB();
         pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
         MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
-        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
+        
+		if(target)
+			{
+				pCreature->SetDisplayId(target->GetDisplayId());
+				pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+			}
+		//player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
 
         // Cleanup memory
         delete result;
@@ -2940,9 +2965,9 @@
 
     if(show == "last")
     {
-        PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
+        PSendSysMessage("DEBUG: wp last, PathID: %u", pathid);
 
-        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
+        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",pathid);
         if( result )
         {
             Maxpoint = (*result)[0].GetUInt32();
@@ -2952,10 +2977,10 @@
         else
             Maxpoint = 0;
 
-        result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
+        result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM waypoint_data WHERE point ='%u' AND id = '%u'",Maxpoint, pathid);
         if(!result)
         {
-            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
+            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid);
             return true;
         }
         Field *fields = result->Fetch();
@@ -2979,7 +3004,13 @@
         pCreature->SaveToDB();
         pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), chr->GetInstanceId());
         MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
-        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
+        
+		if(target)
+			{
+				pCreature->SetDisplayId(target->GetDisplayId());
+				pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+			}
+		//player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
         // Cleanup memory
         delete result;
         return true;
@@ -2987,7 +3018,7 @@
 
     if(show == "off")
     {
-        QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
+        QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1);
         if(!result)
         {
             SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
@@ -3018,7 +3049,7 @@
             }
         }while(result->NextRow());
         // set "wpguid" column to "empty" - no visual waypoint spawned
-        WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
+        WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '0'");
 
         if( hasError )
         {
Index: src/game/Level3.cpp
===================================================================
--- src/game/Level3.cpp	(revision 5687)
+++ src/game/Level3.cpp	(working copy)
@@ -108,7 +108,8 @@
     HandleReloadQuestEndScriptsCommand("a");
     HandleReloadQuestStartScriptsCommand("a");
     HandleReloadSpellScriptsCommand("a");
-    SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
+    HandleReloadWaypointScriptsCommand("a");
+	SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
     return true;
 }
 
@@ -125,7 +126,8 @@
     HandleReloadSpellScriptTargetCommand("a");
     HandleReloadSpellTeleportCommand("a");
     HandleReloadSpellThreatsCommand("a");
-    return true;
+    HandleReloadWaypointScriptsCommand("a");
+	return true;
 }
 
 bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
@@ -435,6 +437,25 @@
     return true;
 }
 
+bool ChatHandler::HandleReloadWaypointScriptsCommand(const char* arg)
+{
+    if(sWorld.IsScriptScheduled())
+    {
+        SendSysMessage("DB scripts used currently, please attempt reload later.");
+        return true;
+    }
+
+    if(*arg!='a')
+        sLog.outString( "Re-Loading Scripts from `quest_start_scripts`...");
+
+	objmgr.LoadWaypointScripts();
+
+    if(*arg!='a')
+        SendGlobalSysMessage("DB table `quest_start_scripts` reloaded.");
+
+    return true;
+}
+
 bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg)
 {
     if(sWorld.IsScriptScheduled())
Index: src/game/Object.cpp
===================================================================
--- src/game/Object.cpp	(revision 5687)
+++ src/game/Object.cpp	(working copy)
@@ -525,9 +525,54 @@
 {
     if(!target)
         return;
+	
+	bool reset = false;
+	uint32 oldflags = 0;
+	bool IsActivateToQuest = false;
+    
+    Creature const* pThis = static_cast<Creature const*>(this);
+				/*
+				if(GetTypeId() == TYPEID_UNIT && pThis->isTagged && (pThis->loot.gold || pThis->loot.items.size()))
+				{
+					// Let's see if we're the tagger or not.
+					oldflags = m_uint32Values[UNIT_DYNAMIC_FLAGS];
+					uint32 Flags = m_uint32Values[UNIT_DYNAMIC_FLAGS];
+					uint32 oldFlags = 0;
 
-    bool IsActivateToQuest = false;
-    if (updatetype == UPDATETYPE_CREATE_OBJECT || updatetype == UPDATETYPE_CREATE_OBJECT2)
+				if(pThis->TaggerGuid == target->GetGUID())
+
+					{
+					// Our target is our tagger.
+					oldFlags = 4;
+
+					if(Flags & 4)
+						Flags &= ~oldFlags;
+
+					if(!(Flags & 1))
+						Flags |= 1;
+					}
+			else
+			{
+				// Target is not the tagger.
+				oldFlags = 1;
+
+				if(!(Flags & 4))
+					Flags |= 4;
+
+				if(Flags & 1)
+					Flags &= ~oldFlags;
+			}
+
+			m_uint32Values[UNIT_DYNAMIC_FLAGS] = Flags;
+
+			updateMask->SetBit(UNIT_DYNAMIC_FLAGS);
+			
+			
+			
+			reset = true;
+				}*/
+	
+	if (updatetype == UPDATETYPE_CREATE_OBJECT || updatetype == UPDATETYPE_CREATE_OBJECT2)
     {
         if (isType(TYPE_GAMEOBJECT) && !((GameObject*)this)->IsTransport())
         {
@@ -584,14 +629,15 @@
                 {
                     *data << (m_uint32Values[ index ] & ~UNIT_FLAG_NOT_SELECTABLE);
                 }
-                else
-                {
-                    // send in current format (float as float, uint32 as uint32)
+				
+				 else
+			
+					// send in current format (float as float, uint32 as uint32)
                     *data << m_uint32Values[ index ];
                 }
             }
         }
-    }
+    
     else if(isType(TYPE_GAMEOBJECT))                        // gameobject case
     {
         for( uint16 index = 0; index < m_valuesCount; index ++ )
@@ -635,6 +681,12 @@
             }
         }
     }
+
+//if(reset && GetTypeId() == TYPEID_UNIT)
+	//m_uint32Values[UNIT_DYNAMIC_FLAGS] = oldflags;
+			
+		
+
 }
 
 void Object::ClearUpdateMask(bool remove)
Index: src/game/ObjectAccessor.cpp
===================================================================
--- src/game/ObjectAccessor.cpp	(revision 5687)
+++ src/game/ObjectAccessor.cpp	(working copy)
@@ -35,6 +35,7 @@
 #include "GridNotifiersImpl.h"
 #include "Opcodes.h"
 #include "ObjectDefines.h"
+#include "WaypointMovementGenerator.h"
 
 #include <cmath>
 
@@ -561,16 +562,24 @@
 ObjectAccessor::Update(uint32 diff)
 {
     {
-        typedef std::multimap<uint32, Player *> CreatureLocationHolderType;
+        typedef std::multimap<uint32, Unit *> CreatureLocationHolderType;
         CreatureLocationHolderType creature_locations;
         //TODO: Player guard
         HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
-        for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
+        
+		for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
         {
             if(iter->second->IsInWorld()) iter->second->Update(diff);
             creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) );
         }
-
+		
+		WaypointMovementGenerator<Creature>::ActiveCreatureList& WpMap = WaypointMovementGenerator<Creature>::GetContainer();
+		
+		for(WaypointMovementGenerator<Creature>::ActiveCreatureList::iterator iter = WpMap.begin(); iter != WpMap.end(); ++iter)
+        {
+           creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) );
+        }
+		
         Map *map;
 
         MaNGOS::ObjectUpdater updater(diff);
@@ -586,7 +595,7 @@
 
         for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter)
         {
-            Player *player = (*iter).second;
+            Unit *player = (*iter).second;
             map = MapManager::Instance().GetMap((*iter).first, player);
 
             CellPair standing_cell(MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()));
Index: src/game/ObjectAccessor.h
===================================================================
--- src/game/ObjectAccessor.h	(revision 5687)
+++ src/game/ObjectAccessor.h	(working copy)
@@ -24,6 +24,7 @@
 #include "zthread/FastMutex.h"
 #include "Utilities/HashMap.h"
 #include "Policies/ThreadingModel.h"
+#include "WaypointMovementGenerator.h"
 
 #include "ByteBuffer.h"
 #include "UpdateData.h"
@@ -48,25 +49,27 @@
     public:
 
         typedef HM_NAMESPACE::hash_map< uint64, T* >   MapType;
-        typedef ZThread::FastMutex LockType;
+		typedef ZThread::FastMutex LockType;
         typedef MaNGOS::GeneralLock<LockType > Guard;
 
         static void Insert(T* o) { m_objectMap[o->GetGUID()] = o; }
-        static void Remove(T* o)
+        
+		static void Remove(T* o)
         {
             Guard guard(i_lock);
             typename MapType::iterator itr = m_objectMap.find(o->GetGUID());
             if (itr != m_objectMap.end())
                 m_objectMap.erase(itr);
         }
-        static T* Find(uint64 guid)
+        
+		static T* Find(uint64 guid)
         {
             typename MapType::iterator itr = m_objectMap.find(guid);
             return (itr != m_objectMap.end()) ? itr->second : NULL;
         }
 
         static MapType& GetContainer() { return m_objectMap; }
-
+		
         static LockType* GetLock() { return &i_lock; }
     private:
 
@@ -89,8 +92,8 @@
     public:
         typedef HM_NAMESPACE::hash_map<uint64, Corpse* >      Player2CorpsesMapType;
         typedef HM_NAMESPACE::hash_map<Player*, UpdateData>::value_type UpdateDataValueType;
-
-        template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
+		
+		template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
         {
             return HashMapHolder<T>::Find(guid);
         }
@@ -140,7 +143,8 @@
         static Creature* GetCreature(WorldObject const &, uint64);
         static Creature* GetCreatureOrPet(WorldObject const &, uint64);
         static Unit* GetUnit(WorldObject const &, uint64);
-        static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
+        static Creature* GetSqlIdCreature(uint32);
+		static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
         static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
         static GameObject* GetGameObject(WorldObject const &, uint64);
         static DynamicObject* GetDynamicObject(Unit const &, uint64);
@@ -149,8 +153,8 @@
         static Player* FindPlayer(uint64);
 
         Player* FindPlayerByName(const char *name) ;
-
-        HashMapHolder<Player>::MapType& GetPlayers()
+		
+		HashMapHolder<Player>::MapType& GetPlayers()
         {
             return HashMapHolder<Player>::GetContainer();
         }
Index: src/game/ObjectMgr.cpp
===================================================================
--- src/game/ObjectMgr.cpp	(revision 5687)
+++ 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);
 
@@ -45,6 +46,7 @@
 ScriptMapMap sSpellScripts;
 ScriptMapMap sGameObjectScripts;
 ScriptMapMap sEventScripts;
+ScriptMapMap sWaypointScripts;
 
 ObjectMgr::ObjectMgr()
 {
@@ -658,6 +660,26 @@
     }
 }
 
+void ObjectMgr::LoadCreatureFormations()
+{
+    
+	sCreatureFormation.Load();
+
+    sLog.outString( ">> Loaded %u creature formations", sCreatureFormation.RecordCount );
+    sLog.outString();
+	
+	for(uint32 i = 1; i < sCreatureFormation.MaxEntry; ++i)
+    {
+		
+	CreatureFormation const* formation = sCreatureFormation.LookupEntry<CreatureFormation>(i);
+        if(!formation)
+            continue;
+
+		if(mCreatureDataMap.find(formation->follower)==mCreatureDataMap.end())
+			sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_formation`",formation->follower);
+	}
+}
+
 EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry)
 {
     return sEquipmentStorage.LookupEntry<EquipmentInfo>(entry);
@@ -808,6 +830,13 @@
     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;
@@ -3290,6 +3319,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");
Index: src/game/ObjectMgr.h
===================================================================
--- src/game/ObjectMgr.h	(revision 5687)
+++ src/game/ObjectMgr.h	(working copy)
@@ -45,6 +45,7 @@
 
 extern SQLStorage sCreatureStorage;
 extern SQLStorage sCreatureDataAddonStorage;
+extern SQLStorage sCreatureFormation;
 extern SQLStorage sCreatureInfoAddonStorage;
 extern SQLStorage sCreatureModelStorage;
 extern SQLStorage sEquipmentStorage;
@@ -81,6 +82,7 @@
 extern ScriptMapMap sSpellScripts;
 extern ScriptMapMap sGameObjectScripts;
 extern ScriptMapMap sEventScripts;
+extern ScriptMapMap sWaypointScripts;
 
 struct AreaTrigger
 {
@@ -256,7 +258,12 @@
             return sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(entry);
         }
 
-        static ItemPrototype const* GetItemPrototype(uint32 id) { return sItemStorage.LookupEntry<ItemPrototype>(id); }
+        static CreatureFormation const *GetFormation( uint32 lowguid )
+        {
+            return sCreatureFormation.LookupEntry<CreatureFormation>(lowguid);
+        }
+		
+		static ItemPrototype const* GetItemPrototype(uint32 id) { return sItemStorage.LookupEntry<ItemPrototype>(id); }
 
         static InstanceTemplate const* GetInstanceTemplate(uint32 map)
         {
@@ -409,6 +416,7 @@
         void LoadQuestStartScripts();
         void LoadEventScripts();
         void LoadSpellScripts();
+        void LoadWaypointScripts();
 
         bool LoadMangosStrings();
         void LoadMangosStringLocales();
@@ -419,7 +427,9 @@
         void LoadCreatureRespawnTimes();
         void LoadCreatureAddons();
         void LoadCreatureModelInfo();
-        void LoadEquipmentTemplates();
+        void LoadWaypointData();
+        void LoadCreatureFormations();
+		void LoadEquipmentTemplates();
         void LoadGameObjectLocales();
         void LoadGameobjects();
         void LoadGameobjectRespawnTimes();
@@ -693,8 +703,7 @@
         MangosStringLocaleMap mMangosStringLocaleMap;
         RespawnTimes mCreatureRespawnTimes;
         RespawnTimes mGORespawnTimes;
-
-        typedef std::vector<uint32> GuildBankTabPriceMap;
+		typedef std::vector<uint32> GuildBankTabPriceMap;
         GuildBankTabPriceMap mGuildBankTabPrice;
 };
 
Index: src/game/TargetedMovementGenerator.cpp
===================================================================
--- src/game/TargetedMovementGenerator.cpp	(revision 5687)
+++ src/game/TargetedMovementGenerator.cpp	(working copy)
@@ -92,10 +92,22 @@
 {
     if(!&owner)
         return;
+
     owner.SetUnitMovementFlag(MOVEMENT_FLAG_RUN);
+
     _setTargetLocation(owner);
 }
 
+void
+TargetedMovementGenerator<Creature>::Initialize(Creature &owner)
+{
+    if(!&owner)
+        return;
+    
+	owner.SetUnitMovementFlag(MOVEMENT_FLAG_RUN);
+    _setTargetLocation(owner);
+}
+
 template<class T>
 void
 TargetedMovementGenerator<T>::Finalize(T &owner)
@@ -192,7 +204,7 @@
 template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
 template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
 template void TargetedMovementGenerator<Player>::Initialize(Player &);
-template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
+//template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
 template void TargetedMovementGenerator<Player>::Finalize(Player &);
 template void TargetedMovementGenerator<Creature>::Finalize(Creature &);
 template void TargetedMovementGenerator<Player>::Reset(Player &);
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 5687)
+++ src/game/Unit.cpp	(working copy)
@@ -442,7 +442,7 @@
 
     // remove affects from attacker at any non-DoT damage (including 0 damage)
     if( damagetype != DOT)
-    {
+	{
         RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
         RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
 
@@ -474,7 +474,7 @@
     if(!spellProto || spellProto->Mechanic != MECHANIC_ROOT)
         pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage);
 
-    if(pVictim->GetTypeId() != TYPEID_PLAYER)
+	if(pVictim->GetTypeId() != TYPEID_PLAYER)
     {
         //pVictim->SetInFront(this);
         // no xp,health if type 8 /critters/
@@ -9623,11 +9623,6 @@
 
     // send explicit stop packet
     SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(),0, GetUnitMovementFlags(), 0);
-
-    // update position and orientation;
-    WorldPacket data;
-    BuildHeartBeatMsg(&data);
-    SendMessageToSet(&data,false);
 }
 
 bool Unit::IsStandState() const
Index: src/game/WaypointMovementGenerator.cpp
===================================================================
--- src/game/WaypointMovementGenerator.cpp	(revision 5687)
+++ src/game/WaypointMovementGenerator.cpp	(working copy)
@@ -16,295 +16,396 @@
  * 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 `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';
-
-*/
-
+//Basic header
 #include <ctime>
 
 #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 "MapManager.h"
+#include "CreatureAI.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 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");
+	wpdata.clear();
+}
+
+void WaypointStore::Load()
+{
+    QueryResult *result = WorldDatabase.PQuery("SELECT MAX(`id`) FROM `waypoint_data");
+    if(!result)
+    {
+        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
     }
-    */
 
-    if( result )
+	records = (*result)[0].GetUInt32();
+    delete result;
+
+
+	result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`move_flag`,`delay`,`event_id`,`event_chance` FROM `waypoint_data` ORDER BY `id`, `point`");
+    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.outErrorDb("The table `creature_addon` is empty or corrupted");
+        return;
+    }
 
-        do
-        {
-            //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();
+    WaypointPath* path_data;
+    uint32 total_records = result->GetRowCount();
 
-            if( (emote != 0) || (spell != 0)
-                || !text1.empty() || !text2.empty() || !text3.empty() || !text4.empty() || !text5.empty()
-                || (model1 != 0)  || (model2 != 0) || (orientation != 100))
-            {
-                WaypointBehavior *tmpWPB = new WaypointBehavior;
+	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 && id != 0)
+			path_data = new WaypointPath;
+		
+		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->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();
+        
+		path_data->push_back(wp);
+	
+	if(id != last_id)	
+		wpdata[id] = path_data;
+		
+		last_id = id;
 
-            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
-                    );
+    } while(result->NextRow()) ;
 
-                // 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;
+    delete result;
+}
 
-        } while( result->NextRow() );
+void WaypointStore::UpdatePath(uint32 id)
+{
+	
+	if(wpdata.find(id)!= wpdata.end())
+		wpdata[id]->clear();
+	
+	QueryResult *result;
 
-        delete result;
+    result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`move_flag`,`delay`,`event_id`,`event_chance` FROM `waypoint_data` WHERE id = %u ORDER BY `point`", id);
+    
+	if(!result)
+		return;
+    
+	WaypointPath* path_data;
+	
+	path_data = new WaypointPath;
+	
+	Field *fields;
+	
+	do
+    {
+		fields = result->Fetch();
+        uint32 id = fields[0].GetUInt32();
+        
+        WaypointData *wp = new WaypointData;
 
-        assert( sz == count );
-    }
+		float x,y,z;
+        x = fields[2].GetFloat();
+        y = fields[3].GetFloat();
+        z = fields[4].GetFloat();
+
+        MaNGOS::NormalizeMapCoord(x);
+        MaNGOS::NormalizeMapCoord(y);
+
+        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();
+     
+		path_data->push_back(wp);
+
+	}while (result->NextRow());
+ 
+wpdata[id] = path_data;
+
+delete result;
 }
 
+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); 
+	m_ActiveCreatureMap[u.GetGUID()] = &u;
 }
 
 void
-WaypointMovementGenerator<Creature>::Initialize()
+WaypointMovementGenerator<Creature>::Finalize(Creature &u)
 {
-    QueryResult *result = WorldDatabase.Query("SELECT distinct(id) as uniqueid FROM creature_movement");
+	WaypointMovementGenerator<T>::ActiveCreatureList::iterator itr = m_ActiveCreatureMap.find(u.GetGUID());
+            if (itr != m_ActiveCreatureMap.end())
+                m_ActiveCreatureMap.erase(itr);
+}
 
-    if( result )
-    {
-        do
-        {
-            Field *fields = result->Fetch();
-            si_waypointHolders.insert( fields[0].GetUInt32() );
-        }
-        while( result->NextRow() );
+void
+WaypointMovementGenerator<Player>::Finalize(Player &u)
+{
 
-        delete result;
-    }
 }
 
+
+template<class T>
+void
+WaypointMovementGenerator<T>::Reset(T &u)
+{
+    u.StopMoving();
+    
+    float x,y,z;
+    i_destinationHolder.GetLocationNow(x,y,z);
+
+
+    Traveller<T> traveller(u);
+    i_destinationHolder.GetDestination(x,y,z);
+    i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+}
+
+template<class T>
+void
+WaypointMovementGenerator<T>::GeneratePathId(T &unit)
+{
+    path_id = 0;
+}
+
+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
+}
+
+void
+WaypointMovementGenerator<Creature>::SetMoveFlag(Creature &unit,bool flag)
+{
+	unit.SetUnitMovementFlag(flag);   
+}
+
+template<class T>
+void
+WaypointMovementGenerator<T>::MovementInform(T &unit)
+{
+	
+}
+
+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)
+    if(!&unit)
         return true;
 
     // 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())
-    {
+    // Clear the generator if the path doesn't exist
+    if(!waypoints || !waypoints->size())
         return true;
-    }
 
-    CreatureTraveller traveller(creature);
+	if(((Creature*)&unit)->IsStoppedByEvent())
+		return true;
+	
+	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( i_nextMoveTime.Passed() )
+	{
+        if( unit.IsStopped() )
+		{
+            if(i_currentNode == waypoints->size() - 1) //If that's our last waypoint
             {
-                if(tmpBehavior->emote != 0)
-                {
-                    creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,tmpBehavior->emote);
-                }
-                //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;
+					MovementInform(unit);
+				
+				if(repeating) //If the movement is repeating
+                    i_currentNode = 0; //Start moving all over again
+                else
+                    return false; //Clear the waypoint movement
 
-                        //sLog.outDebug("DEBUG: tmpBehavior->text[i] == \"\": %d", i);
-                        //sLog.outDebug("DEBUG: rand() % (i): %d", rand() % (i));
+            }
+            else 
+				i_currentNode++;
 
-                        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.SetDisplayId(tmpBehavior->model1);
-                }
-                tmpBehavior->HasDone = true;
-                MovementInform(creature);
-            }                                               // HasDone == false
-        }                                                   // wpBehaviour found
-    }                                                       // i_creature.IsStopped()
-
-    if( i_nextMoveTime.Passed() )
-    {
-        if( creature.IsStopped() )
+			ExecuteScript = false;
+			WaypointData* nextWP = *(waypoints->begin()+i_currentNode);
+            SetMoveFlag(unit, nextWP->run);
+            unit.addUnitState(UNIT_STAT_ROAMING);
+            
+			if(((Creature*)&unit)->IsFollower())
+			{			
+				
+			uint32 guid = ((Creature*)&unit)->GetCreatureFormation()->leader;
+			uint32 entry = objmgr.GetCreatureData(guid)->id;	
+			
+			Creature* Leader = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, entry, HIGHGUID_UNIT), (Creature*)NULL);
+			
+				if(Leader)
+				{
+				dist = ((Creature*)&unit)->GetCreatureFormation()->offset_dist;
+				offset = ((Creature*)&unit)->GetCreatureFormation()->offset_angle;
+				
+					if(dist && offset)
+					{
+					Map const* map = MapManager::Instance().GetBaseMap(unit.GetMapId());
+					float x,y,z,pathangle;
+					pathangle = atan2(Leader->GetPositionY()-nextWP->y,Leader->GetPositionX()-nextWP->x);
+				
+					x = nextWP->x+cos(offset+pathangle)*dist;
+					y = nextWP->y+sin(offset+pathangle)*dist;
+					z = map->GetHeight(x,y,nextWP->z, false);                      // use .map base surface height
+					i_destinationHolder.SetDestination(traveller, x, y, z);
+					((Creature*)&unit)->SetCoordsBeforeBattle(x,y,z);
+					Leader->SetLinkedtoFormation(true);
+					}
+				}	
+			}
+			else 
+			{
+				i_destinationHolder.SetDestination(traveller, nextWP->x, nextWP->y, nextWP->z);
+				((Creature*)&unit)->SetCoordsBeforeBattle( nextWP->x, nextWP->y, nextWP->z);
+			}
+				i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+		}
+		else
         {
-            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 )
-            {
-                struct WaypointBehavior *tmpBehavior = i_wpBehaviour[wpB];
-                tmpBehavior->HasDone = false;
-                if(tmpBehavior->model2 != 0)
-                {
-                    creature.SetDisplayId(tmpBehavior->model2);
-                }
-                if (tmpBehavior->orientation !=100)
-                {
-                    creature.SetOrientation(tmpBehavior->orientation);
-                }
-                creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
-            }
-        }
-        else
-        {
-            creature.StopMoving();
-            i_nextMoveTime.Reset(i_delays[i_currentNode]);
-            ++i_currentNode;
-            if( i_currentNode >= i_path.Size() )
-                i_currentNode = 0;
-        }
-    }
-    return true;
+			WaypointData* wp = *(waypoints->begin()+i_currentNode);
+            
+			//Determine waittime 
+			if(wp->delay)
+				i_nextMoveTime.Reset(wp->delay);
+			else 
+				i_nextMoveTime.Reset(200); //Prevents some lag
+			
+			if(wp->event_id && rand()%100 < wp->event_chance && !ExecuteScript)
+			{
+				sWorld.ScriptsStart(sWaypointScripts, wp->event_id, &unit, NULL);
+				ExecuteScript = true;	
+			}
+		
+			((Creature*)&unit)->UpdateWaypointID(i_currentNode);
+		
+			if(!((Creature*)&unit)->IsFollower())
+			{
+				if(!((Creature*)&unit)->isLinkedtoFormation())
+					((Creature*)&unit)->clearUnitState(UNIT_STAT_MOVING);
+			
+			}		
+			else
+			{
+				uint32 guid = ((Creature*)&unit)->GetCreatureFormation()->leader;
+				uint32 entry = objmgr.GetCreatureData(guid)->id;	
+			
+				Creature* Leader = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, entry, HIGHGUID_UNIT), (Creature*)NULL);
+			
+				if(Leader)
+				{
+					if(((Creature*)&unit)->GetCurrentWaypointID() == Leader->GetCurrentWaypointID())	
+					{
+					((Creature*)&unit)->clearUnitState(UNIT_STAT_MOVING);	
+					Leader->SetLinkedtoFormation(false);
+					}
+					else if(((Creature*)&unit)->GetCurrentWaypointID() == Leader->GetCurrentWaypointID()-1)
+							if(Leader->isLinkedtoFormation())
+							{
+								((Creature*)&unit)->clearUnitState(UNIT_STAT_MOVING);
+							}
+				}
+			}
+		}
+    } 
+	return true;
 }
 
-void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
-{
-    if(unit.AI())
-        unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
-}
+template <class T> HM_NAMESPACE::hash_map< uint64, T* > WaypointMovementGenerator<T>::m_ActiveCreatureMap;
 
-std::set<uint32> WaypointMovementGenerator<Creature>::si_waypointHolders;
+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);
 
 //----------------------------------------------------//
 void
Index: src/game/WaypointMovementGenerator.h
===================================================================
--- src/game/WaypointMovementGenerator.h	(revision 5687)
+++ 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,31 +25,57 @@
  * packets for the players.
  */
 
+class Player;
+
+//Movement classes
 #include "MovementGenerator.h"
 #include "DestinationHolder.h"
 #include "Path.h"
 #include "Traveller.h"
+#include "FollowerReference.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;
-    bool HasDone;
+	uint32 id;
+    float x,y,z;
+    bool run;
+    uint32 delay;
+    uint32 event_id;
+    uint8 event_chance;
 };
 
+typedef std::vector<WaypointData*> WaypointPath;
+typedef HM_NAMESPACE::hash_map<uint32, WaypointPath*> waypoint_map;
+
+WaypointData* CreateWaypoint(uint32 id, float x, float y, float z, bool run, uint32 delay, uint32 event_id, uint8 event_chance);
+
+class WaypointStore
+{
+    private :
+        waypoint_map wpdata;
+        uint32	records;
+			
+	public:
+        void UpdatePath(uint32 id);
+		void Load();
+        void Free();
+        
+        WaypointPath* GetPath(uint32 id)
+        {
+			if(wpdata.find(id) != wpdata.end())
+                return wpdata[id];
+			else return 0;
+		}
+		
+		inline uint32 GetRecordsCount() { return records; }
+};
+
+extern WaypointStore sWaypointStore;
+
 template<class T>
 class MANGOS_DLL_SPEC PathMovementBase
 {
@@ -59,67 +85,78 @@
 
         inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
 
-        // template pattern, not defined .. override required
         void LoadPath(T &);
         void ReloadPath(T &);
         uint32 GetCurrentNode() const { 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>
-class MANGOS_DLL_SPEC WaypointMovementGenerator;
 
-template<>
-class MANGOS_DLL_SPEC 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 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() 
+		{
+            if(custom_path)
+            {
+                for(WaypointPath::iterator itr = waypoints->begin(); itr!= waypoints->end();)
+                {
+                    delete (*itr);
+                    itr = waypoints->erase(itr);
+                }
+                delete waypoints;
+            }
+        }
+		typedef HM_NAMESPACE::hash_map< uint64, T* >   ActiveCreatureList;
+		
+		void Initialize(T &);
+        void Finalize(T &);
+		static ActiveCreatureList& GetContainer(){return m_ActiveCreatureMap;}
+
+		void UseCustomPath(uint32 custom_id, WaypointPath *data)
         {
-            i_nextMoveTime.Reset(0);                        // TODO: check the lower bound (0 is probably too small)
-            u.StopMoving();
-            LoadPath(u);
+            cucstom_path = true;
+            path_id = custom_id;
+            waypoints = data;
         }
-        void Finalize(Creature &) {}
-        void Reset(Creature &u) { ReloadPath(u); }
-        bool Update(Creature &u, const uint32 &diff);
 
-        void MovementInform(Creature &);
+        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, ExecuteScript;
+		float offset;
+		float dist;
+		static ActiveCreatureList m_ActiveCreatureMap;
+	};
 
 /** FlightPathMovementGenerator generates movement of the player for the paths
  * and hence generates ground and activities for the player.
  */
+
 class MANGOS_DLL_SPEC FlightPathMovementGenerator
-: public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
-public PathMovementBase<Player>
+    : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, 
+      public PathMovementBase<Player>
 {
     uint32 i_pathId;
     std::vector<uint32> i_mapIds;
@@ -142,4 +179,5 @@
         void SetCurrentNodeAfterTeleport();
         void SkipCurrentNode() { ++i_currentNode; }
 };
+
 #endif
Index: src/game/World.cpp
===================================================================
--- src/game/World.cpp	(revision 5687)
+++ src/game/World.cpp	(working copy)
@@ -790,7 +790,13 @@
     sLog.outString( "Loading BattleMasters..." );
     objmgr.LoadBattleMastersEntry();
 
-    ///- Handle outdated emails (delete/return)
+    sLog.outString( "Loading Waypoint Data..." );
+    objmgr.LoadWaypointData();
+
+    sLog.outString( "Loading Creature Formations..." );
+	objmgr.LoadCreatureFormations();
+	
+	///- Handle outdated emails (delete/return)
     sLog.outString( "Returning old mails..." );
     objmgr.ReturnOrDeleteOldMails(false);
 
@@ -801,6 +807,7 @@
     objmgr.LoadSpellScripts();                              // must be after load Creature/Gameobject(Template/Data)
     objmgr.LoadGameObjectScripts();                         // must be after load Creature/Gameobject(Template/Data)
     objmgr.LoadEventScripts();                              // must be after load Creature/Gameobject(Template/Data)
+    objmgr.LoadWaypointScripts();
 
     sLog.outString( "Initializing Scripts..." );
     if(!LoadScriptingModule())
@@ -839,7 +846,6 @@
 
     ///- Initilize static helper structures
     AIRegistry::Initialize();
-    WaypointMovementGenerator<Creature>::Initialize();
     Player::InitVisibleBits();
     RedZone::Initialize();
 
@@ -1177,7 +1183,7 @@
                     sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
                     break;
                 }
-                if(step.script->datalong > 2)
+                if(step.script->datalong > 3)
                 {
                     sLog.outError("SCRIPT_COMMAND_TALK invalid chat type (%u), skipping.",step.script->datalong);
                     break;
@@ -1185,7 +1191,7 @@
 
                 uint64 unit_target = target!=NULL ? target->GetGUID() : 0;
 
-                //datalong 0=normal say, datalong 1=whisper, datalong 2=yell
+                //datalong 0=normal say, datalong 1=whisper, datalong 2=yell, datalong 3=textemote
                 switch(step.script->datalong)
                 {
                     case 0:                                 // SAY
@@ -1202,7 +1208,11 @@
                     case 2:                                 // YELL
                         ((Creature *)source)->Yell(step.script->datatext.c_str(), 0, unit_target);
                         break;
-                    default:
+                    case 3:                                 // TEXTEMOTE
+						((Creature *)source)->TextEmote(step.script->datatext.c_str(),0);
+                        break;
+					
+					default:
                         break;                              // must be already checked at load
                 }
                 break;
@@ -1580,8 +1590,28 @@
 
                 break;
             }
+			case SCRIPT_START_PATH:
+				{
+				if(!source)
+                {
+                    sLog.outError("SCRIPT_COMMAND_EMOTE call for NULL creature.");
+                    break;
+                }
 
-            default:
+                if(source->GetTypeId()!=TYPEID_UNIT)
+                {
+                    sLog.outError("SCRIPT_COMMAND_EMOTE call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
+                    break;
+                }
+				
+				((Creature*)source)->LoadPath(step.script->datalong);
+				((Creature*)source)->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+				((Creature*)source)->GetMotionMaster()->Initialize();
+				
+				break;
+				}
+			
+			default:
                 sLog.outError("Unknown script command %u called.",step.script->command);
                 break;
         }
Index: src/game/World.h
===================================================================
--- src/game/World.h	(revision 5687)
+++ src/game/World.h	(working copy)
@@ -203,7 +203,7 @@
 #define SCRIPT_COMMAND_TEMP_SUMMON_CREATURE 10
 #define SCRIPT_COMMAND_OPEN_DOOR            11
 #define SCRIPT_COMMAND_CLOSE_DOOR           12
-
+#define SCRIPT_START_PATH					14
 /// CLI related stuff, define here to prevent cyclic dependancies
 
 typedef int(* pPrintf)(const char*,...);
Index: src/shared/Database/SQLStorage.cpp
===================================================================
--- src/shared/Database/SQLStorage.cpp	(revision 5687)
+++ src/shared/Database/SQLStorage.cpp	(working copy)
@@ -28,9 +28,10 @@
 #endif
 
 const char CreatureInfofmt[]="iiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiliiiiiiiiiiiiiiiisiilliis";
-const char CreatureDataAddonInfofmt[]="iiiiiis";
+const char CreatureDataAddonInfofmt[]="iiiiiiis";
+const char CreatureDataFormationInfofmt[]="iiff";
 const char CreatureModelfmt[]="iffii";
-const char CreatureInfoAddonInfofmt[]="iiiiiis";
+const char CreatureInfoAddonInfofmt[]="iiiiiiis";
 const char EquipmentInfofmt[]="iiiiiiiiii";
 const char GameObjectInfofmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";
 const char ItemPrototypefmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii";
@@ -40,6 +41,7 @@
 
 SQLStorage sCreatureStorage(CreatureInfofmt,"entry","creature_template");
 SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
+SQLStorage sCreatureFormation(CreatureDataFormationInfofmt,"follower","creature_formations");
 SQLStorage sCreatureModelStorage(CreatureModelfmt,"modelid","creature_model_info");
 SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_template_addon");
 SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template");
Index: win/VC90/game.vcproj
===================================================================
--- win/VC90/game.vcproj	(revision 5687)
+++ win/VC90/game.vcproj	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9.00"
+	Version="9,00"
 	Name="game"
 	ProjectGUID="{1DC6C4DA-A028-41F3-877D-D5400C594F88}"
 	RootNamespace="game"