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

Revision 263, 123.7 kB (checked in by yumileroy, 17 years ago)

Some missing changes. This should fix the bug that loading char causes crash.
Please do not commit to the other tip (I do not know how to delete it).

Original author: megamage
Date: 2008-11-20 17:40:13-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 != "textid1") && (show != "textid2")
2365        && (show != "textid3") && (show != "textid4") && (show != "textid5")
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    // set in game textids not supported
2709    if( show == "textid1" || show == "textid2" || show == "textid3" ||
2710        show == "textid4" || show == "textid5" )
2711    {
2712        return false;
2713    }
2714
2715    WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
2716
2717    Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2718    if(npcCreature)
2719    {
2720        npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2721        npcCreature->GetMotionMaster()->Initialize();
2722        if(npcCreature->isAlive())                          // dead creature will reset movement generator at respawn
2723        {
2724            npcCreature->setDeathState(JUST_DIED);
2725            npcCreature->Respawn();
2726        }
2727    }
2728    PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2729
2730    return true;
2731}
2732
2733/**
2734 * .wp show info | on | off
2735 *
2736 * info -> User has selected a visual waypoint before
2737 *
2738 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2739 *                        provided the GUID of the NPC and the number of
2740 *                        the waypoint.
2741 *
2742 * on -> User has selected an NPC; all visual waypoints for this
2743 *       NPC are added to 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 added from the world.
2748 *
2749 * off -> User has selected an NPC; all visual waypoints for this
2750 *        NPC are removed from the world.
2751 *
2752 * on <GUID> -> User did not select an NPC - instead the GUID of the
2753 *              NPC is provided. All visual waypoints for this NPC
2754 *              are removed from the world.
2755 *
2756 *
2757 */
2758bool ChatHandler::HandleWpShowCommand(const char* args)
2759{
2760    sLog.outDebug("DEBUG: HandleWpShowCommand");
2761
2762    if(!*args)
2763        return false;
2764
2765    // first arg: on, off, first, last
2766    char* show_str = strtok((char*)args, " ");
2767    if (!show_str)
2768    {
2769        return false;
2770    }
2771    // second arg: GUID (optional, if a creature is selected)
2772    char* guid_str = strtok((char*)NULL, " ");
2773    sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2774    //if (!guid_str) {
2775    //    return false;
2776    //}
2777
2778    // Did user provide a GUID
2779    // or did the user select a creature?
2780    // -> variable lowguid is filled with the GUID
2781    Creature* target = getSelectedCreature();
2782    // Did player provide a GUID?
2783    if (!guid_str)
2784    {
2785        sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2786        // No GUID provided
2787        // -> Player must have selected a creature
2788
2789        if(!target)
2790        {
2791            SendSysMessage(LANG_SELECT_CREATURE);
2792            SetSentErrorMessage(true);
2793            return false;
2794        }
2795    }
2796    else
2797    {
2798        sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2799        // GUID provided
2800        // Warn if player also selected a creature
2801        // -> Creature selection is ignored <-
2802        if(target)
2803        {
2804            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2805        }
2806
2807        uint32 lowguid = atoi((char*)guid_str);
2808
2809        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2810        if(!data)
2811        {
2812            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2813            SetSentErrorMessage(true);
2814            return false;
2815        }
2816
2817        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2818
2819        if(!target)
2820        {
2821            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2822            SetSentErrorMessage(true);
2823            return false;
2824        }
2825    }
2826
2827    uint32 lowguid = target->GetDBTableGUIDLow();
2828
2829    std::string show = show_str;
2830    uint32 Maxpoint;
2831
2832    sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid, show_str);
2833
2834    // Show info for the selected waypoint
2835    if(show == "info")
2836    {
2837        PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
2838
2839        // Check if the user did specify a visual waypoint
2840        if( target->GetEntry() != VISUAL_WAYPOINT )
2841        {
2842            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2843            SetSentErrorMessage(true);
2844            return false;
2845        }
2846
2847        //PSendSysMessage("wp on, GUID: %u", lowguid);
2848
2849        //pCreature->GetPositionX();
2850
2851        QueryResult *result =
2852            WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2853            target->GetGUIDLow() );
2854        if(!result)
2855        {
2856            // Since we compare float values, we have to deal with
2857            // some difficulties.
2858            // Here we search for all waypoints that only differ in one from 1 thousand
2859            // (0.001) - There is no other way to compare C++ floats with mySQL floats
2860            // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2861            const char* maxDIFF = "0.01";
2862            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
2863
2864            result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2865                target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2866            if(!result)
2867            {
2868                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2869                SetSentErrorMessage(true);
2870                return false;
2871            }
2872        }
2873        do
2874        {
2875            Field *fields = result->Fetch();
2876            uint32 creGUID          = fields[0].GetUInt32();
2877            uint32 point            = fields[1].GetUInt32();
2878            int waittime            = fields[2].GetUInt32();
2879            uint32 emote            = fields[3].GetUInt32();
2880            uint32 spell            = fields[4].GetUInt32();
2881            uint32 textid[MAX_WAYPOINT_TEXT];
2882            for(int i = 0;  i < MAX_WAYPOINT_TEXT; ++i)
2883                textid[i]           = fields[5+i].GetUInt32();
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            for(int i = 0;  i < MAX_WAYPOINT_TEXT; ++i)
2897                PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, i+1, textid[i], (textid[i] ? GetTrinityString(textid[i]) : ""));
2898
2899        }while( result->NextRow() );
2900        // Cleanup memory
2901        delete result;
2902        return true;
2903    }
2904
2905    if(show == "on")
2906    {
2907        PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
2908
2909        QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
2910        if(!result)
2911        {
2912            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2913            SetSentErrorMessage(true);
2914            return false;
2915        }
2916        // Delete all visuals for this NPC
2917        QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
2918        if(result2)
2919        {
2920            bool hasError = false;
2921            do
2922            {
2923                Field *fields = result2->Fetch();
2924                uint32 wpguid = fields[0].GetUInt32();
2925                Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2926
2927                if(!pCreature)
2928                {
2929                    PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
2930                    hasError = true;
2931                    WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
2932                }
2933                else
2934                {
2935                    pCreature->DeleteFromDB();
2936                    pCreature->CleanupsBeforeDelete();
2937                    pCreature->AddObjectToRemoveList();
2938                }
2939
2940            }while( result2->NextRow() );
2941            delete result2;
2942            if( hasError )
2943            {
2944                PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2945                PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2946                PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2947            }
2948        }
2949
2950        do
2951        {
2952            Field *fields = result->Fetch();
2953            uint32 point    = fields[0].GetUInt32();
2954            float x         = fields[1].GetFloat();
2955            float y         = fields[2].GetFloat();
2956            float z         = fields[3].GetFloat();
2957
2958            uint32 id = VISUAL_WAYPOINT;
2959
2960            Player *chr = m_session->GetPlayer();
2961            Map *map = chr->GetMap();
2962            float o = chr->GetOrientation();
2963
2964            Creature* wpCreature = new Creature;
2965            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
2966            {
2967                PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
2968                delete wpCreature;
2969                delete result;
2970                return false;
2971            }
2972
2973            wpCreature->Relocate(x, y, z, o);
2974
2975            if(!wpCreature->IsPositionValid())
2976            {
2977                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());
2978                delete wpCreature;
2979                delete result;
2980                return false;
2981            }
2982
2983            wpCreature->SetVisibility(VISIBILITY_OFF);
2984            sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
2985            // set "wpguid" column to the visual waypoint
2986            WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
2987
2988            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2989            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2990            wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
2991            map->Add(wpCreature);
2992            //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
2993        }while( result->NextRow() );
2994
2995        // Cleanup memory
2996        delete result;
2997        return true;
2998    }
2999
3000    if(show == "first")
3001    {
3002        PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3003
3004        QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3005        if(!result)
3006        {
3007            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3008            SetSentErrorMessage(true);
3009            return false;
3010        }
3011
3012        Field *fields = result->Fetch();
3013        float x         = fields[0].GetFloat();
3014        float y         = fields[1].GetFloat();
3015        float z         = fields[2].GetFloat();
3016        uint32 id = VISUAL_WAYPOINT;
3017
3018        Player *chr = m_session->GetPlayer();
3019        float o = chr->GetOrientation();
3020        Map *map = chr->GetMap();
3021
3022        Creature* pCreature = new Creature;
3023        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
3024        {
3025            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3026            delete pCreature;
3027            delete result;
3028            return false;
3029        }
3030
3031        pCreature->Relocate(x, y, z, o);
3032
3033        if(!pCreature->IsPositionValid())
3034        {
3035            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());
3036            delete pCreature;
3037            delete result;
3038            return false;
3039        }
3040
3041        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3042        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3043        map->Add(pCreature);
3044        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3045
3046        // Cleanup memory
3047        delete result;
3048        return true;
3049    }
3050
3051    if(show == "last")
3052    {
3053        PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3054
3055        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3056        if( result )
3057        {
3058            Maxpoint = (*result)[0].GetUInt32();
3059
3060            delete result;
3061        }
3062        else
3063            Maxpoint = 0;
3064
3065        result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3066        if(!result)
3067        {
3068            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3069            SetSentErrorMessage(true);
3070            return false;
3071        }
3072        Field *fields = result->Fetch();
3073        float x         = fields[0].GetFloat();
3074        float y         = fields[1].GetFloat();
3075        float z         = fields[2].GetFloat();
3076        uint32 id = VISUAL_WAYPOINT;
3077
3078        Player *chr = m_session->GetPlayer();
3079        float o = chr->GetOrientation();
3080        Map *map = chr->GetMap();
3081
3082        Creature* pCreature = new Creature;
3083        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3084        {
3085            PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3086            delete pCreature;
3087            delete result;
3088            return false;
3089        }
3090
3091        pCreature->Relocate(x, y, z, o);
3092
3093        if(!pCreature->IsPositionValid())
3094        {
3095            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());
3096            delete pCreature;
3097            delete result;
3098            return false;
3099        }
3100
3101        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3102        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3103        map->Add(pCreature);
3104        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3105        // Cleanup memory
3106        delete result;
3107        return true;
3108    }
3109
3110    if(show == "off")
3111    {
3112        QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3113        if(!result)
3114        {
3115            SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3116            SetSentErrorMessage(true);
3117            return false;
3118        }
3119        bool hasError = false;
3120        do
3121        {
3122            Field *fields = result->Fetch();
3123            uint32 guid = fields[0].GetUInt32();
3124            Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3125
3126            //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3127
3128            if(!pCreature)
3129            {
3130                PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3131                hasError = true;
3132                WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3133            }
3134            else
3135            {
3136                pCreature->DeleteFromDB();
3137                pCreature->CleanupsBeforeDelete();
3138                pCreature->AddObjectToRemoveList();
3139            }
3140        }while(result->NextRow());
3141        // set "wpguid" column to "empty" - no visual waypoint spawned
3142        WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3143
3144        if( hasError )
3145        {
3146            PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3147            PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3148            PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3149        }
3150
3151        SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3152        // Cleanup memory
3153        delete result;
3154
3155        return true;
3156    }
3157
3158    PSendSysMessage("DEBUG: wpshow - no valid command found");
3159
3160    return true;
3161}                                                           // HandleWpShowCommand
3162
3163bool ChatHandler::HandleWpExportCommand(const char *args)
3164{
3165    if(!*args)
3166        return false;
3167
3168    // Next arg is: <GUID> <ARGUMENT>
3169
3170    // Did user provide a GUID
3171    // or did the user select a creature?
3172    // -> variable lowguid is filled with the GUID of the NPC
3173    uint32 lowguid = 0;
3174    Creature* target = getSelectedCreature();
3175    char* arg_str = NULL;
3176    if (target)
3177    {
3178        if (target->GetEntry() != VISUAL_WAYPOINT)
3179            lowguid = target->GetGUIDLow();
3180        else
3181        {
3182            QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3183            if (!result)
3184            {
3185                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3186                return true;
3187            }
3188            Field *fields = result->Fetch();
3189            lowguid = fields[0].GetUInt32();;
3190            delete result;
3191        }
3192
3193        arg_str = strtok((char*)args, " ");
3194    }
3195    else
3196    {
3197        // user provided <GUID>
3198        char* guid_str = strtok((char*)args, " ");
3199        if( !guid_str )
3200        {
3201            SendSysMessage(LANG_WAYPOINT_NOGUID);
3202            return false;
3203        }
3204        lowguid = atoi((char*)guid_str);
3205
3206        arg_str = strtok((char*)NULL, " ");
3207    }
3208
3209    if( !arg_str)
3210    {
3211        PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3212        return false;
3213    }
3214
3215    PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3216
3217    QueryResult *result = WorldDatabase.PQuery(
3218    //          0      1           2           3           4            5       6       7         8      9      10       11       12       13       14       15
3219        "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
3220
3221    if (!result)
3222    {
3223        PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3224        SetSentErrorMessage(true);
3225        return false;
3226    }
3227
3228    std::ofstream outfile;
3229    outfile.open (arg_str);
3230
3231    do
3232    {
3233        Field *fields = result->Fetch();
3234
3235        outfile << "INSERT INTO creature_movement ";
3236        outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3237
3238        outfile << "( ";
3239        outfile << fields[15].GetUInt32();                  // id
3240        outfile << ", ";
3241        outfile << fields[0].GetUInt32();                   // point
3242        outfile << ", ";
3243        outfile << fields[1].GetFloat();                    // position_x
3244        outfile << ", ";
3245        outfile << fields[2].GetFloat();                    // position_y
3246        outfile << ", ";
3247        outfile << fields[3].GetUInt32();                   // position_z
3248        outfile << ", ";
3249        outfile << fields[4].GetUInt32();                   // orientation
3250        outfile << ", ";
3251        outfile << fields[5].GetUInt32();                   // model1
3252        outfile << ", ";
3253        outfile << fields[6].GetUInt32();                   // model2
3254        outfile << ", ";
3255        outfile << fields[7].GetUInt16();                   // waittime
3256        outfile << ", ";
3257        outfile << fields[8].GetUInt32();                   // emote
3258        outfile << ", ";
3259        outfile << fields[9].GetUInt32();                   // spell
3260        outfile << ", ";
3261        outfile << fields[10].GetUInt32();                  // textid1
3262        outfile << ", ";
3263        outfile << fields[11].GetUInt32();                  // textid2
3264        outfile << ", ";
3265        outfile << fields[12].GetUInt32();                  // textid3
3266        outfile << ", ";
3267        outfile << fields[13].GetUInt32();                  // textid4
3268        outfile << ", ";
3269        outfile << fields[14].GetUInt32();                  // textid5
3270        outfile << ");\n ";
3271
3272    } while( result->NextRow() );
3273    delete result;
3274
3275    PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3276    outfile.close();
3277
3278    return true;
3279}
3280
3281bool ChatHandler::HandleWpImportCommand(const char *args)
3282{
3283    if(!*args)
3284        return false;
3285
3286    char* arg_str = strtok((char*)args, " ");
3287    if (!arg_str)
3288        return false;
3289
3290    std::string line;
3291    std::ifstream infile (arg_str);
3292    if (infile.is_open())
3293    {
3294        while (! infile.eof() )
3295        {
3296            getline (infile,line);
3297            //cout << line << endl;
3298            QueryResult *result = WorldDatabase.Query(line.c_str());
3299            delete result;
3300        }
3301        infile.close();
3302    }
3303    PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3304
3305    return true;
3306}
3307
3308//rename characters
3309bool ChatHandler::HandleRenameCommand(const char* args)
3310{
3311    Player* target = NULL;
3312    uint64 targetGUID = 0;
3313    std::string oldname;
3314
3315    char* px = strtok((char*)args, " ");
3316
3317    if(px)
3318    {
3319        oldname = px;
3320
3321        if(!normalizePlayerName(oldname))
3322        {
3323            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3324            SetSentErrorMessage(true);
3325            return false;
3326        }
3327
3328        target = objmgr.GetPlayer(oldname.c_str());
3329
3330        if (!target)
3331            targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3332    }
3333
3334    if(!target && !targetGUID)
3335    {
3336        target = getSelectedPlayer();
3337    }
3338
3339    if(!target && !targetGUID)
3340    {
3341        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3342        SetSentErrorMessage(true);
3343        return false;
3344    }
3345
3346    if(target)
3347    {
3348        PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
3349        target->SetAtLoginFlag(AT_LOGIN_RENAME);
3350        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3351    }
3352    else
3353    {
3354        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
3355        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3356    }
3357
3358    return true;
3359}
3360
3361//spawn go
3362bool ChatHandler::HandleGameObjectCommand(const char* args)
3363{
3364    if (!*args)
3365        return false;
3366
3367    char* pParam1 = strtok((char*)args, " ");
3368    if (!pParam1)
3369        return false;
3370
3371    uint32 id = atoi((char*)pParam1);
3372    if(!id)
3373        return false;
3374
3375    char* spawntimeSecs = strtok(NULL, " ");
3376
3377    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
3378
3379    if (!goI)
3380    {
3381        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
3382        SetSentErrorMessage(true);
3383        return false;
3384    }
3385
3386    Player *chr = m_session->GetPlayer();
3387    float x = float(chr->GetPositionX());
3388    float y = float(chr->GetPositionY());
3389    float z = float(chr->GetPositionZ());
3390    float o = float(chr->GetOrientation());
3391    Map *map = chr->GetMap();
3392
3393    float rot2 = sin(o/2);
3394    float rot3 = cos(o/2);
3395
3396    GameObject* pGameObj = new GameObject;
3397    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
3398
3399    if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
3400    {
3401        delete pGameObj;
3402        return false;
3403    }
3404
3405    if( spawntimeSecs )
3406    {
3407        uint32 value = atoi((char*)spawntimeSecs);
3408        pGameObj->SetRespawnTime(value);
3409        //sLog.outDebug("*** spawntimeSecs: %d", value);
3410    }
3411
3412    // fill the gameobject data and save to the db
3413    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3414
3415    // this will generate a new guid if the object is in an instance
3416    if(!pGameObj->LoadFromDB(db_lowGUID, map))
3417    {
3418        delete pGameObj;
3419        return false;
3420    }
3421
3422    sLog.outDebug(GetTrinityString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
3423
3424    map->Add(pGameObj);
3425
3426    // TODO: is it really necessary to add both the real and DB table guid here ?
3427    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
3428
3429    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
3430    return true;
3431}
3432
3433//show animation
3434bool ChatHandler::HandleAnimCommand(const char* args)
3435{
3436    if (!*args)
3437        return false;
3438
3439    uint32 anim_id = atoi((char*)args);
3440    m_session->GetPlayer()->HandleEmoteCommand(anim_id);
3441    return true;
3442}
3443
3444//change standstate
3445bool ChatHandler::HandleStandStateCommand(const char* args)
3446{
3447    if (!*args)
3448        return false;
3449
3450    uint32 anim_id = atoi((char*)args);
3451    m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3452
3453    return true;
3454}
3455
3456bool ChatHandler::HandleAddHonorCommand(const char* args)
3457{
3458    if (!*args)
3459        return false;
3460
3461    Player *target = getSelectedPlayer();
3462    if(!target)
3463    {
3464        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3465        SetSentErrorMessage(true);
3466        return false;
3467    }
3468
3469    uint32 amount = (uint32)atoi(args);
3470    target->RewardHonor(NULL, 1, amount);
3471    return true;
3472}
3473
3474bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3475{
3476    Unit *target = getSelectedUnit();
3477    if(!target)
3478    {
3479        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3480        SetSentErrorMessage(true);
3481        return false;
3482    }
3483
3484    m_session->GetPlayer()->RewardHonor(target, 1);
3485    return true;
3486}
3487
3488bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3489{
3490    Player *target = getSelectedPlayer();
3491    if(!target)
3492    {
3493        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3494        SetSentErrorMessage(true);
3495        return false;
3496    }
3497
3498    target->UpdateHonorFields();
3499    return true;
3500}
3501
3502bool ChatHandler::HandleLookupEventCommand(const char* args)
3503{
3504    if(!*args)
3505        return false;
3506
3507    std::string namepart = args;
3508    std::wstring wnamepart;
3509
3510    // converting string that we try to find to lower case
3511    if(!Utf8toWStr(namepart,wnamepart))
3512        return false;
3513
3514    wstrToLower(wnamepart);
3515
3516    uint32 counter = 0;
3517
3518    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3519    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3520
3521    for(uint32 id = 0; id < events.size(); ++id )
3522    {
3523        GameEventData const& eventData = events[id];
3524
3525        std::string descr = eventData.description;
3526        if(descr.empty())
3527            continue;
3528
3529        if (Utf8FitTo(descr, wnamepart))
3530        {
3531            char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : "";
3532           
3533                        if(m_session)
3534                                PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
3535                        else
3536                                PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
3537
3538            ++counter;
3539        }
3540    }
3541
3542    if (counter==0)
3543        SendSysMessage(LANG_NOEVENTFOUND);
3544
3545    return true;
3546}
3547
3548bool ChatHandler::HandleEventActiveListCommand(const char* args)
3549{
3550    uint32 counter = 0;
3551
3552    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3553    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3554
3555    char const* active = GetTrinityString(LANG_ACTIVE);
3556
3557    for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3558    {
3559        uint32 event_id = *itr;
3560        GameEventData const& eventData = events[event_id];
3561
3562        if(m_session)
3563                        PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
3564                else
3565                        PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
3566
3567        ++counter;
3568    }
3569
3570    if (counter==0)
3571        SendSysMessage(LANG_NOEVENTFOUND);
3572
3573    return true;
3574}
3575
3576bool ChatHandler::HandleEventInfoCommand(const char* args)
3577{
3578    if(!*args)
3579        return false;
3580
3581    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3582    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3583    if(!cId)
3584        return false;
3585
3586    uint32 event_id = atoi(cId);
3587
3588    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3589
3590    if(event_id >=events.size())
3591    {
3592        SendSysMessage(LANG_EVENT_NOT_EXIST);
3593        SetSentErrorMessage(true);
3594        return false;
3595    }
3596
3597    GameEventData const& eventData = events[event_id];
3598    if(!eventData.isValid())
3599    {
3600        SendSysMessage(LANG_EVENT_NOT_EXIST);
3601        SetSentErrorMessage(true);
3602        return false;
3603    }
3604
3605    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3606    bool active = activeEvents.find(event_id) != activeEvents.end();
3607    char const* activeStr = active ? GetTrinityString(LANG_ACTIVE) : "";
3608
3609    std::string startTimeStr = TimeToTimestampStr(eventData.start);
3610    std::string endTimeStr = TimeToTimestampStr(eventData.end);
3611
3612    uint32 delay = gameeventmgr.NextCheck(event_id);
3613    time_t nextTime = time(NULL)+delay;
3614    std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3615
3616    std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3617    std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3618
3619    PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3620        startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3621        nextStr.c_str());
3622    return true;
3623}
3624
3625bool ChatHandler::HandleEventStartCommand(const char* args)
3626{
3627    if(!*args)
3628        return false;
3629
3630    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3631    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3632    if(!cId)
3633        return false;
3634
3635    int32 event_id = atoi(cId);
3636
3637    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3638
3639    if(event_id < 1 || event_id >=events.size())
3640    {
3641        SendSysMessage(LANG_EVENT_NOT_EXIST);
3642        SetSentErrorMessage(true);
3643        return false;
3644    }
3645
3646    GameEventData const& eventData = events[event_id];
3647    if(!eventData.isValid())
3648    {
3649        SendSysMessage(LANG_EVENT_NOT_EXIST);
3650        SetSentErrorMessage(true);
3651        return false;
3652    }
3653
3654    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3655    if(activeEvents.find(event_id) != activeEvents.end())
3656    {
3657        PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
3658        SetSentErrorMessage(true);
3659        return false;
3660    }
3661
3662    gameeventmgr.StartEvent(event_id,true);
3663    return true;
3664}
3665
3666bool ChatHandler::HandleEventStopCommand(const char* args)
3667{
3668    if(!*args)
3669        return false;
3670
3671    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3672    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3673    if(!cId)
3674        return false;
3675
3676    int32 event_id = atoi(cId);
3677
3678    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3679
3680    if(event_id < 1 || event_id >=events.size())
3681    {
3682        SendSysMessage(LANG_EVENT_NOT_EXIST);
3683        SetSentErrorMessage(true);
3684        return false;
3685    }
3686
3687    GameEventData const& eventData = events[event_id];
3688    if(!eventData.isValid())
3689    {
3690        SendSysMessage(LANG_EVENT_NOT_EXIST);
3691        SetSentErrorMessage(true);
3692        return false;
3693    }
3694
3695    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3696
3697    if(activeEvents.find(event_id) == activeEvents.end())
3698    {
3699        PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
3700        SetSentErrorMessage(true);
3701        return false;
3702    }
3703
3704    gameeventmgr.StopEvent(event_id,true);
3705    return true;
3706}
3707
3708bool ChatHandler::HandleCombatStopCommand(const char* args)
3709{
3710    Player *player;
3711
3712    if(*args)
3713    {
3714        std::string playername = args;
3715
3716        if(!normalizePlayerName(playername))
3717        {
3718            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3719            SetSentErrorMessage(true);
3720            return false;
3721        }
3722
3723        player = objmgr.GetPlayer(playername.c_str());
3724
3725        if(!player)
3726        {
3727            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3728            SetSentErrorMessage(true);
3729            return false;
3730        }
3731    }
3732    else
3733    {
3734        player = getSelectedPlayer();
3735
3736        if (!player)
3737            player = m_session->GetPlayer();
3738    }
3739
3740    player->CombatStop();
3741    player->getHostilRefManager().deleteReferences();
3742    return true;
3743}
3744
3745bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3746{
3747    uint32 classmask = m_session->GetPlayer()->getClassMask();
3748
3749    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3750    {
3751        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3752        if( !skillInfo )
3753            continue;
3754
3755        if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
3756        {
3757            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3758            {
3759                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3760                if( !skillLine )
3761                    continue;
3762
3763                // skip racial skills
3764                if( skillLine->racemask != 0 )
3765                    continue;
3766
3767                // skip wrong class skills
3768                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3769                    continue;
3770
3771                if( skillLine->skillId != i || skillLine->forward_spellid )
3772                    continue;
3773
3774                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3775                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3776                    continue;
3777
3778                m_session->GetPlayer()->learnSpell(skillLine->spellId);
3779            }
3780        }
3781    }
3782
3783    SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
3784    return true;
3785}
3786
3787bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
3788{
3789    //  Learns all recipes of specified profession and sets skill to max
3790    //  Example: .learn all_recipes enchanting
3791
3792    Player* target = getSelectedPlayer();
3793    if( !target )
3794    {
3795        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3796        return false;
3797    }
3798
3799    if (!*args)
3800        return false;
3801
3802    std::wstring wnamepart;
3803
3804    if(!Utf8toWStr(args,wnamepart))
3805        return false;
3806
3807    uint32 counter = 0;                                     // Counter for figure out that we found smth.
3808
3809    // converting string that we try to find to lower case
3810    wstrToLower( wnamepart );
3811
3812    uint32 classmask = m_session->GetPlayer()->getClassMask();
3813
3814    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3815    {
3816        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3817        if( !skillInfo )
3818            continue;
3819
3820        if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
3821            skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
3822            continue;
3823
3824        int loc = m_session->GetSessionDbcLocale();
3825        std::string name = skillInfo->name[loc];
3826
3827        if(Utf8FitTo(name, wnamepart))
3828        {
3829            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3830            {
3831                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3832                if( !skillLine )
3833                    continue;
3834
3835                if( skillLine->skillId != i || skillLine->forward_spellid )
3836                    continue;
3837
3838                // skip racial skills
3839                if( skillLine->racemask != 0 )
3840                    continue;
3841
3842                // skip wrong class skills
3843                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3844                    continue;
3845
3846                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3847                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3848                    continue;
3849
3850                if( !target->HasSpell(spellInfo->Id) )
3851                    m_session->GetPlayer()->learnSpell(skillLine->spellId);
3852            }
3853
3854            uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
3855            target->SetSkill(skillInfo->id, maxLevel, maxLevel);
3856            PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
3857            return true;
3858        }
3859    }
3860
3861    return false;
3862}
3863
3864bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
3865{
3866 
3867    if (!*args)
3868        return false;
3869
3870    std::string ip = strtok ((char*)args, " ");
3871        char* limit_str = strtok (NULL, " ");
3872        int32 limit = limit_str ? atoi (limit_str) : -1;
3873
3874    loginDatabase.escape_string (ip);
3875
3876    QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
3877
3878    return LookupPlayerSearchCommand (result,limit);
3879}
3880
3881bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
3882{
3883    if (!*args)
3884        return false;
3885
3886    std::string account = strtok ((char*)args, " ");
3887        char* limit_str = strtok (NULL, " ");
3888        int32 limit = limit_str ? atoi (limit_str) : -1;
3889
3890    if (!AccountMgr::normilizeString (account))
3891        return false;
3892
3893    loginDatabase.escape_string (account);
3894
3895    QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
3896
3897    return LookupPlayerSearchCommand (result,limit);
3898}
3899
3900bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
3901{
3902 
3903    if (!*args)
3904        return false;
3905
3906    std::string email = strtok ((char*)args, " ");
3907        char* limit_str = strtok (NULL, " ");
3908        int32 limit = limit_str ? atoi (limit_str) : -1;
3909
3910    loginDatabase.escape_string (email);
3911
3912    QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
3913
3914    return LookupPlayerSearchCommand (result,limit);
3915}
3916
3917bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
3918{
3919    if(!result)
3920    {
3921        PSendSysMessage(LANG_NO_PLAYERS_FOUND);
3922        SetSentErrorMessage(true);
3923        return false;
3924    }
3925
3926    int i =0;
3927    do
3928    {
3929        Field* fields = result->Fetch();
3930        uint32 acc_id = fields[0].GetUInt32();
3931        std::string acc_name = fields[1].GetCppString();
3932       
3933        QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
3934        if(chars)
3935        {
3936            PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
3937
3938            uint64 guid = 0;
3939            std::string name;
3940
3941            do
3942            {
3943                Field* charfields = chars->Fetch();
3944                guid = charfields[0].GetUInt64();
3945                name = charfields[1].GetCppString();
3946
3947                PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
3948                ++i;
3949
3950            } while( chars->NextRow() && ( limit == -1 || i < limit ) );
3951
3952            delete chars;
3953        }
3954    } while(result->NextRow());
3955
3956    delete result;
3957
3958    return true;
3959}
3960
3961/// Triggering corpses expire check in world
3962bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
3963{
3964        CorpsesErase();
3965        return true;
3966}
3967
3968bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
3969{
3970    Player *target = getSelectedPlayer();
3971
3972    if(!target)
3973    {
3974        PSendSysMessage(LANG_NO_CHAR_SELECTED);
3975        SetSentErrorMessage(true);
3976        return false;
3977        }
3978
3979    // Repair items
3980    target->DurabilityRepairAll(false, 0, false);
3981
3982    PSendSysMessage(LANG_YOU_REPAIR_ITEMS, target->GetName());
3983    if(needReportToTarget(target))
3984        ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetName());
3985    return true;
3986}
3987
3988bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
3989{
3990    Player *player = m_session->GetPlayer();
3991    Creature *creature = getSelectedCreature();
3992
3993    if(!creature)
3994    {
3995        PSendSysMessage(LANG_SELECT_CREATURE);
3996        SetSentErrorMessage(true);
3997        return false;
3998    }
3999
4000    // Follow player - Using pet's default dist and angle
4001    creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
4002
4003    PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
4004    return true;
4005}
4006
4007bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
4008{
4009    Player *player = m_session->GetPlayer();
4010    Creature *creature = getSelectedCreature();
4011
4012    if(!creature)
4013    {
4014        PSendSysMessage(LANG_SELECT_CREATURE);
4015        SetSentErrorMessage(true);
4016        return false;
4017    }
4018
4019    if (creature->GetMotionMaster()->empty() ||
4020        creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
4021    {
4022        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
4023        SetSentErrorMessage(true);
4024        return false;
4025    }
4026
4027    TargetedMovementGenerator<Creature> const* mgen
4028        = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
4029
4030    if(mgen->GetTarget()!=player)
4031    {
4032        PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
4033        SetSentErrorMessage(true);
4034        return false;
4035    }
4036
4037    // reset movement
4038    creature->GetMotionMaster()->MovementExpired(true);
4039
4040    PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
4041    return true;
4042}
4043
4044bool ChatHandler::HandleCreatePetCommand(const char* args)
4045{
4046        Player *player = m_session->GetPlayer();
4047        Creature *creatureTarget = getSelectedCreature();
4048   
4049        if(!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER)
4050        {
4051                PSendSysMessage(LANG_SELECT_CREATURE);
4052                SetSentErrorMessage(true);
4053                return false;
4054        }
4055
4056        CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creatureTarget->GetEntry());
4057        // Creatures with family 0 crashes the server
4058        if(cInfo->family == 0)
4059        {
4060                PSendSysMessage("This creature cannot be tamed. (family id: 0).");
4061                SetSentErrorMessage(true);
4062                return false;
4063        }
4064
4065        if(player->GetPetGUID())
4066        {
4067                PSendSysMessage("You already have a pet");
4068                SetSentErrorMessage(true);
4069                return false;
4070        }
4071
4072        // Everything looks OK, create new pet
4073        Pet* pet = new Pet(HUNTER_PET);
4074
4075        if(!pet->CreateBaseAtCreature(creatureTarget))
4076        {
4077                delete pet;
4078                PSendSysMessage("Error 1");
4079                return false;
4080        }
4081
4082        creatureTarget->setDeathState(JUST_DIED);
4083        creatureTarget->RemoveCorpse();
4084        creatureTarget->SetHealth(0); // just for nice GM-mode view
4085
4086        pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, player->GetGUID());
4087        pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
4088        pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());
4089
4090        if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
4091        {
4092                sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
4093                PSendSysMessage("Error 2");
4094                return false;
4095        }
4096
4097        // prepare visual effect for levelup
4098        pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
4099
4100         pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
4101         // this enables pet details window (Shift+P)
4102         pet->AIM_Initialize();
4103         pet->InitPetCreateSpells();
4104         pet->SetHealth(pet->GetMaxHealth());
4105
4106         MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet);
4107
4108         // visual effect for levelup
4109         pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
4110
4111         player->SetPet(pet);
4112         pet->SavePetToDB(PET_SAVE_AS_CURRENT);
4113         player->PetSpellInitialize();
4114
4115        return true;
4116}
4117
4118bool ChatHandler::HandlePetLearnCommand(const char* args)
4119{
4120        if(!*args)
4121                return false;
4122
4123        Player *plr = m_session->GetPlayer();
4124        Pet *pet = plr->GetPet();
4125
4126        if(!pet)
4127        {
4128                PSendSysMessage("You have no pet");
4129                SetSentErrorMessage(true);
4130                return false;
4131        }
4132
4133        uint32 spellId = extractSpellIdFromLink((char*)args);
4134
4135        if(!spellId || !sSpellStore.LookupEntry(spellId))
4136        return false;
4137
4138        // Check if pet already has it
4139        if(pet->HasSpell(spellId))
4140        {
4141                PSendSysMessage("Pet already has spell: %u", spellId);
4142                SetSentErrorMessage(true);
4143        return false;
4144        }
4145
4146        // Check if spell is valid
4147        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
4148        if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo))
4149    {
4150        PSendSysMessage(LANG_COMMAND_SPELL_BROKEN,spellId);
4151        SetSentErrorMessage(true);
4152        return false;
4153    }
4154
4155        pet->learnSpell(spellId);
4156
4157        PSendSysMessage("Pet has learned spell %u", spellId);
4158        return true;
4159}
4160
4161bool ChatHandler::HandlePetUnlearnCommand(const char *args)
4162{
4163        if(!*args)
4164                return false;
4165
4166        Player *plr = m_session->GetPlayer();
4167        Pet *pet = plr->GetPet();
4168
4169        if(!pet)
4170        {
4171                PSendSysMessage("You have no pet");
4172                SetSentErrorMessage(true);
4173                return false;
4174        }
4175
4176        uint32 spellId = extractSpellIdFromLink((char*)args);
4177
4178        if(pet->HasSpell(spellId))
4179                pet->removeSpell(spellId);
4180        else
4181                PSendSysMessage("Pet doesn't have that spell");
4182
4183        return true;
4184}
4185
4186bool ChatHandler::HandlePetTpCommand(const char *args)
4187{
4188        if(!*args)
4189                return false;
4190
4191        Player *plr = m_session->GetPlayer();
4192        Pet *pet = plr->GetPet();
4193
4194        if(!pet)
4195        {
4196                PSendSysMessage("You have no pet");
4197                SetSentErrorMessage(true);
4198                return false;
4199        }
4200
4201        uint32 tp = atol(args);
4202
4203        pet->SetTP(tp);
4204
4205        PSendSysMessage("Pet's tp changed to %u", tp);
4206        return true;
4207}
4208
4209bool ChatHandler::HandleActivateObjectCommand(const char *args)
4210{
4211        if(!*args)
4212                return false;
4213
4214        char* cId = extractKeyFromLink((char*)args,"Hgameobject");
4215    if(!cId)
4216        return false;
4217
4218    uint32 lowguid = atoi(cId);
4219    if(!lowguid)
4220        return false;
4221
4222    GameObject* obj = NULL;
4223
4224    // by DB guid
4225    if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
4226        obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
4227
4228    if(!obj)
4229    {
4230        PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
4231        SetSentErrorMessage(true);
4232        return false;
4233    }
4234
4235        // Activate
4236        obj->SetLootState(GO_READY);
4237        obj->UseDoorOrButton(10000);
4238
4239        PSendSysMessage("Object activated!");
4240
4241        return true;
4242}
Note: See TracBrowser for help on using the browser.