root/trunk/src/game/Level2.cpp @ 149

Revision 149, 121.5 kB (checked in by yumileroy, 17 years ago)

[svn] *Implement new player conditions CONDITION_NO_AURA, CONDITION_ACTIVE_EVENT
* Default behaviour of pets for creatures changed to REACT_DEFENSIVE
* Disallowed sending wrapped items as COD
* Prevent loading and saving single target auras for pet in same way as already implemented for player
* Correctly limit use some flask types to zones.
* Fixed extracting common.MPQ under *nix
* Many small xleanups and fixes.
** mangos merge rev.

TEST REV so be careful of creepy crawly bugs!

Original author: KingPin?
Date: 2008-11-02 16:53:46-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Common.h"
22#include "Database/DatabaseEnv.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "World.h"
26#include "ObjectMgr.h"
27#include "Player.h"
28#include "Item.h"
29#include "GameObject.h"
30#include "Opcodes.h"
31#include "Chat.h"
32#include "ObjectAccessor.h"
33#include "MapManager.h"
34#include "Language.h"
35#include "World.h"
36#include "GameEvent.h"
37#include "SpellMgr.h"
38#include "AccountMgr.h"
39#include "WaypointManager.h"
40#include "Util.h"
41#include <cctype>
42#include <iostream>
43#include <fstream>
44#include <map>
45#include "GlobalEvents.h"
46
47#include "TargetedMovementGenerator.h"                      // for HandleNpcUnFollowCommand
48
49static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
50{
51    LANG_REP_HATED,    LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL,
52    LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED,    LANG_REP_EXALTED
53};
54
55//mute player for some times
56bool ChatHandler::HandleMuteCommand(const char* args)
57{
58    if (!*args)
59        return false;
60
61    char *charname = strtok((char*)args, " ");
62    if (!charname)
63        return false;
64
65    std::string cname = charname;
66
67    char *timetonotspeak = strtok(NULL, " ");
68    if(!timetonotspeak)
69        return false;
70
71    uint32 notspeaktime = (uint32) atoi(timetonotspeak);
72
73    if(!normalizePlayerName(cname))
74    {
75        SendSysMessage(LANG_PLAYER_NOT_FOUND);
76        SetSentErrorMessage(true);
77        return false;
78    }
79
80    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
81    if(!guid)
82    {
83        SendSysMessage(LANG_PLAYER_NOT_FOUND);
84        SetSentErrorMessage(true);
85        return false;
86    }
87
88    Player *chr = objmgr.GetPlayer(guid);
89
90    // check security
91    uint32 account_id = 0;
92    uint32 security = 0;
93
94    if (chr)
95    {
96        account_id = chr->GetSession()->GetAccountId();
97        security = chr->GetSession()->GetSecurity();
98    }
99    else
100    {
101        account_id = objmgr.GetPlayerAccountIdByGUID(guid);
102        security = accmgr.GetSecurity(account_id);
103    }
104
105    if(m_session && security >= m_session->GetSecurity())
106    {
107        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
108        SetSentErrorMessage(true);
109        return false;
110    }
111
112    time_t mutetime = time(NULL) + notspeaktime*60;
113
114    if (chr)
115        chr->GetSession()->m_muteTime = mutetime;
116
117    loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
118
119    if(chr)
120        ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
121
122    PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
123
124    return true;
125}
126
127//unmute player
128bool ChatHandler::HandleUnmuteCommand(const char* args)
129{
130    if (!*args)
131        return false;
132
133    char *charname = strtok((char*)args, " ");
134    if (!charname)
135        return false;
136
137    std::string cname = charname;
138
139    if(!normalizePlayerName(cname))
140    {
141        SendSysMessage(LANG_PLAYER_NOT_FOUND);
142        SetSentErrorMessage(true);
143        return false;
144    }
145
146    uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
147    if(!guid)
148    {
149        SendSysMessage(LANG_PLAYER_NOT_FOUND);
150        SetSentErrorMessage(true);
151        return false;
152    }
153
154    Player *chr = objmgr.GetPlayer(guid);
155
156    // check security
157    uint32 account_id = 0;
158    uint32 security = 0;
159
160    if (chr)
161    {
162        account_id = chr->GetSession()->GetAccountId();
163        security = chr->GetSession()->GetSecurity();
164    }
165    else
166    {
167        account_id = objmgr.GetPlayerAccountIdByGUID(guid);
168        security = accmgr.GetSecurity(account_id);
169    }
170
171    if(m_session && security >= m_session->GetSecurity())
172    {
173        SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
174        SetSentErrorMessage(true);
175        return false;
176    }
177
178    if (chr)
179    {
180        if(chr->CanSpeak())
181        {
182            SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
183            SetSentErrorMessage(true);
184            return false;
185        }
186
187        chr->GetSession()->m_muteTime = 0;
188    }
189
190    loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
191
192    if(chr)
193        ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
194
195    PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
196    return true;
197}
198
199bool ChatHandler::HandleTargetObjectCommand(const char* args)
200{
201    Player* pl = m_session->GetPlayer();
202    QueryResult *result;
203    GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
204    if(*args)
205    {
206        int32 id = atoi((char*)args);
207        if(id)
208            result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1",
209                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
210        else
211        {
212            std::string name = args;
213            WorldDatabase.escape_string(name);
214            result = WorldDatabase.PQuery(
215                "SELECT guid, id, position_x, position_y, position_z, orientation, map, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
216                "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
217                pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
218        }
219    }
220    else
221    {
222        std::ostringstream eventFilter;
223        eventFilter << " AND (event IS NULL ";
224        bool initString = true;
225
226        for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
227        {
228            if (initString)
229            {
230                eventFilter  <<  "OR event IN (" <<*itr;
231                initString =false;
232            }
233            else
234                eventFilter << "," << *itr;
235        }
236
237        if (!initString)
238            eventFilter << "))";
239        else
240            eventFilter << ")";
241
242        result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
243            "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
244            "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
245            m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
246    }
247
248    if (!result)
249    {
250        SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
251        return true;
252    }
253
254    Field *fields = result->Fetch();
255    uint32 lowguid = fields[0].GetUInt32();
256    uint32 id = fields[1].GetUInt32();
257    float x = fields[2].GetFloat();
258    float y = fields[3].GetFloat();
259    float z = fields[4].GetFloat();
260    float o = fields[5].GetFloat();
261    int mapid = fields[6].GetUInt16();
262    delete result;
263
264    GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
265
266    if (!goI)
267    {
268        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
269        return false;
270    }
271
272    GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
273
274    PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
275
276    if(target)
277    {
278        int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
279        if(curRespawnDelay < 0)
280            curRespawnDelay = 0;
281
282        std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
283        std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
284
285        PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
286    }
287    return true;
288}
289
290//teleport to gameobject
291bool ChatHandler::HandleGoObjectCommand(const char* args)
292{
293    if(!*args)
294        return false;
295
296    Player* _player = m_session->GetPlayer();
297
298    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
299    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
300    if(!cId)
301        return false;
302
303    int32 guid = atoi(cId);
304    if(!guid)
305        return false;
306
307    float x, y, z, ort;
308    int mapid;
309
310    // by DB guid
311    if (GameObjectData const* go_data = objmgr.GetGOData(guid))
312    {
313        x = go_data->posX;
314        y = go_data->posY;
315        z = go_data->posZ;
316        ort = go_data->orientation;
317        mapid = go_data->mapid;
318    }
319    else
320    {
321        SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
322        SetSentErrorMessage(true);
323        return false;
324    }
325
326    if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
327    {
328        PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
329        SetSentErrorMessage(true);
330        return false;
331    }
332
333    // stop flight if need
334    if(_player->isInFlight())
335    {
336        _player->GetMotionMaster()->MovementExpired();
337        _player->m_taxi.ClearTaxiDestinations();
338    }
339    // save only in non-flight case
340    else
341        _player->SaveRecallPosition();
342
343    _player->TeleportTo(mapid, x, y, z, ort);
344    return true;
345}
346
347bool ChatHandler::HandleGoTriggerCommand(const char* args)
348{
349    Player* _player = m_session->GetPlayer();
350
351    if (!*args)
352        return false;
353
354    char *atId = strtok((char*)args, " ");
355    if (!atId)
356        return false;
357
358    int32 i_atId = atoi(atId);
359
360    if(!i_atId)
361        return false;
362
363    AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
364    if (!at)
365    {
366        PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
367        SetSentErrorMessage(true);
368        return false;
369    }
370
371    if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
372    {
373        PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
374        SetSentErrorMessage(true);
375        return false;
376    }
377
378    // stop flight if need
379    if(_player->isInFlight())
380    {
381        _player->GetMotionMaster()->MovementExpired();
382        _player->m_taxi.ClearTaxiDestinations();
383    }
384    // save only in non-flight case
385    else
386        _player->SaveRecallPosition();
387
388    _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
389    return true;
390}
391
392bool ChatHandler::HandleGoGraveyardCommand(const char* args)
393{
394    Player* _player = m_session->GetPlayer();
395
396    if (!*args)
397        return false;
398
399    char *gyId = strtok((char*)args, " ");
400    if (!gyId)
401        return false;
402
403    int32 i_gyId = atoi(gyId);
404
405    if(!i_gyId)
406        return false;
407
408    WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
409    if (!gy)
410    {
411        PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
412        SetSentErrorMessage(true);
413        return false;
414    }
415
416    if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
417    {
418        PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
419        SetSentErrorMessage(true);
420        return false;
421    }
422
423    // stop flight if need
424    if(_player->isInFlight())
425    {
426        _player->GetMotionMaster()->MovementExpired();
427        _player->m_taxi.ClearTaxiDestinations();
428    }
429    // save only in non-flight case
430    else
431        _player->SaveRecallPosition();
432
433    _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
434    return true;
435}
436
437/** \brief Teleport the GM to the specified creature
438 *
439 * .gocreature <GUID>      --> TP using creature.guid
440 * .gocreature azuregos    --> TP player to the mob with this name
441 *                             Warning: If there is more than one mob with this name
442 *                                      you will be teleported to the first one that is found.
443 * .gocreature id 6109     --> TP player to the mob, that has this creature_template.entry
444 *                             Warning: If there is more than one mob with this "id"
445 *                                      you will be teleported to the first one that is found.
446 */
447//teleport to creature
448bool ChatHandler::HandleGoCreatureCommand(const char* args)
449{
450    if(!*args)
451        return false;
452    Player* _player = m_session->GetPlayer();
453
454    // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
455    char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
456    if (!pParam1)
457        return false;
458
459    std::ostringstream whereClause;
460
461    // User wants to teleport to the NPC's template entry
462    if( strcmp(pParam1, "id") == 0 )
463    {
464        //sLog.outError("DEBUG: ID found");
465
466        // Get the "creature_template.entry"
467        // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
468        char* tail = strtok(NULL,"");
469        if(!tail)
470            return false;
471        char* cId = extractKeyFromLink(tail,"Hcreature_entry");
472        if(!cId)
473            return false;
474
475        int32 tEntry = atoi(cId);
476        //sLog.outError("DEBUG: ID value: %d", tEntry);
477        if(!tEntry)
478            return false;
479
480        whereClause << "WHERE id = '" << tEntry << "'";
481    }
482    else
483    {
484        //sLog.outError("DEBUG: ID *not found*");
485
486        int32 guid = atoi(pParam1);
487
488        // Number is invalid - maybe the user specified the mob's name
489        if(!guid)
490        {
491            std::string name = pParam1;
492            WorldDatabase.escape_string(name);
493            whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
494        }
495        else
496        {
497            whereClause <<  "WHERE guid = '" << guid << "'";
498        }
499    }
500    //sLog.outError("DEBUG: %s", whereClause.c_str());
501
502    QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
503    if (!result)
504    {
505        SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
506        SetSentErrorMessage(true);
507        return false;
508    }
509    if( result->GetRowCount() > 1 )
510    {
511        SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
512    }
513
514    Field *fields = result->Fetch();
515    float x = fields[0].GetFloat();
516    float y = fields[1].GetFloat();
517    float z = fields[2].GetFloat();
518    float ort = fields[3].GetFloat();
519    int mapid = fields[4].GetUInt16();
520
521    delete result;
522
523    if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
524    {
525        PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
526        SetSentErrorMessage(true);
527        return false;
528    }
529
530    // stop flight if need
531    if(_player->isInFlight())
532    {
533        _player->GetMotionMaster()->MovementExpired();
534        _player->m_taxi.ClearTaxiDestinations();
535    }
536    // save only in non-flight case
537    else
538        _player->SaveRecallPosition();
539
540    _player->TeleportTo(mapid, x, y, z, ort);
541    return true;
542}
543
544bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
545{
546    uint64 guid = m_session->GetPlayer()->GetSelection();
547
548    if (guid == 0)
549    {
550        SendSysMessage(LANG_NO_SELECTION);
551        SetSentErrorMessage(true);
552        return false;
553    }
554
555    PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
556    return true;
557}
558
559bool ChatHandler::HandleLookupFactionCommand(const char* args)
560{
561    if (!*args)
562        return false;
563
564    // Can be NULL at console call
565        Player *target = getSelectedPlayer ();
566
567    std::string namepart = args;
568    std::wstring wnamepart;
569
570    if (!Utf8toWStr (namepart,wnamepart))
571        return false;
572
573    // converting string that we try to find to lower case
574    wstrToLower (wnamepart);
575
576    uint32 counter = 0;                                     // Counter for figure out that we found smth.
577
578    for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
579    {
580        FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
581        if (factionEntry)
582        {
583            FactionState const* repState = NULL;
584                        if(target)
585                        {
586                                FactionStateList::const_iterator repItr = target->m_factions.find (factionEntry->reputationListID);
587                                if(repItr != target->m_factions.end())
588                                        repState = &repItr->second;
589                        }
590
591            int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
592            std::string name = factionEntry->name[loc];
593            if(name.empty())
594                continue;
595
596            if (!Utf8FitTo(name, wnamepart))
597            {
598                loc = 0;
599                for(; loc < MAX_LOCALE; ++loc)
600                {
601                    if(m_session && loc==m_session->GetSessionDbcLocale())
602                        continue;
603
604                    name = factionEntry->name[loc];
605                    if(name.empty())
606                        continue;
607
608                    if (Utf8FitTo(name, wnamepart))
609                        break;
610                }
611            }
612
613            if(loc < MAX_LOCALE)
614            {
615                // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
616                // or              "id - [faction] [no reputation]" format
617                std::ostringstream ss;
618                if (m_session)
619                                        ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
620                                else
621                                        ss << id << " - " << name << " " << localeNames[loc];
622
623                if (repState)                               // and then target!=NULL also
624                {
625                    ReputationRank rank = target->GetReputationRank(factionEntry);
626                    std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
627
628                    ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
629
630                    if(repState->Flags & FACTION_FLAG_VISIBLE)
631                        ss << GetTrinityString(LANG_FACTION_VISIBLE);
632                    if(repState->Flags & FACTION_FLAG_AT_WAR)
633                        ss << GetTrinityString(LANG_FACTION_ATWAR);
634                    if(repState->Flags & FACTION_FLAG_PEACE_FORCED)
635                        ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
636                    if(repState->Flags & FACTION_FLAG_HIDDEN)
637                        ss << GetTrinityString(LANG_FACTION_HIDDEN);
638                    if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
639                        ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
640                    if(repState->Flags & FACTION_FLAG_INACTIVE)
641                        ss << GetTrinityString(LANG_FACTION_INACTIVE);
642                }
643                else
644                    ss << GetTrinityString(LANG_FACTION_NOREPUTATION);
645
646                SendSysMessage(ss.str().c_str());
647                counter++;
648            }
649        }
650    }
651
652    if (counter == 0)                                       // if counter == 0 then we found nth
653        SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
654    return true;
655}
656
657bool ChatHandler::HandleModifyRepCommand(const char * args)
658{
659    if (!*args) return false;
660
661    Player* target = NULL;
662    target = getSelectedPlayer();
663
664    if(!target)
665    {
666        SendSysMessage(LANG_PLAYER_NOT_FOUND);
667        SetSentErrorMessage(true);
668        return false;
669    }
670
671    char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
672    if(!factionTxt)
673        return false;
674
675    uint32 factionId = atoi(factionTxt);
676
677    int32 amount = 0;
678    char *rankTxt = strtok(NULL, " ");
679    if (!factionTxt || !rankTxt)
680        return false;
681
682    amount = atoi(rankTxt);
683    if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
684    {
685        std::string rankStr = rankTxt;
686        std::wstring wrankStr;
687        if(!Utf8toWStr(rankStr,wrankStr))
688            return false;
689        wstrToLower( wrankStr );
690
691        int r = 0;
692        amount = -42000;
693        for (; r < MAX_REPUTATION_RANK; ++r)
694        {
695            std::string rank = GetTrinityString(ReputationRankStrIndex[r]);
696            if(rank.empty())
697                continue;
698
699            std::wstring wrank;
700            if(!Utf8toWStr(rank,wrank))
701                continue;
702
703            wstrToLower(wrank);
704
705            if(wrank.substr(0,wrankStr.size())==wrankStr)
706            {
707                char *deltaTxt = strtok(NULL, " ");
708                if (deltaTxt)
709                {
710                    int32 delta = atoi(deltaTxt);
711                    if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1))
712                    {
713                        PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1));
714                        SetSentErrorMessage(true);
715                        return false;
716                    }
717                    amount += delta;
718                }
719                break;
720            }
721            amount += Player::ReputationRank_Length[r];
722        }
723        if (r >= MAX_REPUTATION_RANK)
724        {
725            PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
726            SetSentErrorMessage(true);
727            return false;
728        }
729    }
730
731    FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
732
733    if (!factionEntry)
734    {
735        PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
736        SetSentErrorMessage(true);
737        return false;
738    }
739
740    if (factionEntry->reputationListID < 0)
741    {
742        PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
743        SetSentErrorMessage(true);
744        return false;
745    }
746
747    target->SetFactionReputation(factionEntry,amount);
748    PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
749    return true;
750}
751
752bool ChatHandler::HandleNameCommand(const char* args)
753{
754    /* Temp. disabled
755        if(!*args)
756            return false;
757
758        if(strlen((char*)args)>75)
759        {
760            PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
761            return true;
762        }
763
764        for (uint8 i = 0; i < strlen(args); i++)
765        {
766            if(!isalpha(args[i]) && args[i]!=' ')
767            {
768                SendSysMessage(LANG_CHARS_ONLY);
769                return false;
770            }
771        }
772
773        uint64 guid;
774        guid = m_session->GetPlayer()->GetSelection();
775        if (guid == 0)
776        {
777            SendSysMessage(LANG_NO_SELECTION);
778            return true;
779        }
780
781        Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
782
783        if(!pCreature)
784        {
785            SendSysMessage(LANG_SELECT_CREATURE);
786            return true;
787        }
788
789        pCreature->SetName(args);
790        uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
791        pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
792
793        pCreature->SaveToDB();
794    */
795
796    return true;
797}
798
799bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
800{
801    /* Temp. disabled
802
803    if(!*args)
804        args = "";
805
806    if(strlen((char*)args)>75)
807    {
808
809        PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
810        return true;
811    }
812
813    for (uint8 i = 0; i < strlen(args); i++)
814    {
815        if(!isalpha(args[i]) && args[i]!=' ')
816        {
817            SendSysMessage(LANG_CHARS_ONLY);
818            return false;
819        }
820    }
821    uint64 guid;
822    guid = m_session->GetPlayer()->GetSelection();
823    if (guid == 0)
824    {
825        SendSysMessage(LANG_NO_SELECTION);
826        return true;
827    }
828
829    Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
830
831    if(!pCreature)
832    {
833        SendSysMessage(LANG_SELECT_CREATURE);
834        return true;
835    }
836
837    uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
838    pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
839
840    pCreature->SaveToDB();
841    */
842    return true;
843}
844
845//move item to other slot
846bool ChatHandler::HandleItemMoveCommand(const char* args)
847{
848    if(!*args)
849        return false;
850    uint8 srcslot, dstslot;
851
852    char* pParam1 = strtok((char*)args, " ");
853    if (!pParam1)
854        return false;
855
856    char* pParam2 = strtok(NULL, " ");
857    if (!pParam2)
858        return false;
859
860    srcslot = (uint8)atoi(pParam1);
861    dstslot = (uint8)atoi(pParam2);
862
863    uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
864    uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
865
866    if(srcslot==dstslot)
867        return true;
868
869    m_session->GetPlayer()->SwapItem( src, dst );
870
871    return true;
872}
873
874//add spawn of creature
875bool ChatHandler::HandleAddSpwCommand(const char* args)
876{
877    if(!*args)
878        return false;
879    char* charID = strtok((char*)args, " ");
880    if (!charID)
881        return false;
882
883    char* team = strtok(NULL, " ");
884    int32 teamval = 0;
885    if (team) { teamval = atoi(team); }
886    if (teamval < 0) { teamval = 0; }
887
888    uint32 id  = atoi(charID);
889
890    Player *chr = m_session->GetPlayer();
891    float x = chr->GetPositionX();
892    float y = chr->GetPositionY();
893    float z = chr->GetPositionZ();
894    float o = chr->GetOrientation();
895    Map *map = chr->GetMap();
896
897    Creature* pCreature = new Creature;
898    if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
899    {
900        delete pCreature;
901        return false;
902    }
903
904    pCreature->Relocate(x,y,z,o);
905
906    if(!pCreature->IsPositionValid())
907    {
908        sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
909        delete pCreature;
910        return false;
911    }
912
913    pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
914
915    uint32 db_guid = pCreature->GetDBTableGUIDLow();
916
917    // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
918    pCreature->LoadFromDB(db_guid, map);
919
920    map->Add(pCreature);
921    objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
922    return true;
923}
924
925bool ChatHandler::HandleDelCreatureCommand(const char* args)
926{
927    Creature* unit = NULL;
928
929    if(*args)
930    {
931        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
932        char* cId = extractKeyFromLink((char*)args,"Hcreature");
933        if(!cId)
934            return false;
935
936        uint32 lowguid = atoi(cId);
937        if(!lowguid)
938            return false;
939
940        if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
941            unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
942    }
943    else
944        unit = getSelectedCreature();
945
946    if(!unit || unit->isPet() || unit->isTotem())
947    {
948        SendSysMessage(LANG_SELECT_CREATURE);
949        SetSentErrorMessage(true);
950        return false;
951    }
952
953    // Delete the creature
954    unit->CombatStop();
955    unit->DeleteFromDB();
956    unit->CleanupsBeforeDelete();
957    unit->AddObjectToRemoveList();
958
959    SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
960
961    return true;
962}
963
964//delete object by selection or guid
965bool ChatHandler::HandleDelObjectCommand(const char* args)
966{
967    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
968    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
969    if(!cId)
970        return false;
971
972    uint32 lowguid = atoi(cId);
973    if(!lowguid)
974        return false;
975
976    GameObject* obj = NULL;
977
978    // by DB guid
979    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
980        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
981
982    if(!obj)
983    {
984        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
985        SetSentErrorMessage(true);
986        return false;
987    }
988
989    uint64 owner_guid = obj->GetOwnerGUID();
990    if(owner_guid)
991    {
992        Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
993        if(!owner && !IS_PLAYER_GUID(owner_guid))
994        {
995            PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
996            SetSentErrorMessage(true);
997            return false;
998        }
999
1000        owner->RemoveGameObject(obj,false);
1001    }
1002
1003    obj->SetRespawnTime(0);                                 // not save respawn time
1004    obj->Delete();
1005    obj->DeleteFromDB();
1006
1007    PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
1008
1009    return true;
1010}
1011
1012//turn selected object
1013bool ChatHandler::HandleTurnObjectCommand(const char* args)
1014{
1015    // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
1016    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
1017    if(!cId)
1018        return false;
1019
1020    uint32 lowguid = atoi(cId);
1021    if(!lowguid)
1022        return false;
1023
1024    GameObject* obj = NULL;
1025
1026    // by DB guid
1027    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
1028        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
1029
1030    if(!obj)
1031    {
1032        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
1033        SetSentErrorMessage(true);
1034        return false;
1035    }
1036
1037    char* po = strtok(NULL, " ");
1038    float o;
1039
1040    if (po)
1041    {
1042        o = (float)atof(po);
1043    }
1044    else
1045    {
1046        Player *chr = m_session->GetPlayer();
1047        o = chr->GetOrientation();
1048    }
1049
1050    float rot2 = sin(o/2);
1051    float rot3 = cos(o/2);
1052
1053    Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1054    map->Remove(obj,false);
1055
1056    obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
1057
1058    obj->SetFloatValue(GAMEOBJECT_FACING, o);
1059    obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
1060    obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
1061
1062    map->Add(obj);
1063
1064    obj->SaveToDB();
1065    obj->Refresh();
1066
1067    PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o);
1068
1069    return true;
1070}
1071
1072//move selected creature
1073bool ChatHandler::HandleMoveCreatureCommand(const char* args)
1074{
1075    uint32 lowguid = 0;
1076
1077    Creature* pCreature = getSelectedCreature();
1078
1079    if(!pCreature)
1080    {
1081        // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1082        char* cId = extractKeyFromLink((char*)args,"Hcreature");
1083        if(!cId)
1084            return false;
1085
1086        uint32 lowguid = atoi(cId);
1087
1088        /* FIXME: impossibel without entry
1089        if(lowguid)
1090            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1091        */
1092
1093        // Attempting creature load from DB data
1094        if(!pCreature)
1095        {
1096            CreatureData const* data = objmgr.GetCreatureData(lowguid);
1097            if(!data)
1098            {
1099                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1100                SetSentErrorMessage(true);
1101                return false;
1102            }
1103
1104            uint32 map_id = data->mapid;
1105
1106            if(m_session->GetPlayer()->GetMapId()!=map_id)
1107            {
1108                PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
1109                SetSentErrorMessage(true);
1110                return false;
1111            }
1112        }
1113        else
1114        {
1115            lowguid = pCreature->GetDBTableGUIDLow();
1116        }
1117    }
1118    else
1119    {
1120        lowguid = pCreature->GetDBTableGUIDLow();
1121    }
1122
1123    float x = m_session->GetPlayer()->GetPositionX();
1124    float y = m_session->GetPlayer()->GetPositionY();
1125    float z = m_session->GetPlayer()->GetPositionZ();
1126    float o = m_session->GetPlayer()->GetOrientation();
1127
1128    if (pCreature)
1129    {
1130        if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
1131        {
1132            const_cast<CreatureData*>(data)->posX = x;
1133            const_cast<CreatureData*>(data)->posY = y;
1134            const_cast<CreatureData*>(data)->posZ = z;
1135            const_cast<CreatureData*>(data)->orientation = o;
1136        }
1137        MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
1138        pCreature->GetMotionMaster()->Initialize();
1139        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1140        {
1141            pCreature->setDeathState(JUST_DIED);
1142            pCreature->Respawn();
1143        }
1144    }
1145
1146    WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
1147    PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
1148    return true;
1149}
1150
1151//move selected object
1152bool ChatHandler::HandleMoveObjectCommand(const char* args)
1153{
1154    // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1155    char* cId = extractKeyFromLink((char*)args,"Hgameobject");
1156    if(!cId)
1157        return false;
1158
1159    uint32 lowguid = atoi(cId);
1160    if(!lowguid)
1161        return false;
1162
1163    GameObject* obj = NULL;
1164
1165    // by DB guid
1166    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
1167        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
1168
1169    if(!obj)
1170    {
1171        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
1172        SetSentErrorMessage(true);
1173        return false;
1174    }
1175
1176    char* px = strtok(NULL, " ");
1177    char* py = strtok(NULL, " ");
1178    char* pz = strtok(NULL, " ");
1179
1180    if (!px)
1181    {
1182        Player *chr = m_session->GetPlayer();
1183
1184        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1185        map->Remove(obj,false);
1186
1187        obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
1188        obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
1189        obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
1190        obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
1191
1192        map->Add(obj);
1193    }
1194    else
1195    {
1196        if(!py || !pz)
1197            return false;
1198
1199        float x = (float)atof(px);
1200        float y = (float)atof(py);
1201        float z = (float)atof(pz);
1202
1203        if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
1204        {
1205            PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
1206            SetSentErrorMessage(true);
1207            return false;
1208        }
1209
1210        Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1211        map->Remove(obj,false);
1212
1213        obj->Relocate(x, y, z, obj->GetOrientation());
1214        obj->SetFloatValue(GAMEOBJECT_POS_X, x);
1215        obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
1216        obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
1217
1218        map->Add(obj);
1219    }
1220
1221    obj->SaveToDB();
1222    obj->Refresh();
1223
1224    PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
1225
1226    return true;
1227}
1228
1229//demorph player or unit
1230bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1231{
1232    Unit *target = getSelectedUnit();
1233    if(!target)
1234        target = m_session->GetPlayer();
1235
1236    target->DeMorph();
1237
1238    return true;
1239}
1240
1241//add item in vendorlist
1242bool ChatHandler::HandleAddVendorItemCommand(const char* args)
1243{
1244    if (!*args)
1245        return false;
1246
1247    char* pitem  = extractKeyFromLink((char*)args,"Hitem");
1248    if (!pitem)
1249    {
1250        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1251        SetSentErrorMessage(true);
1252        return false;
1253    }
1254
1255    uint32 itemId = atol(pitem);
1256
1257    char* fmaxcount = strtok(NULL, " ");                    //add maxcount, default: 0
1258    uint32 maxcount = 0;
1259    if (fmaxcount)
1260        maxcount = atol(fmaxcount);
1261
1262    char* fincrtime = strtok(NULL, " ");                    //add incrtime, default: 0
1263    uint32 incrtime = 0;
1264    if (fincrtime)
1265        incrtime = atol(fincrtime);
1266
1267    char* fextendedcost = strtok(NULL, " ");                //add ExtendedCost, default: 0
1268    uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
1269
1270    Creature* vendor = getSelectedCreature();
1271
1272    uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
1273
1274    if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
1275    {
1276        SetSentErrorMessage(true);
1277        return false;
1278    }
1279
1280    objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
1281
1282    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1283
1284    PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
1285    return true;
1286}
1287
1288//del item from vendor list
1289bool ChatHandler::HandleDelVendorItemCommand(const char* args)
1290{
1291    if (!*args)
1292        return false;
1293
1294    Creature* vendor = getSelectedCreature();
1295    if (!vendor || !vendor->isVendor())
1296    {
1297        SendSysMessage(LANG_COMMAND_VENDORSELECTION);
1298        SetSentErrorMessage(true);
1299        return false;
1300    }
1301
1302    char* pitem  = extractKeyFromLink((char*)args,"Hitem");
1303    if (!pitem)
1304    {
1305        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1306        SetSentErrorMessage(true);
1307        return false;
1308    }
1309    uint32 itemId = atol(pitem);
1310
1311
1312    if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
1313    {
1314        PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
1315        SetSentErrorMessage(true);
1316        return false;
1317    }
1318
1319    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1320
1321    PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
1322    return true;
1323}
1324
1325//add move for creature
1326bool ChatHandler::HandleAddMoveCommand(const char* args)
1327{
1328    if(!*args)
1329        return false;
1330
1331    char* guid_str = strtok((char*)args, " ");
1332    char* wait_str = strtok((char*)NULL, " ");
1333
1334    uint32 lowguid = atoi((char*)guid_str);
1335
1336    Creature* pCreature = NULL;
1337
1338    /* FIXME: impossible without entry
1339    if(lowguid)
1340        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1341    */
1342
1343    // attempt check creature existence by DB data
1344    if(!pCreature)
1345    {
1346        CreatureData const* data = objmgr.GetCreatureData(lowguid);
1347        if(!data)
1348        {
1349            PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1350            SetSentErrorMessage(true);
1351            return false;
1352        }
1353    }
1354    else
1355    {
1356        // obtain real GUID for DB operations
1357        lowguid = pCreature->GetDBTableGUIDLow();
1358    }
1359
1360    int wait = wait_str ? atoi(wait_str) : 0;
1361
1362    if(wait < 0)
1363        wait = 0;
1364
1365    Player* player = m_session->GetPlayer();
1366
1367    WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
1368
1369    // update movement type
1370    WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1371    if(pCreature)
1372    {
1373        pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1374        pCreature->GetMotionMaster()->Initialize();
1375        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1376        {
1377            pCreature->setDeathState(JUST_DIED);
1378            pCreature->Respawn();
1379        }
1380        pCreature->SaveToDB();
1381    }
1382
1383    SendSysMessage(LANG_WAYPOINT_ADDED);
1384
1385    return true;
1386}
1387
1388/**
1389 * Set the movement type for an NPC.<br/>
1390 * <br/>
1391 * Valid movement types are:
1392 * <ul>
1393 * <li> stay - NPC wont move </li>
1394 * <li> random - NPC will move randomly according to the spawndist </li>
1395 * <li> way - NPC will move with given waypoints set </li>
1396 * </ul>
1397 * additional parameter: NODEL - so no waypoints are deleted, if you
1398 *                       change the movement type
1399 */
1400bool ChatHandler::HandleSetMoveTypeCommand(const char* args)
1401{
1402    if(!*args)
1403        return false;
1404
1405    // 3 arguments:
1406    // GUID (optional - you can also select the creature)
1407    // stay|random|way (determines the kind of movement)
1408    // NODEL (optional - tells the system NOT to delete any waypoints)
1409    //        this is very handy if you want to do waypoints, that are
1410    //        later switched on/off according to special events (like escort
1411    //        quests, etc)
1412    char* guid_str = strtok((char*)args, " ");
1413    char* type_str = strtok((char*)NULL, " ");
1414    char* dontdel_str = strtok((char*)NULL, " ");
1415
1416    bool doNotDelete = false;
1417
1418    if(!guid_str)
1419        return false;
1420
1421    uint32 lowguid = 0;
1422    Creature* pCreature = NULL;
1423
1424    if( dontdel_str )
1425    {
1426        //sLog.outError("DEBUG: All 3 params are set");
1427
1428        // All 3 params are set
1429        // GUID
1430        // type
1431        // doNotDEL
1432        if( stricmp( dontdel_str, "NODEL" ) == 0 )
1433        {
1434            //sLog.outError("DEBUG: doNotDelete = true;");
1435            doNotDelete = true;
1436        }
1437    }
1438    else
1439    {
1440        // Only 2 params - but maybe NODEL is set
1441        if( type_str )
1442        {
1443            sLog.outError("DEBUG: Only 2 params ");
1444            if( stricmp( type_str, "NODEL" ) == 0 )
1445            {
1446                //sLog.outError("DEBUG: type_str, NODEL ");
1447                doNotDelete = true;
1448                type_str = NULL;
1449            }
1450        }
1451    }
1452
1453    if(!type_str)                                           // case .setmovetype $move_type (with selected creature)
1454    {
1455        type_str = guid_str;
1456        pCreature = getSelectedCreature();
1457        if(!pCreature || pCreature->isPet())
1458            return false;
1459        lowguid = pCreature->GetDBTableGUIDLow();
1460    }
1461    else                                                    // case .setmovetype #creature_guid $move_type (with selected creature)
1462    {
1463        lowguid = atoi((char*)guid_str);
1464
1465        /* impossible without entry
1466        if(lowguid)
1467            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1468        */
1469
1470        // attempt check creature existence by DB data
1471        if(!pCreature)
1472        {
1473            CreatureData const* data = objmgr.GetCreatureData(lowguid);
1474            if(!data)
1475            {
1476                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1477                SetSentErrorMessage(true);
1478                return false;
1479            }
1480        }
1481        else
1482        {
1483            lowguid = pCreature->GetDBTableGUIDLow();
1484        }
1485    }
1486
1487    // now lowguid is low guid really existed creature
1488    // and pCreature point (maybe) to this creature or NULL
1489
1490    MovementGeneratorType move_type;
1491
1492    std::string type = type_str;
1493
1494    if(type == "stay")
1495        move_type = IDLE_MOTION_TYPE;
1496    else if(type == "random")
1497        move_type = RANDOM_MOTION_TYPE;
1498    else if(type == "way")
1499        move_type = WAYPOINT_MOTION_TYPE;
1500    else
1501        return false;
1502
1503    // update movement type
1504    if(doNotDelete == false)
1505        WaypointMgr.DeletePath(lowguid);
1506
1507    if(pCreature)
1508    {
1509        pCreature->SetDefaultMovementType(move_type);
1510        pCreature->GetMotionMaster()->Initialize();
1511        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1512        {
1513            pCreature->setDeathState(JUST_DIED);
1514            pCreature->Respawn();
1515        }
1516        pCreature->SaveToDB();
1517    }
1518    if( doNotDelete == false )
1519    {
1520        PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1521    }
1522    else
1523    {
1524        PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1525    }
1526
1527    return true;
1528}                                                           // HandleSetMoveTypeCommand
1529
1530//change level of creature or pet
1531bool ChatHandler::HandleChangeLevelCommand(const char* args)
1532{
1533    if (!*args)
1534        return false;
1535
1536    uint8 lvl = (uint8) atoi((char*)args);
1537    if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1538    {
1539        SendSysMessage(LANG_BAD_VALUE);
1540        SetSentErrorMessage(true);
1541        return false;
1542    }
1543
1544    Creature* pCreature = getSelectedCreature();
1545    if(!pCreature)
1546    {
1547        SendSysMessage(LANG_SELECT_CREATURE);
1548        SetSentErrorMessage(true);
1549        return false;
1550    }
1551
1552    if(pCreature->isPet())
1553    {
1554        ((Pet*)pCreature)->GivePetLevel(lvl);
1555    }
1556    else
1557    {
1558        pCreature->SetMaxHealth( 100 + 30*lvl);
1559        pCreature->SetHealth( 100 + 30*lvl);
1560        pCreature->SetLevel( lvl);
1561        pCreature->SaveToDB();
1562    }
1563
1564    return true;
1565}
1566
1567//set npcflag of creature
1568bool ChatHandler::HandleNPCFlagCommand(const char* args)
1569{
1570    if (!*args)
1571        return false;
1572
1573    uint32 npcFlags = (uint32) atoi((char*)args);
1574
1575    Creature* pCreature = getSelectedCreature();
1576
1577    if(!pCreature)
1578    {
1579        SendSysMessage(LANG_SELECT_CREATURE);
1580        SetSentErrorMessage(true);
1581        return false;
1582    }
1583
1584    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1585
1586    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
1587
1588    SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1589
1590    return true;
1591}
1592
1593//set model of creature
1594bool ChatHandler::HandleSetModelCommand(const char* args)
1595{
1596    if (!*args)
1597        return false;
1598
1599    uint32 displayId = (uint32) atoi((char*)args);
1600
1601    Creature *pCreature = getSelectedCreature();
1602
1603    if(!pCreature || pCreature->isPet())
1604    {
1605        SendSysMessage(LANG_SELECT_CREATURE);
1606        SetSentErrorMessage(true);
1607        return false;
1608    }
1609
1610    pCreature->SetDisplayId(displayId);
1611    pCreature->SetNativeDisplayId(displayId);
1612
1613    pCreature->SaveToDB();
1614
1615    return true;
1616}
1617
1618//morph creature or player
1619bool ChatHandler::HandleMorphCommand(const char* args)
1620{
1621    if (!*args)
1622        return false;
1623
1624    uint16 display_id = (uint16)atoi((char*)args);
1625
1626    Unit *target = getSelectedUnit();
1627    if(!target)
1628        target = m_session->GetPlayer();
1629
1630    target->SetDisplayId(display_id);
1631
1632    return true;
1633}
1634
1635//set faction of creature  or go
1636bool ChatHandler::HandleFactionIdCommand(const char* args)
1637{
1638    if (!*args)
1639        return false;
1640
1641    uint32 factionId = (uint32) atoi((char*)args);
1642
1643    if (!sFactionTemplateStore.LookupEntry(factionId))
1644    {
1645        PSendSysMessage(LANG_WRONG_FACTION, factionId);
1646        SetSentErrorMessage(true);
1647        return false;
1648    }
1649
1650    Creature* pCreature = getSelectedCreature();
1651
1652    if(!pCreature)
1653    {
1654        SendSysMessage(LANG_SELECT_CREATURE);
1655        SetSentErrorMessage(true);
1656        return false;
1657    }
1658
1659    pCreature->setFaction(factionId);
1660
1661    // faction is set in creature_template - not inside creature
1662
1663    // update in memory
1664    if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
1665    {
1666        const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
1667        const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
1668    }
1669
1670    // and DB
1671    WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
1672
1673    return true;
1674}
1675
1676//kick player
1677bool ChatHandler::HandleKickPlayerCommand(const char *args)
1678{
1679    char* kickName = strtok((char*)args, " ");
1680    if (!kickName)
1681    {
1682        Player* player = getSelectedPlayer();
1683
1684        if(!player)
1685        {
1686            SendSysMessage(LANG_NO_CHAR_SELECTED);
1687            SetSentErrorMessage(true);
1688            return false;
1689        }
1690
1691        if(player==m_session->GetPlayer())
1692        {
1693            SendSysMessage(LANG_COMMAND_KICKSELF);
1694            SetSentErrorMessage(true);
1695            return false;
1696        }
1697
1698        player->GetSession()->KickPlayer();
1699    }
1700    else
1701    {
1702        std::string name = kickName;
1703        if(!normalizePlayerName(name))
1704        {
1705            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1706            SetSentErrorMessage(true);
1707            return false;
1708        }
1709
1710        if(m_session && name==m_session->GetPlayer()->GetName())
1711        {
1712            SendSysMessage(LANG_COMMAND_KICKSELF);
1713            SetSentErrorMessage(true);
1714            return false;
1715        }
1716
1717        if(sWorld.KickPlayer(name))
1718        {
1719            PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
1720        }
1721        else
1722            PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
1723    }
1724
1725    return true;
1726}
1727
1728//show info of player
1729bool ChatHandler::HandlePInfoCommand(const char* args)
1730{
1731    Player* target = NULL;
1732    uint64 targetGUID = 0;
1733
1734    char* px = strtok((char*)args, " ");
1735    char* py = NULL;
1736
1737    std::string name;
1738
1739    if (px)
1740    {
1741        name = px;
1742
1743        if(name.empty())
1744            return false;
1745
1746        if(!normalizePlayerName(name))
1747        {
1748            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1749            SetSentErrorMessage(true);
1750            return false;
1751        }
1752
1753        target = objmgr.GetPlayer(name.c_str());
1754        if (target)
1755            py = strtok(NULL, " ");
1756        else
1757        {
1758            targetGUID = objmgr.GetPlayerGUIDByName(name);
1759            if(targetGUID)
1760                py = strtok(NULL, " ");
1761            else
1762                py = px;
1763        }
1764    }
1765
1766    if(!target && !targetGUID)
1767    {
1768        target = getSelectedPlayer();
1769    }
1770
1771    if(!target && !targetGUID)
1772    {
1773        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1774        SetSentErrorMessage(true);
1775        return false;
1776    }
1777
1778    uint32 accId = 0;
1779    uint32 money = 0;
1780    uint32 total_player_time = 0;
1781    uint32 level = 0;
1782    uint32 latency = 0;
1783
1784    // get additional information from Player object
1785    if(target)
1786    {
1787        targetGUID = target->GetGUID();
1788        name = target->GetName();                           // re-read for case getSelectedPlayer() target
1789        accId = target->GetSession()->GetAccountId();
1790        money = target->GetMoney();
1791        total_player_time = target->GetTotalPlayedTime();
1792        level = target->getLevel();
1793        latency = target->GetSession()->GetLatency();
1794    }
1795    // get additional information from DB
1796    else
1797    {
1798        accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
1799        Player plr(m_session);                              // use current session for temporary load
1800        plr.MinimalLoadFromDB(NULL, targetGUID);
1801        money = plr.GetMoney();
1802        total_player_time = plr.GetTotalPlayedTime();
1803        level = plr.getLevel();
1804    }
1805
1806    std::string username = GetTrinityString(LANG_ERROR);
1807    std::string last_ip = GetTrinityString(LANG_ERROR);
1808    uint32 security = 0;
1809    std::string last_login = GetTrinityString(LANG_ERROR);
1810
1811    QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
1812    if(result)
1813    {
1814        Field* fields = result->Fetch();
1815        username = fields[0].GetCppString();
1816        security = fields[1].GetUInt32();
1817       
1818                if(!m_session || m_session->GetSecurity() >= security)
1819        {
1820            last_ip = fields[2].GetCppString();
1821            last_login = fields[3].GetCppString();
1822        }
1823        else
1824        {
1825            last_ip = "-";
1826            last_login = "-";
1827        }
1828
1829        delete result;
1830    }
1831
1832    PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
1833
1834    std::string timeStr = secsToTimeString(total_player_time,true,true);
1835    uint32 gold = money /GOLD;
1836    uint32 silv = (money % GOLD) / SILVER;
1837    uint32 copp = (money % GOLD) % SILVER;
1838    PSendSysMessage(LANG_PINFO_LEVEL,  timeStr.c_str(), level, gold,silv,copp );
1839
1840    if ( py && strncmp(py, "rep", 3) == 0 )
1841    {
1842        if(!target)
1843        {
1844            // rep option not implemented for offline case
1845            SendSysMessage(LANG_PINFO_NO_REP);
1846            SetSentErrorMessage(true);
1847            return false;
1848        }
1849
1850        char* FactionName;
1851        for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
1852        {
1853            FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
1854            if (factionEntry)
1855                FactionName = factionEntry->name[m_session->GetSessionDbcLocale()];
1856            else
1857                FactionName = "#Not found#";
1858            ReputationRank rank = target->GetReputationRank(factionEntry);
1859            std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
1860            std::ostringstream ss;
1861            ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
1862
1863            if(itr->second.Flags & FACTION_FLAG_VISIBLE)
1864                ss << GetTrinityString(LANG_FACTION_VISIBLE);
1865            if(itr->second.Flags & FACTION_FLAG_AT_WAR)
1866                ss << GetTrinityString(LANG_FACTION_ATWAR);
1867            if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
1868                ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
1869            if(itr->second.Flags & FACTION_FLAG_HIDDEN)
1870                ss << GetTrinityString(LANG_FACTION_HIDDEN);
1871            if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
1872                ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
1873            if(itr->second.Flags & FACTION_FLAG_INACTIVE)
1874                ss << GetTrinityString(LANG_FACTION_INACTIVE);
1875
1876            SendSysMessage(ss.str().c_str());
1877        }
1878    }
1879    return true;
1880}
1881
1882//show tickets
1883void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
1884{
1885    std::string name;
1886    if(!objmgr.GetPlayerNameByGUID(guid,name))
1887        name = GetTrinityString(LANG_UNKNOWN);
1888
1889    PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text);
1890}
1891
1892//ticket commands
1893bool ChatHandler::HandleTicketCommand(const char* args)
1894{
1895    char* px = strtok((char*)args, " ");
1896
1897    // ticket<end>
1898    if (!px)
1899    {
1900                if(!m_session)
1901                {
1902                        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1903                        SetSentErrorMessage(true);
1904                        return false;
1905                }
1906
1907        size_t count;
1908        QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket");
1909        if(result)
1910        {
1911            count = (*result)[0].GetUInt32();
1912            delete result;
1913        }
1914        else
1915            count = 0;
1916
1917        bool accept = m_session->GetPlayer()->isAcceptTickets();
1918               
1919                PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ?  GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF));
1920        return true;
1921    }
1922
1923    // ticket on
1924    if(strncmp(px,"on",3) == 0)
1925    {
1926                if(!m_session)
1927                {
1928                        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1929                        SetSentErrorMessage(true);
1930                        return false;
1931                }
1932
1933        m_session->GetPlayer()->SetAcceptTicket(true);
1934        SendSysMessage(LANG_COMMAND_TICKETON);
1935        return true;
1936    }
1937
1938    // ticket off
1939    if(strncmp(px,"off",4) == 0)
1940    {
1941                if(!m_session)
1942                {
1943                        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1944                        SetSentErrorMessage(true);
1945                        return false;
1946                }
1947
1948        m_session->GetPlayer()->SetAcceptTicket(false);
1949        SendSysMessage(LANG_COMMAND_TICKETOFF);
1950        return true;
1951    }
1952
1953    // ticket #num
1954    int num = atoi(px);
1955    if(num > 0)
1956    {
1957        QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
1958
1959        if(!result)
1960        {
1961            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1962            delete result;
1963            SetSentErrorMessage(true);
1964            return false;
1965        }
1966
1967        Field* fields = result->Fetch();
1968
1969        uint64 guid = fields[0].GetUInt64();
1970        char const* text = fields[1].GetString();
1971        char const* time = fields[2].GetString();
1972
1973        ShowTicket(guid,text,time);
1974        delete result;
1975        return true;
1976    }
1977
1978    std::string name = px;
1979
1980    if(!normalizePlayerName(name))
1981    {
1982        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1983        SetSentErrorMessage(true);
1984        return false;
1985    }
1986
1987    uint64 guid = objmgr.GetPlayerGUIDByName(name);
1988
1989    if(!guid)
1990        return false;
1991
1992    // ticket $char_name
1993    QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid));
1994
1995    if(!result)
1996        return false;
1997
1998    Field* fields = result->Fetch();
1999
2000    char const* text = fields[0].GetString();
2001    char const* time = fields[1].GetString();
2002
2003    ShowTicket(guid,text,time);
2004    delete result;
2005
2006    return true;
2007}
2008
2009uint32 ChatHandler::GetTicketIDByNum(uint32 num)
2010{
2011    QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket");
2012
2013    if(!result || num > result->GetRowCount())
2014    {
2015        PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2016        delete result;
2017        return 0;
2018    }
2019
2020    for(uint32 i = 1; i < num; ++i)
2021        result->NextRow();
2022
2023    Field* fields = result->Fetch();
2024
2025    uint32 id = fields[0].GetUInt32();
2026    delete result;
2027    return id;
2028}
2029
2030//dell all tickets
2031bool ChatHandler::HandleDelTicketCommand(const char *args)
2032{
2033    char* px = strtok((char*)args, " ");
2034    if (!px)
2035        return false;
2036
2037    // delticket all
2038    if(strncmp(px,"all",4) == 0)
2039    {
2040        QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket");
2041
2042        if(!result)
2043            return true;
2044
2045        // notify players about ticket deleting
2046        do
2047        {
2048            Field* fields = result->Fetch();
2049
2050            uint64 guid = fields[0].GetUInt64();
2051
2052            if(Player* sender = objmgr.GetPlayer(guid))
2053                sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2054
2055        }while(result->NextRow());
2056
2057        delete result;
2058
2059        CharacterDatabase.PExecute("DELETE FROM character_ticket");
2060        SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
2061        return true;
2062    }
2063
2064    int num = (uint32)atoi(px);
2065
2066    // delticket #num
2067    if(num > 0)
2068    {
2069        QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
2070
2071        if(!result)
2072        {
2073            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2074            delete result;
2075            SetSentErrorMessage(true);
2076            return false;
2077        }
2078
2079        Field* fields = result->Fetch();
2080
2081        uint32 id   = fields[0].GetUInt32();
2082        uint64 guid = fields[1].GetUInt64();
2083        delete result;
2084
2085        CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id);
2086
2087        // notify players about ticket deleting
2088        if(Player* sender = objmgr.GetPlayer(guid))
2089        {
2090            sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2091            PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName());
2092        }
2093        else
2094            SendSysMessage(LANG_COMMAND_TICKETDEL);
2095
2096        return true;
2097    }
2098
2099    std::string name = px;
2100
2101    if(!normalizePlayerName(name))
2102    {
2103        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2104        SetSentErrorMessage(true);
2105        return false;
2106    }
2107
2108    uint64 guid = objmgr.GetPlayerGUIDByName(name);
2109
2110    if(!guid)
2111        return false;
2112
2113    // delticket $char_name
2114    CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid));
2115
2116    // notify players about ticket deleting
2117    if(Player* sender = objmgr.GetPlayer(guid))
2118        sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2119
2120    PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
2121    return true;
2122}
2123
2124//set spawn dist of creature
2125bool ChatHandler::HandleSpawnDistCommand(const char* args)
2126{
2127    if(!*args)
2128        return false;
2129
2130    float option = atof((char*)args);
2131    if (option < 0.0f)
2132    {
2133        SendSysMessage(LANG_BAD_VALUE);
2134        return false;
2135    }
2136
2137    MovementGeneratorType mtype = IDLE_MOTION_TYPE;
2138    if (option >0.0f)
2139        mtype = RANDOM_MOTION_TYPE;
2140
2141    Creature *pCreature = getSelectedCreature();
2142    uint32 u_guidlow = 0;
2143
2144    if (pCreature)
2145        u_guidlow = pCreature->GetDBTableGUIDLow();
2146    else
2147        return false;
2148
2149    pCreature->SetRespawnRadius((float)option);
2150    pCreature->SetDefaultMovementType(mtype);
2151    pCreature->GetMotionMaster()->Initialize();
2152    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn
2153    {
2154        pCreature->setDeathState(JUST_DIED);
2155        pCreature->Respawn();
2156    }
2157
2158    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
2159    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
2160    return true;
2161}
2162
2163bool ChatHandler::HandleSpawnTimeCommand(const char* args)
2164{
2165    if(!*args)
2166        return false;
2167
2168    char* stime = strtok((char*)args, " ");
2169
2170    if (!stime)
2171        return false;
2172
2173    int i_stime = atoi((char*)stime);
2174
2175    if (i_stime < 0)
2176    {
2177        SendSysMessage(LANG_BAD_VALUE);
2178        SetSentErrorMessage(true);
2179        return false;
2180    }
2181
2182    Creature *pCreature = getSelectedCreature();
2183    uint32 u_guidlow = 0;
2184
2185    if (pCreature)
2186        u_guidlow = pCreature->GetDBTableGUIDLow();
2187    else
2188        return false;
2189
2190    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
2191    pCreature->SetRespawnDelay((uint32)i_stime);
2192    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
2193
2194    return true;
2195}
2196
2197/**
2198 * Add a waypoint to a creature.
2199 *
2200 * The user can either select an npc or provide its GUID.
2201 *
2202 * The user can even select a visual waypoint - then the new waypoint
2203 * is placed *after* the selected one - this makes insertion of new
2204 * waypoints possible.
2205 *
2206 * eg:
2207 * .wp add 12345
2208 * -> adds a waypoint to the npc with the GUID 12345
2209 *
2210 * .wp add
2211 * -> adds a waypoint to the currently selected creature
2212 *
2213 *
2214 * @param args if the user did not provide a GUID, it is NULL
2215 *
2216 * @return true - command did succeed, false - something went wrong
2217 */
2218bool ChatHandler::HandleWpAddCommand(const char* args)
2219{
2220    sLog.outDebug("DEBUG: HandleWpAddCommand");
2221
2222    // optional
2223    char* guid_str = NULL;
2224
2225    if(*args)
2226    {
2227        guid_str = strtok((char*)args, " ");
2228    }
2229
2230    uint32 lowguid = 0;
2231    uint32 point = 0;
2232    Creature* target = getSelectedCreature();
2233    // Did player provide a GUID?
2234    if (!guid_str)
2235    {
2236        sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2237
2238        // No GUID provided
2239        // -> Player must have selected a creature
2240
2241        if(!target || target->isPet())
2242        {
2243            SendSysMessage(LANG_SELECT_CREATURE);
2244            SetSentErrorMessage(true);
2245            return false;
2246        }
2247        if (target->GetEntry() == VISUAL_WAYPOINT )
2248        {
2249            sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2250
2251            QueryResult *result =
2252                WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2253                target->GetGUIDLow() );
2254            if(!result)
2255            {
2256                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
2257                // User selected a visual spawnpoint -> get the NPC
2258                // Select NPC GUID
2259                // Since we compare float values, we have to deal with
2260                // some difficulties.
2261                // Here we search for all waypoints that only differ in one from 1 thousand
2262                // (0.001) - There is no other way to compare C++ floats with mySQL floats
2263                // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2264                const char* maxDIFF = "0.01";
2265                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 )",
2266                    target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2267                if(!result)
2268                {
2269                    PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
2270                    SetSentErrorMessage(true);
2271                    return false;
2272                }
2273            }
2274            do
2275            {
2276                Field *fields = result->Fetch();
2277                lowguid = fields[0].GetUInt32();
2278                point   = fields[1].GetUInt32();
2279            }while( result->NextRow() );
2280            delete result;
2281
2282            CreatureData const* data = objmgr.GetCreatureData(lowguid);
2283            if(!data)
2284            {
2285                PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2286                SetSentErrorMessage(true);
2287                return false;
2288            }
2289
2290            target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2291            if(!target)
2292            {
2293                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2294                SetSentErrorMessage(true);
2295                return false;
2296            }
2297        }
2298        else
2299        {
2300            lowguid = target->GetDBTableGUIDLow();
2301        }
2302    }
2303    else
2304    {
2305        sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2306
2307        // GUID provided
2308        // Warn if player also selected a creature
2309        // -> Creature selection is ignored <-
2310        if(target)
2311        {
2312            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2313        }
2314        lowguid = atoi((char*)guid_str);
2315
2316        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2317        if(!data)
2318        {
2319            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2320            SetSentErrorMessage(true);
2321            return false;
2322        }
2323
2324        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2325        if(!target || target->isPet())
2326        {
2327            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2328            SetSentErrorMessage(true);
2329            return false;
2330        }
2331    }
2332    // lowguid -> GUID of the NPC
2333    // point   -> number of the waypoint (if not 0)
2334    sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
2335
2336    sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2337
2338    Player* player = m_session->GetPlayer();
2339    WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
2340
2341    // update movement type
2342    if(target)
2343    {
2344        target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2345        target->GetMotionMaster()->Initialize();
2346        if(target->isAlive())                               // dead creature will reset movement generator at respawn
2347        {
2348            target->setDeathState(JUST_DIED);
2349            target->Respawn();
2350        }
2351        target->SaveToDB();
2352    }
2353    else
2354        WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
2355
2356    PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
2357
2358    return true;
2359}                                                           // HandleWpAddCommand
2360
2361/**
2362 * .wp modify emote | spell | text | del | move | add
2363 *
2364 * add -> add a WP after the selected visual waypoint
2365 *        User must select a visual waypoint and then issue ".wp modify add"
2366 *
2367 * emote <emoteID>
2368 *   User has selected a visual waypoint before.
2369 *   <emoteID> is added to this waypoint. Everytime the
2370 *   NPC comes to this waypoint, the emote is called.
2371 *
2372 * emote <GUID> <WPNUM> <emoteID>
2373 *   User has not selected visual waypoint before.
2374 *   For the waypoint <WPNUM> for the NPC with <GUID>
2375 *   an emote <emoteID> is added.
2376 *   Everytime the NPC comes to this waypoint, the emote is called.
2377 *
2378 *
2379 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2380 */
2381bool ChatHandler::HandleWpModifyCommand(const char* args)
2382{
2383    sLog.outDebug("DEBUG: HandleWpModifyCommand");
2384
2385    if(!*args)
2386        return false;
2387
2388    // first arg: add del text emote spell waittime move
2389    char* show_str = strtok((char*)args, " ");
2390    if (!show_str)
2391    {
2392        return false;
2393    }
2394
2395    std::string show = show_str;
2396    // Check
2397    // Remember: "show" must also be the name of a column!
2398    if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2")
2399        && (show != "text3") && (show != "text4") && (show != "text5")
2400        && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
2401        && (show != "model1") && (show != "model2") && (show != "orientation"))
2402    {
2403        return false;
2404    }
2405
2406    // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2407
2408    // Did user provide a GUID
2409    // or did the user select a creature?
2410    // -> variable lowguid is filled with the GUID of the NPC
2411    uint32 lowguid = 0;
2412    uint32 point = 0;
2413    uint32 wpGuid = 0;
2414    Creature* target = getSelectedCreature();
2415
2416    if(target)
2417    {
2418        sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2419
2420        // Did the user select a visual spawnpoint?
2421        if (target->GetEntry() != VISUAL_WAYPOINT )
2422        {
2423            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2424            SetSentErrorMessage(true);
2425            return false;
2426        }
2427
2428        wpGuid = target->GetGUIDLow();
2429
2430        // The visual waypoint
2431        QueryResult *result =
2432            WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2433            target->GetGUIDLow() );
2434        if(!result)
2435        {
2436            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
2437            SetSentErrorMessage(true);
2438            return false;
2439        }
2440        sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2441
2442        Field *fields = result->Fetch();
2443        lowguid = fields[0].GetUInt32();
2444        point   = fields[1].GetUInt32();
2445
2446        // Cleanup memory
2447        sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2448        delete result;
2449    }
2450    else
2451    {
2452        // User did provide <GUID> <WPNUM>
2453
2454        char* guid_str = strtok((char*)NULL, " ");
2455        if( !guid_str )
2456        {
2457            SendSysMessage(LANG_WAYPOINT_NOGUID);
2458            return false;
2459        }
2460        lowguid = atoi((char*)guid_str);
2461
2462        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2463        if(!data)
2464        {
2465            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2466            SetSentErrorMessage(true);
2467            return false;
2468        }
2469
2470        PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2471
2472        char* point_str = strtok((char*)NULL, " ");
2473        if( !point_str )
2474        {
2475            SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2476            return false;
2477        }
2478        point    = atoi((char*)point_str);
2479
2480        PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2481
2482        // Now we need the GUID of the visual waypoint
2483        // -> "del", "move", "add" command
2484
2485        QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
2486        if (!result)
2487        {
2488            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2489            SetSentErrorMessage(true);
2490            return false;
2491        }
2492
2493        Field *fields = result->Fetch();
2494        wpGuid  = fields[0].GetUInt32();
2495
2496        // Free memory
2497        delete result;
2498    }
2499
2500    char* arg_str = NULL;
2501    // Check for argument
2502    if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
2503    {
2504        // Text is enclosed in "<>", all other arguments not
2505        if( show.find("text") != std::string::npos )
2506            arg_str = strtok((char*)NULL, "<>");
2507        else
2508            arg_str = strtok((char*)NULL, " ");
2509
2510        if( !arg_str)
2511        {
2512            PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2513            return false;
2514        }
2515    }
2516
2517    sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2518
2519    // wpGuid  -> GUID of the waypoint creature
2520    // lowguid -> GUID of the NPC
2521    // point   -> waypoint number
2522
2523    // Special functions:
2524    // add - move - del -> no args commands
2525    // Add a waypoint after the selected visual
2526    if(show == "add" && target)
2527    {
2528        PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2529
2530        // Get the creature for which we read the waypoint
2531        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2532        if(!data)
2533        {
2534            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2535            SetSentErrorMessage(true);
2536            return false;
2537        }
2538
2539        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2540
2541        if( !npcCreature )
2542        {
2543            PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2544            SetSentErrorMessage(true);
2545            return false;
2546        }
2547
2548        sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2549
2550        // What to do:
2551        // Add the visual spawnpoint (DB only)
2552        // Adjust the waypoints
2553        // Respawn the owner of the waypoints
2554        sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
2555
2556        Player* chr = m_session->GetPlayer();
2557        Map *map = chr->GetMap();
2558
2559        if(npcCreature)
2560        {
2561            npcCreature->GetMotionMaster()->Initialize();
2562            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
2563            {
2564                npcCreature->setDeathState(JUST_DIED);
2565                npcCreature->Respawn();
2566            }
2567        }
2568
2569        // create the waypoint creature
2570        wpGuid = 0;
2571        Creature* wpCreature = new Creature;
2572        if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
2573        {
2574            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2575            delete wpCreature;
2576        }
2577        else
2578        {
2579            wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2580
2581            if(!wpCreature->IsPositionValid())
2582            {
2583                sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
2584                delete wpCreature;
2585            }
2586            else
2587            {
2588                wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2589                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2590                wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
2591                map->Add(wpCreature);
2592                wpGuid = wpCreature->GetGUIDLow();
2593            }
2594        }
2595
2596        WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
2597
2598        if(!wpGuid)
2599            return false;
2600
2601        PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2602        return true;
2603    }                                                       // add
2604
2605    if(show == "del" && target)
2606    {
2607        PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2608
2609        // Get the creature for which we read the waypoint
2610        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2611        if(!data)
2612        {
2613            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2614            SetSentErrorMessage(true);
2615            return false;
2616        }
2617
2618        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2619
2620        // wpCreature
2621        Creature* wpCreature = NULL;
2622        if( wpGuid != 0 )
2623        {
2624            wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2625            wpCreature->DeleteFromDB();
2626            wpCreature->CleanupsBeforeDelete();
2627            wpCreature->AddObjectToRemoveList();
2628        }
2629
2630        // What to do:
2631        // Remove the visual spawnpoint
2632        // Adjust the waypoints
2633        // Respawn the owner of the waypoints
2634
2635        WaypointMgr.DeleteNode(lowguid, point);
2636
2637        if(npcCreature)
2638        {
2639            // Any waypoints left?
2640            QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
2641            if(!result2)
2642            {
2643                npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2644            }
2645            else
2646            {
2647                npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2648                delete result2;
2649            }
2650            npcCreature->GetMotionMaster()->Initialize();
2651            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
2652            {
2653                npcCreature->setDeathState(JUST_DIED);
2654                npcCreature->Respawn();
2655            }
2656            npcCreature->SaveToDB();
2657        }
2658
2659        PSendSysMessage(LANG_WAYPOINT_REMOVED);
2660        return true;
2661    }                                                       // del
2662
2663    if(show == "move" && target)
2664    {
2665        PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2666
2667        Player *chr = m_session->GetPlayer();
2668        Map *map = chr->GetMap();
2669        {
2670            // Get the creature for which we read the waypoint
2671            CreatureData const* data = objmgr.GetCreatureData(lowguid);
2672            if(!data)
2673            {
2674                PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2675                SetSentErrorMessage(true);
2676                return false;
2677            }
2678
2679            Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2680
2681            // wpCreature
2682            Creature* wpCreature = NULL;
2683            // What to do:
2684            // Move the visual spawnpoint
2685            // Respawn the owner of the waypoints
2686            if( wpGuid != 0 )
2687            {
2688                wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2689                wpCreature->DeleteFromDB();
2690                wpCreature->CleanupsBeforeDelete();
2691                wpCreature->AddObjectToRemoveList();
2692                // re-create
2693                Creature* wpCreature2 = new Creature;
2694                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
2695                {
2696                    PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2697                    delete wpCreature2;
2698                    return false;
2699                }
2700
2701                wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2702
2703                if(!wpCreature2->IsPositionValid())
2704                {
2705                    sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());
2706                    delete wpCreature2;
2707                    return false;
2708                }
2709
2710                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2711                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2712                wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
2713                map->Add(wpCreature2);
2714                //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2715            }
2716
2717            WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
2718
2719            if(npcCreature)
2720            {
2721                npcCreature->GetMotionMaster()->Initialize();
2722                if(npcCreature->isAlive())                  // dead creature will reset movement generator at respawn
2723                {
2724                    npcCreature->setDeathState(JUST_DIED);
2725                    npcCreature->Respawn();
2726                }
2727            }
2728            PSendSysMessage(LANG_WAYPOINT_CHANGED);
2729        }
2730        return true;
2731    }                                                       // move
2732
2733    // Create creature - npc that has the waypoint
2734    CreatureData const* data = objmgr.GetCreatureData(lowguid);
2735    if(!data)
2736    {
2737        PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2738        SetSentErrorMessage(true);
2739        return false;
2740    }
2741
2742    WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
2743
2744    Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2745    if(npcCreature)
2746    {
2747        npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2748        npcCreature->GetMotionMaster()->Initialize();
2749        if(npcCreature->isAlive())                          // dead creature will reset movement generator at respawn
2750        {
2751            npcCreature->setDeathState(JUST_DIED);
2752            npcCreature->Respawn();
2753        }
2754    }
2755    PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2756
2757    return true;
2758}
2759
2760/**
2761 * .wp show info | on | off
2762 *
2763 * info -> User has selected a visual waypoint before
2764 *
2765 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2766 *                        provided the GUID of the NPC and the number of
2767 *                        the waypoint.
2768 *
2769 * on -> User has selected an NPC; all visual waypoints for this
2770 *       NPC are added to the world
2771 *
2772 * on <GUID> -> User did not select an NPC - instead the GUID of the
2773 *              NPC is provided. All visual waypoints for this NPC
2774 *              are added from the world.
2775 *
2776 * off -> User has selected an NPC; all visual waypoints for this
2777 *        NPC are removed from the world.
2778 *
2779 * on <GUID> -> User did not select an NPC - instead the GUID of the
2780 *              NPC is provided. All visual waypoints for this NPC
2781 *              are removed from the world.
2782 *
2783 *
2784 */
2785bool ChatHandler::HandleWpShowCommand(const char* args)
2786{
2787    sLog.outDebug("DEBUG: HandleWpShowCommand");
2788
2789    if(!*args)
2790        return false;
2791
2792    // first arg: on, off, first, last
2793    char* show_str = strtok((char*)args, " ");
2794    if (!show_str)
2795    {
2796        return false;
2797    }
2798    // second arg: GUID (optional, if a creature is selected)
2799    char* guid_str = strtok((char*)NULL, " ");
2800    sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2801    //if (!guid_str) {
2802    //    return false;
2803    //}
2804
2805    // Did user provide a GUID
2806    // or did the user select a creature?
2807    // -> variable lowguid is filled with the GUID
2808    Creature* target = getSelectedCreature();
2809    // Did player provide a GUID?
2810    if (!guid_str)
2811    {
2812        sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2813        // No GUID provided
2814        // -> Player must have selected a creature
2815
2816        if(!target)
2817        {
2818            SendSysMessage(LANG_SELECT_CREATURE);
2819            SetSentErrorMessage(true);
2820            return false;
2821        }
2822    }
2823    else
2824    {
2825        sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2826        // GUID provided
2827        // Warn if player also selected a creature
2828        // -> Creature selection is ignored <-
2829        if(target)
2830        {
2831            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2832        }
2833
2834        uint32 lowguid = atoi((char*)guid_str);
2835
2836        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2837        if(!data)
2838        {
2839            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2840            SetSentErrorMessage(true);
2841            return false;
2842        }
2843
2844        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2845
2846        if(!target)
2847        {
2848            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2849            SetSentErrorMessage(true);
2850            return false;
2851        }
2852    }
2853
2854    uint32 lowguid = target->GetDBTableGUIDLow();
2855
2856    std::string show = show_str;
2857    uint32 Maxpoint;
2858
2859    sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
2860
2861    sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", target );
2862
2863    sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
2864    //PSendSysMessage("wpshow - show: %s", show);
2865
2866    // Show info for the selected waypoint
2867    if(show == "info")
2868    {
2869        PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
2870
2871        // Check if the user did specify a visual waypoint
2872        if( target->GetEntry() != VISUAL_WAYPOINT )
2873        {
2874            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2875            SetSentErrorMessage(true);
2876            return false;
2877        }
2878
2879        //PSendSysMessage("wp on, GUID: %u", lowguid);
2880
2881        //pCreature->GetPositionX();
2882
2883        QueryResult *result =
2884            WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2885            target->GetGUID() );
2886        if(!result)
2887        {
2888            // Since we compare float values, we have to deal with
2889            // some difficulties.
2890            // Here we search for all waypoints that only differ in one from 1 thousand
2891            // (0.001) - There is no other way to compare C++ floats with mySQL floats
2892            // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2893            const char* maxDIFF = "0.01";
2894            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
2895
2896            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 )",
2897                target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2898            if(!result)
2899            {
2900                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2901                SetSentErrorMessage(true);
2902                return false;
2903            }
2904        }
2905        do
2906        {
2907            Field *fields = result->Fetch();
2908            uint32 creGUID          = fields[0].GetUInt32();
2909            uint32 point            = fields[1].GetUInt32();
2910            int waittime            = fields[2].GetUInt32();
2911            uint32 emote            = fields[3].GetUInt32();
2912            uint32 spell            = fields[4].GetUInt32();
2913            const char * text1      = fields[5].GetString();
2914            const char * text2      = fields[6].GetString();
2915            const char * text3      = fields[7].GetString();
2916            const char * text4      = fields[8].GetString();
2917            const char * text5      = fields[9].GetString();
2918            uint32 model1           = fields[10].GetUInt32();
2919            uint32 model2           = fields[11].GetUInt32();
2920
2921            // Get the creature for which we read the waypoint
2922            Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2923
2924            PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
2925            PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
2926            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
2927            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
2928            PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
2929            PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
2930            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
2931            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
2932            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
2933            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
2934            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
2935
2936        }while( result->NextRow() );
2937        // Cleanup memory
2938        delete result;
2939        return true;
2940    }
2941
2942    if(show == "on")
2943    {
2944        PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
2945
2946        QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
2947        if(!result)
2948        {
2949            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2950            SetSentErrorMessage(true);
2951            return false;
2952        }
2953        // Delete all visuals for this NPC
2954        QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
2955        if(result2)
2956        {
2957            bool hasError = false;
2958            do
2959            {
2960                Field *fields = result2->Fetch();
2961                uint32 wpguid = fields[0].GetUInt32();
2962                Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2963
2964                if(!pCreature)
2965                {
2966                    PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
2967                    hasError = true;
2968                    WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
2969                }
2970                else
2971                {
2972                    pCreature->DeleteFromDB();
2973                    pCreature->CleanupsBeforeDelete();
2974                    pCreature->AddObjectToRemoveList();
2975                }
2976
2977            }while( result2->NextRow() );
2978            delete result2;
2979            if( hasError )
2980            {
2981                PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2982                PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2983                PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2984            }
2985        }
2986
2987        do
2988        {
2989            Field *fields = result->Fetch();
2990            uint32 point    = fields[0].GetUInt32();
2991            float x         = fields[1].GetFloat();
2992            float y         = fields[2].GetFloat();
2993            float z         = fields[3].GetFloat();
2994
2995            uint32 id = VISUAL_WAYPOINT;
2996
2997            Player *chr = m_session->GetPlayer();
2998            Map *map = chr->GetMap();
2999            float o = chr->GetOrientation();
3000
3001            Creature* wpCreature = new Creature;
3002            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3003            {
3004                PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3005                delete wpCreature;
3006                delete result;
3007                return false;
3008            }
3009
3010            wpCreature->Relocate(x, y, z, o);
3011
3012            if(!wpCreature->IsPositionValid())
3013            {
3014                sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
3015                delete wpCreature;
3016                delete result;
3017                return false;
3018            }
3019
3020            wpCreature->SetVisibility(VISIBILITY_OFF);
3021            sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3022            // set "wpguid" column to the visual waypoint
3023            WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
3024
3025            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3026            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3027            wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
3028            map->Add(wpCreature);
3029            //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
3030        }while( result->NextRow() );
3031
3032        // Cleanup memory
3033        delete result;
3034        return true;
3035    }
3036
3037    if(show == "first")
3038    {
3039        PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3040
3041        QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3042        if(!result)
3043        {
3044            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3045            SetSentErrorMessage(true);
3046            return false;
3047        }
3048
3049        Field *fields = result->Fetch();
3050        float x         = fields[0].GetFloat();
3051        float y         = fields[1].GetFloat();
3052        float z         = fields[2].GetFloat();
3053        uint32 id = VISUAL_WAYPOINT;
3054
3055        Player *chr = m_session->GetPlayer();
3056        float o = chr->GetOrientation();
3057        Map *map = chr->GetMap();
3058
3059        Creature* pCreature = new Creature;
3060        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
3061        {
3062            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3063            delete pCreature;
3064            delete result;
3065            return false;
3066        }
3067
3068        pCreature->Relocate(x, y, z, o);
3069
3070        if(!pCreature->IsPositionValid())
3071        {
3072            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3073            delete pCreature;
3074            delete result;
3075            return false;
3076        }
3077
3078        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3079        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3080        map->Add(pCreature);
3081        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3082
3083        // Cleanup memory
3084        delete result;
3085        return true;
3086    }
3087
3088    if(show == "last")
3089    {
3090        PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3091
3092        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3093        if( result )
3094        {
3095            Maxpoint = (*result)[0].GetUInt32();
3096
3097            delete result;
3098        }
3099        else
3100            Maxpoint = 0;
3101
3102        result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3103        if(!result)
3104        {
3105            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3106            SetSentErrorMessage(true);
3107            return false;
3108        }
3109        Field *fields = result->Fetch();
3110        float x         = fields[0].GetFloat();
3111        float y         = fields[1].GetFloat();
3112        float z         = fields[2].GetFloat();
3113        uint32 id = VISUAL_WAYPOINT;
3114
3115        Player *chr = m_session->GetPlayer();
3116        float o = chr->GetOrientation();
3117        Map *map = chr->GetMap();
3118
3119        Creature* pCreature = new Creature;
3120        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3121        {
3122            PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3123            delete pCreature;
3124            delete result;
3125            return false;
3126        }
3127
3128        pCreature->Relocate(x, y, z, o);
3129
3130        if(!pCreature->IsPositionValid())
3131        {
3132            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3133            delete pCreature;
3134            delete result;
3135            return false;
3136        }
3137
3138        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3139        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3140        map->Add(pCreature);
3141        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3142        // Cleanup memory
3143        delete result;
3144        return true;
3145    }
3146
3147    if(show == "off")
3148    {
3149        QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3150        if(!result)
3151        {
3152            SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3153            SetSentErrorMessage(true);
3154            return false;
3155        }
3156        bool hasError = false;
3157        do
3158        {
3159            Field *fields = result->Fetch();
3160            uint32 guid = fields[0].GetUInt32();
3161            Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3162
3163            //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3164
3165            if(!pCreature)
3166            {
3167                PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3168                hasError = true;
3169                WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3170            }
3171            else
3172            {
3173                pCreature->DeleteFromDB();
3174                pCreature->CleanupsBeforeDelete();
3175                pCreature->AddObjectToRemoveList();
3176            }
3177        }while(result->NextRow());
3178        // set "wpguid" column to "empty" - no visual waypoint spawned
3179        WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3180
3181        if( hasError )
3182        {
3183            PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3184            PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3185            PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3186        }
3187
3188        SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3189        // Cleanup memory
3190        delete result;
3191
3192        return true;
3193    }
3194
3195    PSendSysMessage("DEBUG: wpshow - no valid command found");
3196
3197    return true;
3198}                                                           // HandleWpShowCommand
3199
3200bool ChatHandler::HandleWpExportCommand(const char *args)
3201{
3202    if(!*args)
3203        return false;
3204
3205    // Next arg is: <GUID> <ARGUMENT>
3206
3207    // Did user provide a GUID
3208    // or did the user select a creature?
3209    // -> variable lowguid is filled with the GUID of the NPC
3210    uint32 lowguid = 0;
3211    Creature* target = getSelectedCreature();
3212    char* arg_str = NULL;
3213    if (target)
3214    {
3215        if (target->GetEntry() != VISUAL_WAYPOINT)
3216            lowguid = target->GetGUIDLow();
3217        else
3218        {
3219            QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3220            if (!result)
3221            {
3222                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3223                return true;
3224            }
3225            Field *fields = result->Fetch();
3226            lowguid = fields[0].GetUInt32();;
3227            delete result;
3228        }
3229
3230        arg_str = strtok((char*)args, " ");
3231    }
3232    else
3233    {
3234        // user provided <GUID>
3235        char* guid_str = strtok((char*)args, " ");
3236        if( !guid_str )
3237        {
3238            SendSysMessage(LANG_WAYPOINT_NOGUID);
3239            return false;
3240        }
3241        lowguid = atoi((char*)guid_str);
3242
3243        arg_str = strtok((char*)NULL, " ");
3244    }
3245
3246    if( !arg_str)
3247    {
3248        PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3249        return false;
3250    }
3251
3252    PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3253
3254    QueryResult *result = WorldDatabase.PQuery(
3255    //          0      1           2           3           4            5       6       7         8      9      10     11     12     13     14     15
3256        "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 );
3257
3258    if (!result)
3259    {
3260        PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3261        SetSentErrorMessage(true);
3262        return false;
3263    }
3264
3265    std::ofstream outfile;
3266    outfile.open (arg_str);
3267
3268    do
3269    {
3270        Field *fields = result->Fetch();
3271
3272        outfile << "INSERT INTO creature_movement ";
3273        outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
3274
3275        outfile << "( ";
3276        outfile << fields[15].GetUInt32();                  // id
3277        outfile << ", ";
3278        outfile << fields[0].GetUInt32();                   // point
3279        outfile << ", ";
3280        outfile << fields[1].GetFloat();                    // position_x
3281        outfile << ", ";
3282        outfile << fields[2].GetFloat();                    // position_y
3283        outfile << ", ";
3284        outfile << fields[3].GetUInt32();                   // position_z
3285        outfile << ", ";
3286        outfile << fields[4].GetUInt32();                   // orientation
3287        outfile << ", ";
3288        outfile << fields[5].GetUInt32();                   // model1
3289        outfile << ", ";
3290        outfile << fields[6].GetUInt32();                   // model2
3291        outfile << ", ";
3292        outfile << fields[7].GetUInt16();                   // waittime
3293        outfile << ", ";
3294        outfile << fields[8].GetUInt32();                   // emote
3295        outfile << ", ";
3296        outfile << fields[9].GetUInt32();                   // spell
3297        outfile << ", ";
3298        const char *tmpChar = fields[10].GetString();
3299        if( !tmpChar )
3300        {
3301            outfile << "NULL";                              // text1
3302        }
3303        else
3304        {
3305            outfile << "'";
3306            outfile << tmpChar;                             // text1
3307            outfile << "'";
3308        }
3309        outfile << ", ";
3310        tmpChar = fields[11].GetString();
3311        if( !tmpChar )
3312        {
3313            outfile << "NULL";                              // text2
3314        }
3315        else
3316        {
3317            outfile << "'";
3318            outfile << tmpChar;                             // text2
3319            outfile << "'";
3320        }
3321        outfile << ", ";
3322        tmpChar = fields[12].GetString();
3323        if( !tmpChar )
3324        {
3325            outfile << "NULL";                              // text3
3326        }
3327        else
3328        {
3329            outfile << "'";
3330            outfile << tmpChar;                             // text3
3331            outfile << "'";
3332        }
3333        outfile << ", ";
3334        tmpChar = fields[13].GetString();
3335        if( !tmpChar )
3336        {
3337            outfile << "NULL";                              // text4
3338        }
3339        else
3340        {
3341            outfile << "'";
3342            outfile << tmpChar;                             // text4
3343            outfile << "'";
3344        }
3345        outfile << ", ";
3346        tmpChar = fields[14].GetString();
3347        if( !tmpChar )
3348        {
3349            outfile << "NULL";                              // text5
3350        }
3351        else
3352        {
3353            outfile << "'";
3354            outfile << tmpChar;                             // text5
3355            outfile << "'";
3356        }
3357        outfile << ");\n ";
3358
3359    } while( result->NextRow() );
3360    delete result;
3361
3362    PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3363    outfile.close();
3364
3365    return true;
3366}
3367
3368bool ChatHandler::HandleWpImportCommand(const char *args)
3369{
3370    if(!*args)
3371        return false;
3372
3373    char* arg_str = strtok((char*)args, " ");
3374    if (!arg_str)
3375        return false;
3376
3377    std::string line;
3378    std::ifstream infile (arg_str);
3379    if (infile.is_open())
3380    {
3381        while (! infile.eof() )
3382        {
3383            getline (infile,line);
3384            //cout << line << endl;
3385            QueryResult *result = WorldDatabase.PQuery(line.c_str());
3386            delete result;
3387        }
3388        infile.close();
3389    }
3390    PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3391
3392    return true;
3393}
3394
3395//rename characters
3396bool ChatHandler::HandleRenameCommand(const char* args)
3397{
3398    Player* target = NULL;
3399    uint64 targetGUID = 0;
3400    std::string oldname;
3401
3402    char* px = strtok((char*)args, " ");
3403
3404    if(px)
3405    {
3406        oldname = px;
3407
3408        if(!normalizePlayerName(oldname))
3409        {
3410            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3411            SetSentErrorMessage(true);
3412            return false;
3413        }
3414
3415        target = objmgr.GetPlayer(oldname.c_str());
3416
3417        if (!target)
3418            targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3419    }
3420
3421    if(!target && !targetGUID)
3422    {
3423        target = getSelectedPlayer();
3424    }
3425
3426    if(!target && !targetGUID)
3427    {
3428        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3429        SetSentErrorMessage(true);
3430        return false;
3431    }
3432
3433    if(target)
3434    {
3435        PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
3436        target->SetAtLoginFlag(AT_LOGIN_RENAME);
3437        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3438    }
3439    else
3440    {
3441        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
3442        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3443    }
3444
3445    return true;
3446}
3447
3448//spawn go
3449bool ChatHandler::HandleGameObjectCommand(const char* args)
3450{
3451    if (!*args)
3452        return false;
3453
3454    char* pParam1 = strtok((char*)args, " ");
3455    if (!pParam1)
3456        return false;
3457
3458    uint32 id = atoi((char*)pParam1);
3459    if(!id)
3460        return false;
3461
3462    char* spawntimeSecs = strtok(NULL, " ");
3463
3464    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
3465
3466    if (!goI)
3467    {
3468        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
3469        SetSentErrorMessage(true);
3470        return false;
3471    }
3472
3473    Player *chr = m_session->GetPlayer();
3474    float x = float(chr->GetPositionX());
3475    float y = float(chr->GetPositionY());
3476    float z = float(chr->GetPositionZ());
3477    float o = float(chr->GetOrientation());
3478    Map *map = chr->GetMap();
3479
3480    float rot2 = sin(o/2);
3481    float rot3 = cos(o/2);
3482
3483    GameObject* pGameObj = new GameObject;
3484    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
3485
3486    if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
3487    {
3488        delete pGameObj;
3489        return false;
3490    }
3491
3492    if( spawntimeSecs )
3493    {
3494        uint32 value = atoi((char*)spawntimeSecs);
3495        pGameObj->SetRespawnTime(value);
3496        //sLog.outDebug("*** spawntimeSecs: %d", value);
3497    }
3498
3499    // fill the gameobject data and save to the db
3500    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3501
3502    // this will generate a new guid if the object is in an instance
3503    if(!pGameObj->LoadFromDB(db_lowGUID, map))
3504    {
3505        delete pGameObj;
3506        return false;
3507    }
3508
3509    sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
3510
3511    map->Add(pGameObj);
3512
3513    // TODO: is it really necessary to add both the real and DB table guid here ?
3514    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
3515
3516    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
3517    return true;
3518}
3519
3520//show animation
3521bool ChatHandler::HandleAnimCommand(const char* args)
3522{
3523    if (!*args)
3524        return false;
3525
3526    uint32 anim_id = atoi((char*)args);
3527    m_session->GetPlayer()->HandleEmoteCommand(anim_id);
3528    return true;
3529}
3530
3531//change standstate
3532bool ChatHandler::HandleStandStateCommand(const char* args)
3533{
3534    if (!*args)
3535        return false;
3536
3537    uint32 anim_id = atoi((char*)args);
3538    m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3539
3540    return true;
3541}
3542
3543bool ChatHandler::HandleAddHonorCommand(const char* args)
3544{
3545    if (!*args)
3546        return false;
3547
3548    Player *target = getSelectedPlayer();
3549    if(!target)
3550    {
3551        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3552        SetSentErrorMessage(true);
3553        return false;
3554    }
3555
3556    uint32 amount = (uint32)atoi(args);
3557    target->RewardHonor(NULL, 1, amount);
3558    return true;
3559}
3560
3561bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3562{
3563    Unit *target = getSelectedUnit();
3564    if(!target)
3565    {
3566        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3567        SetSentErrorMessage(true);
3568        return false;
3569    }
3570
3571    m_session->GetPlayer()->RewardHonor(target, 1);
3572    return true;
3573}
3574
3575bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3576{
3577    Player *target = getSelectedPlayer();
3578    if(!target)
3579    {
3580        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3581        SetSentErrorMessage(true);
3582        return false;
3583    }
3584
3585    target->UpdateHonorFields();
3586    return true;
3587}
3588
3589bool ChatHandler::HandleLookupEventCommand(const char* args)
3590{
3591    if(!*args)
3592        return false;
3593
3594    std::string namepart = args;
3595    std::wstring wnamepart;
3596
3597    // converting string that we try to find to lower case
3598    if(!Utf8toWStr(namepart,wnamepart))
3599        return false;
3600
3601    wstrToLower(wnamepart);
3602
3603    uint32 counter = 0;
3604
3605    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3606    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3607
3608    for(uint32 id = 0; id < events.size(); ++id )
3609    {
3610        GameEventData const& eventData = events[id];
3611
3612        std::string descr = eventData.description;
3613        if(descr.empty())
3614            continue;
3615
3616        if (Utf8FitTo(descr, wnamepart))
3617        {
3618            char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : "";
3619           
3620                        if(m_session)
3621                                PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
3622                        else
3623                                PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
3624
3625            ++counter;
3626        }
3627    }
3628
3629    if (counter==0)
3630        SendSysMessage(LANG_NOEVENTFOUND);
3631
3632    return true;
3633}
3634
3635bool ChatHandler::HandleEventActiveListCommand(const char* args)
3636{
3637    uint32 counter = 0;
3638
3639    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3640    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3641
3642    char const* active = GetTrinityString(LANG_ACTIVE);
3643
3644    for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3645    {
3646        uint32 event_id = *itr;
3647        GameEventData const& eventData = events[event_id];
3648
3649        if(m_session)
3650                        PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
3651                else
3652                        PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
3653
3654        ++counter;
3655    }
3656
3657    if (counter==0)
3658        SendSysMessage(LANG_NOEVENTFOUND);
3659
3660    return true;
3661}
3662
3663bool ChatHandler::HandleEventInfoCommand(const char* args)
3664{
3665    if(!*args)
3666        return false;
3667
3668    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3669    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3670    if(!cId)
3671        return false;
3672
3673    uint32 event_id = atoi(cId);
3674
3675    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3676
3677    if(event_id >=events.size())
3678    {
3679        SendSysMessage(LANG_EVENT_NOT_EXIST);
3680        SetSentErrorMessage(true);
3681        return false;
3682    }
3683
3684    GameEventData const& eventData = events[event_id];
3685    if(!eventData.isValid())
3686    {
3687        SendSysMessage(LANG_EVENT_NOT_EXIST);
3688        SetSentErrorMessage(true);
3689        return false;
3690    }
3691
3692    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3693    bool active = activeEvents.find(event_id) != activeEvents.end();
3694    char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
3695
3696    std::string startTimeStr = TimeToTimestampStr(eventData.start);
3697    std::string endTimeStr = TimeToTimestampStr(eventData.end);
3698
3699    uint32 delay = gameeventmgr.NextCheck(event_id);
3700    time_t nextTime = time(NULL)+delay;
3701    std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3702
3703    std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3704    std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3705
3706    PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3707        startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3708        nextStr.c_str());
3709    return true;
3710}
3711
3712bool ChatHandler::HandleEventStartCommand(const char* args)
3713{
3714    if(!*args)
3715        return false;
3716
3717    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3718    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3719    if(!cId)
3720        return false;
3721
3722    int32 event_id = atoi(cId);
3723
3724    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3725
3726    if(event_id < 1 || event_id >=events.size())
3727    {
3728        SendSysMessage(LANG_EVENT_NOT_EXIST);
3729        SetSentErrorMessage(true);
3730        return false;
3731    }
3732
3733    GameEventData const& eventData = events[event_id];
3734    if(!eventData.isValid())
3735    {
3736        SendSysMessage(LANG_EVENT_NOT_EXIST);
3737        SetSentErrorMessage(true);
3738        return false;
3739    }
3740
3741    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3742    if(activeEvents.find(event_id) != activeEvents.end())
3743    {
3744        PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
3745        SetSentErrorMessage(true);
3746        return false;
3747    }
3748
3749    gameeventmgr.StartEvent(event_id,true);
3750    return true;
3751}
3752
3753bool ChatHandler::HandleEventStopCommand(const char* args)
3754{
3755    if(!*args)
3756        return false;
3757
3758    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3759    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3760    if(!cId)
3761        return false;
3762
3763    int32 event_id = atoi(cId);
3764
3765    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3766
3767    if(event_id < 1 || event_id >=events.size())
3768    {
3769        SendSysMessage(LANG_EVENT_NOT_EXIST);
3770        SetSentErrorMessage(true);
3771        return false;
3772    }
3773
3774    GameEventData const& eventData = events[event_id];
3775    if(!eventData.isValid())
3776    {
3777        SendSysMessage(LANG_EVENT_NOT_EXIST);
3778        SetSentErrorMessage(true);
3779        return false;
3780    }
3781
3782    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3783
3784    if(activeEvents.find(event_id) == activeEvents.end())
3785    {
3786        PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
3787        SetSentErrorMessage(true);
3788        return false;
3789    }
3790
3791    gameeventmgr.StopEvent(event_id,true);
3792    return true;
3793}
3794
3795bool ChatHandler::HandleCombatStopCommand(const char* args)
3796{
3797    Player *player;
3798
3799    if(*args)
3800    {
3801        std::string playername = args;
3802
3803        if(!normalizePlayerName(playername))
3804        {
3805            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3806            SetSentErrorMessage(true);
3807            return false;
3808        }
3809
3810        player = objmgr.GetPlayer(playername.c_str());
3811
3812        if(!player)
3813        {
3814            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3815            SetSentErrorMessage(true);
3816            return false;
3817        }
3818    }
3819    else
3820    {
3821        player = getSelectedPlayer();
3822
3823        if (!player)
3824            player = m_session->GetPlayer();
3825    }
3826
3827    player->CombatStop();
3828    player->getHostilRefManager().deleteReferences();
3829    return true;
3830}
3831
3832bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3833{
3834    uint32 classmask = m_session->GetPlayer()->getClassMask();
3835
3836    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3837    {
3838        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3839        if( !skillInfo )
3840            continue;
3841
3842        if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
3843        {
3844            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3845            {
3846                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3847                if( !skillLine )
3848                    continue;
3849
3850                // skip racial skills
3851                if( skillLine->racemask != 0 )
3852                    continue;
3853
3854                // skip wrong class skills
3855                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3856                    continue;
3857
3858                if( skillLine->skillId != i || skillLine->forward_spellid )
3859                    continue;
3860
3861                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3862                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3863                    continue;
3864
3865                m_session->GetPlayer()->learnSpell(skillLine->spellId);
3866            }
3867        }
3868    }
3869
3870    SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
3871    return true;
3872}
3873
3874bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
3875{
3876    //  Learns all recipes of specified profession and sets skill to max
3877    //  Example: .learn all_recipes enchanting
3878
3879    Player* target = getSelectedPlayer();
3880    if( !target )
3881    {
3882        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3883        return false;
3884    }
3885
3886    if (!*args)
3887        return false;
3888
3889    std::wstring wnamepart;
3890
3891    if(!Utf8toWStr(args,wnamepart))
3892        return false;
3893
3894    uint32 counter = 0;                                     // Counter for figure out that we found smth.
3895
3896    // converting string that we try to find to lower case
3897    wstrToLower( wnamepart );
3898
3899    uint32 classmask = m_session->GetPlayer()->getClassMask();
3900
3901    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3902    {
3903        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3904        if( !skillInfo )
3905            continue;
3906
3907        if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
3908            skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
3909            continue;
3910
3911        int loc = m_session->GetSessionDbcLocale();
3912        std::string name = skillInfo->name[loc];
3913
3914        if(Utf8FitTo(name, wnamepart))
3915        {
3916            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3917            {
3918                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3919                if( !skillLine )
3920                    continue;
3921
3922                if( skillLine->skillId != i || skillLine->forward_spellid )
3923                    continue;
3924
3925                // skip racial skills
3926                if( skillLine->racemask != 0 )
3927                    continue;
3928
3929                // skip wrong class skills
3930                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3931                    continue;
3932
3933                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3934                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3935                    continue;
3936
3937                if( !target->HasSpell(spellInfo->Id) )
3938                    m_session->GetPlayer()->learnSpell(skillLine->spellId);
3939            }
3940
3941            uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
3942            target->SetSkill(skillInfo->id, maxLevel, maxLevel);
3943            PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
3944            return true;
3945        }
3946    }
3947
3948    return false;
3949}
3950
3951bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
3952{
3953 
3954    if (!*args)
3955        return false;
3956
3957    std::string ip = strtok ((char*)args, " ");
3958        char* limit_str = strtok (NULL, " ");
3959        int32 limit = limit_str ? atoi (limit_str) : -1;
3960
3961    loginDatabase.escape_string (ip);
3962
3963    QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
3964
3965    return LookupPlayerSearchCommand (result,limit);
3966}
3967
3968bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
3969{
3970    if (!*args)
3971        return false;
3972
3973    std::string account = strtok ((char*)args, " ");
3974        char* limit_str = strtok (NULL, " ");
3975        int32 limit = limit_str ? atoi (limit_str) : -1;
3976
3977    if (!AccountMgr::normilizeString (account))
3978        return false;
3979
3980    loginDatabase.escape_string (account);
3981
3982    QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
3983
3984    return LookupPlayerSearchCommand (result,limit);
3985}
3986
3987bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
3988{
3989 
3990    if (!*args)
3991        return false;
3992
3993    std::string email = strtok ((char*)args, " ");
3994        char* limit_str = strtok (NULL, " ");
3995        int32 limit = limit_str ? atoi (limit_str) : -1;
3996
3997    loginDatabase.escape_string (email);
3998
3999    QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
4000
4001    return LookupPlayerSearchCommand (result,limit);
4002}
4003
4004bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
4005{
4006    if(!result)
4007    {
4008        PSendSysMessage(LANG_NO_PLAYERS_FOUND);
4009        SetSentErrorMessage(true);
4010        return false;
4011    }
4012
4013    int i =0;
4014    do
4015    {
4016        Field* fields = result->Fetch();
4017        uint32 acc_id = fields[0].GetUInt32();
4018        std::string acc_name = fields[1].GetCppString();
4019       
4020        QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
4021        if(chars)
4022        {
4023            PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
4024
4025            uint64 guid = 0;
4026            std::string name;
4027
4028            do
4029            {
4030                Field* charfields = chars->Fetch();
4031                guid = charfields[0].GetUInt64();
4032                name = charfields[1].GetCppString();
4033
4034                PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
4035                ++i;
4036
4037            } while( chars->NextRow() && ( limit == -1 || i < limit ) );
4038
4039            delete chars;
4040        }
4041    } while(result->NextRow());
4042
4043    delete result;
4044
4045    return true;
4046}
4047
4048/// Triggering corpses expire check in world
4049bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4050{
4051        CorpsesErase();
4052        return true;
4053}
4054
4055bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
4056{
4057    Player *target = getSelectedPlayer();
4058
4059    if(!target)
4060    {
4061        PSendSysMessage(LANG_NO_CHAR_SELECTED);
4062        SetSentErrorMessage(true);
4063        return false;
4064        }
4065
4066    // Repair items
4067    target->DurabilityRepairAll(false, 0, false);
4068
4069    PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName());
4070    if(needReportToTarget(target))
4071        ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName());
4072    return true;
4073}
4074
4075bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
4076{
4077    Player *player = m_session->GetPlayer();
4078    Creature *creature = getSelectedCreature();
4079
4080    if(!creature)
4081    {
4082        PSendSysMessage(LANG_SELECT_CREATURE);
4083        SetSentErrorMessage(true);
4084        return false;
4085    }
4086
4087    // Follow player - Using pet's default dist and angle
4088    creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
4089
4090    PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
4091    return true;
4092}
4093
4094bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
4095{
4096    Player *player = m_session->GetPlayer();
4097    Creature *creature = getSelectedCreature();
4098
4099    if(!creature)
4100    {
4101        PSendSysMessage(LANG_SELECT_CREATURE);
4102        SetSentErrorMessage(true);
4103        return false;
4104    }
4105
4106    if (creature->GetMotionMaster()->empty() ||
4107        creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
4108    {
4109        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
4110        SetSentErrorMessage(true);
4111        return false;
4112    }
4113
4114    TargetedMovementGenerator<Creature> const* mgen
4115        = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
4116
4117    if(mgen->GetTarget()!=player)
4118    {
4119        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
4120        SetSentErrorMessage(true);
4121        return false;
4122    }
4123
4124    // reset movement
4125    creature->GetMotionMaster()->MovementExpired(true);
4126
4127    PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
4128    return true;
4129}
Note: See TracBrowser for help on using the browser.