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

Revision 230, 124.9 kB (checked in by yumileroy, 17 years ago)

[svn] *** Source: MaNGOS ***
* Implement localization of creature/gameobject name that say/yell. Author: evilstar (rewrited by: Vladimir)
* Fix auth login queue. Author: Derex
* Allowed switching INVTYPE_HOLDABLE items during combat, used correct spells for triggering global cooldown at weapon switch. Author: mobel/simak
* Fixed some format arg type/value pairs. Other warnings. Author: Vladimir
* [238_world.sql] Allow have team dependent graveyards at entrance map for instances. Author: Vladimir

NOTE:
Entrance map graveyards selected by same way as local (by distance from entrance) Until DB support will work in old way base at current DB data.

Original author: visagalis
Date: 2008-11-14 17:03:03-06:00

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