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

Revision 207, 125.1 kB (checked in by yumileroy, 17 years ago)

[svn] * Improve some arena team related DB access
* Cache GM tickets on server startup.
* Remove unused src/game/HateMatrix.h and references.
* Better check client inventory pos data received in some client packets to
skip invalid cases

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