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

Revision 6, 123.5 kB (checked in by yumileroy, 17 years ago)

[svn] * Added ACE for Linux and Windows (Thanks Derex for Linux part and partial Windows part)
* Updated to 6721 and 676
* Fixed TrinityScript? logo
* Version updated to 0.2.6721.676

Original author: Neo2003
Date: 2008-10-04 06:17:19-05:00

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