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

Revision 18, 122.3 kB (checked in by yumileroy, 17 years ago)

[svn] * Little fix in RandomMovementGenerator?
* Updated to 6731 and 680

Original author: Neo2003
Date: 2008-10-06 04:48:59-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    char* pitem  = extractKeyFromLink((char*)args,"Hitem");
1241    if (!pitem)
1242    {
1243        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1244        SetSentErrorMessage(true);
1245        return false;
1246    }
1247
1248    uint32 itemId = atol(pitem);
1249
1250    char* fmaxcount = strtok(NULL, " ");                    //add maxcount, default: 0
1251    uint32 maxcount = 0;
1252    if (fmaxcount)
1253        maxcount = atol(fmaxcount);
1254
1255    char* fincrtime = strtok(NULL, " ");                    //add incrtime, default: 0
1256    uint32 incrtime = 0;
1257    if (fincrtime)
1258        incrtime = atol(fincrtime);
1259
1260    char* fextendedcost = strtok(NULL, " ");                //add ExtendedCost, default: 0
1261    uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
1262
1263    Creature* vendor = getSelectedCreature();
1264
1265    uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
1266
1267    if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
1268    {
1269        SetSentErrorMessage(true);
1270        return false;
1271    }
1272
1273    objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
1274
1275    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1276
1277    PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
1278    return true;
1279}
1280
1281//del item from vendor list
1282bool ChatHandler::HandleDelVendorItemCommand(const char* args)
1283{
1284    if (!*args)
1285        return false;
1286
1287    Creature* vendor = getSelectedCreature();
1288    if (!vendor || !vendor->isVendor())
1289    {
1290        SendSysMessage(LANG_COMMAND_VENDORSELECTION);
1291        SetSentErrorMessage(true);
1292        return false;
1293    }
1294
1295    char* pitem  = extractKeyFromLink((char*)args,"Hitem");
1296    if (!pitem)
1297    {
1298        SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1299        SetSentErrorMessage(true);
1300        return false;
1301    }
1302    uint32 itemId = atol(pitem);
1303
1304
1305    if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
1306    {
1307        PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
1308        SetSentErrorMessage(true);
1309        return false;
1310    }
1311
1312    ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1313
1314    PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
1315    return true;
1316}
1317
1318//add move for creature
1319bool ChatHandler::HandleAddMoveCommand(const char* args)
1320{
1321    if(!*args)
1322        return false;
1323
1324    char* guid_str = strtok((char*)args, " ");
1325    char* wait_str = strtok((char*)NULL, " ");
1326
1327    uint32 lowguid = atoi((char*)guid_str);
1328
1329    Creature* pCreature = NULL;
1330
1331    /* FIXME: impossible without entry
1332    if(lowguid)
1333        pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1334    */
1335
1336    // attempt check creature existence by DB data
1337    if(!pCreature)
1338    {
1339        CreatureData const* data = objmgr.GetCreatureData(lowguid);
1340        if(!data)
1341        {
1342            PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1343            SetSentErrorMessage(true);
1344            return false;
1345        }
1346    }
1347    else
1348    {
1349        // obtain real GUID for DB operations
1350        lowguid = pCreature->GetDBTableGUIDLow();
1351    }
1352
1353    int wait = wait_str ? atoi(wait_str) : 0;
1354
1355    if(wait < 0)
1356        wait = 0;
1357
1358    Player* player = m_session->GetPlayer();
1359
1360    WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
1361
1362    // update movement type
1363    WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1364    if(pCreature)
1365    {
1366        pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1367        pCreature->GetMotionMaster()->Initialize();
1368        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1369        {
1370            pCreature->setDeathState(JUST_DIED);
1371            pCreature->Respawn();
1372        }
1373        pCreature->SaveToDB();
1374    }
1375
1376    SendSysMessage(LANG_WAYPOINT_ADDED);
1377
1378    return true;
1379}
1380
1381/**
1382 * Set the movement type for an NPC.<br/>
1383 * <br/>
1384 * Valid movement types are:
1385 * <ul>
1386 * <li> stay - NPC wont move </li>
1387 * <li> random - NPC will move randomly according to the spawndist </li>
1388 * <li> way - NPC will move with given waypoints set </li>
1389 * </ul>
1390 * additional parameter: NODEL - so no waypoints are deleted, if you
1391 *                       change the movement type
1392 */
1393bool ChatHandler::HandleSetMoveTypeCommand(const char* args)
1394{
1395    if(!*args)
1396        return false;
1397
1398    // 3 arguments:
1399    // GUID (optional - you can also select the creature)
1400    // stay|random|way (determines the kind of movement)
1401    // NODEL (optional - tells the system NOT to delete any waypoints)
1402    //        this is very handy if you want to do waypoints, that are
1403    //        later switched on/off according to special events (like escort
1404    //        quests, etc)
1405    char* guid_str = strtok((char*)args, " ");
1406    char* type_str = strtok((char*)NULL, " ");
1407    char* dontdel_str = strtok((char*)NULL, " ");
1408
1409    bool doNotDelete = false;
1410
1411    if(!guid_str)
1412        return false;
1413
1414    uint32 lowguid = 0;
1415    Creature* pCreature = NULL;
1416
1417    if( dontdel_str )
1418    {
1419        //sLog.outError("DEBUG: All 3 params are set");
1420
1421        // All 3 params are set
1422        // GUID
1423        // type
1424        // doNotDEL
1425        if( stricmp( dontdel_str, "NODEL" ) == 0 )
1426        {
1427            //sLog.outError("DEBUG: doNotDelete = true;");
1428            doNotDelete = true;
1429        }
1430    }
1431    else
1432    {
1433        // Only 2 params - but maybe NODEL is set
1434        if( type_str )
1435        {
1436            sLog.outError("DEBUG: Only 2 params ");
1437            if( stricmp( type_str, "NODEL" ) == 0 )
1438            {
1439                //sLog.outError("DEBUG: type_str, NODEL ");
1440                doNotDelete = true;
1441                type_str = NULL;
1442            }
1443        }
1444    }
1445
1446    if(!type_str)                                           // case .setmovetype $move_type (with selected creature)
1447    {
1448        type_str = guid_str;
1449        pCreature = getSelectedCreature();
1450        if(!pCreature)
1451            return false;
1452        lowguid = pCreature->GetDBTableGUIDLow();
1453    }
1454    else                                                    // case .setmovetype #creature_guid $move_type (with selected creature)
1455    {
1456        lowguid = atoi((char*)guid_str);
1457
1458        /* impossible without entry
1459        if(lowguid)
1460            pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1461        */
1462
1463        // attempt check creature existence by DB data
1464        if(!pCreature)
1465        {
1466            CreatureData const* data = objmgr.GetCreatureData(lowguid);
1467            if(!data)
1468            {
1469                PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1470                SetSentErrorMessage(true);
1471                return false;
1472            }
1473        }
1474        else
1475        {
1476            lowguid = pCreature->GetDBTableGUIDLow();
1477        }
1478    }
1479
1480    // now lowguid is low guid really existed creature
1481    // and pCreature point (maybe) to this creature or NULL
1482
1483    MovementGeneratorType move_type;
1484
1485    std::string type = type_str;
1486
1487    if(type == "stay")
1488        move_type = IDLE_MOTION_TYPE;
1489    else if(type == "random")
1490        move_type = RANDOM_MOTION_TYPE;
1491    else if(type == "way")
1492        move_type = WAYPOINT_MOTION_TYPE;
1493    else
1494        return false;
1495
1496    // update movement type
1497    if(doNotDelete == false)
1498        WaypointMgr.DeletePath(lowguid);
1499
1500    if(pCreature)
1501    {
1502        pCreature->SetDefaultMovementType(move_type);
1503        pCreature->GetMotionMaster()->Initialize();
1504        if(pCreature->isAlive())                            // dead creature will reset movement generator at respawn
1505        {
1506            pCreature->setDeathState(JUST_DIED);
1507            pCreature->Respawn();
1508        }
1509        pCreature->SaveToDB();
1510    }
1511    if( doNotDelete == false )
1512    {
1513        PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1514    }
1515    else
1516    {
1517        PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1518    }
1519
1520    return true;
1521}                                                           // HandleSetMoveTypeCommand
1522
1523//change level of creature or pet
1524bool ChatHandler::HandleChangeLevelCommand(const char* args)
1525{
1526    if (!*args)
1527        return false;
1528
1529    uint8 lvl = (uint8) atoi((char*)args);
1530    if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1531    {
1532        SendSysMessage(LANG_BAD_VALUE);
1533        SetSentErrorMessage(true);
1534        return false;
1535    }
1536
1537    Creature* pCreature = getSelectedCreature();
1538    if(!pCreature)
1539    {
1540        SendSysMessage(LANG_SELECT_CREATURE);
1541        SetSentErrorMessage(true);
1542        return false;
1543    }
1544
1545    if(pCreature->isPet())
1546    {
1547        ((Pet*)pCreature)->GivePetLevel(lvl);
1548    }
1549    else
1550    {
1551        pCreature->SetMaxHealth( 100 + 30*lvl);
1552        pCreature->SetHealth( 100 + 30*lvl);
1553        pCreature->SetLevel( lvl);
1554        pCreature->SaveToDB();
1555    }
1556
1557    return true;
1558}
1559
1560//set npcflag of creature
1561bool ChatHandler::HandleNPCFlagCommand(const char* args)
1562{
1563    if (!*args)
1564        return false;
1565
1566    uint32 npcFlags = (uint32) atoi((char*)args);
1567
1568    Creature* pCreature = getSelectedCreature();
1569
1570    if(!pCreature)
1571    {
1572        SendSysMessage(LANG_SELECT_CREATURE);
1573        SetSentErrorMessage(true);
1574        return false;
1575    }
1576
1577    pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1578
1579    WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
1580
1581    SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1582
1583    return true;
1584}
1585
1586//set model of creature
1587bool ChatHandler::HandleSetModelCommand(const char* args)
1588{
1589    if (!*args)
1590        return false;
1591
1592    uint32 displayId = (uint32) atoi((char*)args);
1593
1594    Creature *pCreature = getSelectedCreature();
1595
1596    if(!pCreature)
1597    {
1598        SendSysMessage(LANG_SELECT_CREATURE);
1599        SetSentErrorMessage(true);
1600        return false;
1601    }
1602
1603    pCreature->SetDisplayId(displayId);
1604    pCreature->SetNativeDisplayId(displayId);
1605
1606    pCreature->SaveToDB();
1607
1608    return true;
1609}
1610
1611//morph creature or player
1612bool ChatHandler::HandleMorphCommand(const char* args)
1613{
1614    if (!*args)
1615        return false;
1616
1617    uint16 display_id = (uint16)atoi((char*)args);
1618
1619    Unit *target = getSelectedUnit();
1620    if(!target)
1621        target = m_session->GetPlayer();
1622
1623    target->SetDisplayId(display_id);
1624
1625    return true;
1626}
1627
1628//set faction of creature  or go
1629bool ChatHandler::HandleFactionIdCommand(const char* args)
1630{
1631    if (!*args)
1632        return false;
1633
1634    uint32 factionId = (uint32) atoi((char*)args);
1635
1636    if (!sFactionTemplateStore.LookupEntry(factionId))
1637    {
1638        PSendSysMessage(LANG_WRONG_FACTION, factionId);
1639        SetSentErrorMessage(true);
1640        return false;
1641    }
1642
1643    Creature* pCreature = getSelectedCreature();
1644
1645    if(!pCreature)
1646    {
1647        SendSysMessage(LANG_SELECT_CREATURE);
1648        SetSentErrorMessage(true);
1649        return false;
1650    }
1651
1652    pCreature->setFaction(factionId);
1653
1654    // faction is set in creature_template - not inside creature
1655
1656    // update in memory
1657    if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
1658    {
1659        const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
1660        const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
1661    }
1662
1663    // and DB
1664    WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
1665
1666    return true;
1667}
1668
1669//kick player
1670bool ChatHandler::HandleKickPlayerCommand(const char *args)
1671{
1672    char* kickName = strtok((char*)args, " ");
1673    if (!kickName)
1674    {
1675        Player* player = getSelectedPlayer();
1676
1677        if(!player)
1678        {
1679            SendSysMessage(LANG_NO_CHAR_SELECTED);
1680            SetSentErrorMessage(true);
1681            return false;
1682        }
1683
1684        if(player==m_session->GetPlayer())
1685        {
1686            SendSysMessage(LANG_COMMAND_KICKSELF);
1687            SetSentErrorMessage(true);
1688            return false;
1689        }
1690
1691        player->GetSession()->KickPlayer();
1692    }
1693    else
1694    {
1695        std::string name = kickName;
1696        if(!normalizePlayerName(name))
1697        {
1698            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1699            SetSentErrorMessage(true);
1700            return false;
1701        }
1702
1703        if(name==m_session->GetPlayer()->GetName())
1704        {
1705            SendSysMessage(LANG_COMMAND_KICKSELF);
1706            SetSentErrorMessage(true);
1707            return false;
1708        }
1709
1710        if(sWorld.KickPlayer(name))
1711        {
1712            PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
1713        }
1714        else
1715            PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
1716    }
1717
1718    return true;
1719}
1720
1721//show info of player
1722bool ChatHandler::HandlePInfoCommand(const char* args)
1723{
1724    Player* target = NULL;
1725    uint64 targetGUID = 0;
1726
1727    char* px = strtok((char*)args, " ");
1728    char* py = NULL;
1729
1730    std::string name;
1731
1732    if (px)
1733    {
1734        name = px;
1735
1736        if(name.empty())
1737            return false;
1738
1739        if(!normalizePlayerName(name))
1740        {
1741            SendSysMessage(LANG_PLAYER_NOT_FOUND);
1742            SetSentErrorMessage(true);
1743            return false;
1744        }
1745
1746        target = objmgr.GetPlayer(name.c_str());
1747        if (target)
1748            py = strtok(NULL, " ");
1749        else
1750        {
1751            targetGUID = objmgr.GetPlayerGUIDByName(name);
1752            if(targetGUID)
1753                py = strtok(NULL, " ");
1754            else
1755                py = px;
1756        }
1757    }
1758
1759    if(!target && !targetGUID)
1760    {
1761        target = getSelectedPlayer();
1762    }
1763
1764    if(!target && !targetGUID)
1765    {
1766        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1767        SetSentErrorMessage(true);
1768        return false;
1769    }
1770
1771    uint32 accId = 0;
1772    uint32 money = 0;
1773    uint32 total_player_time = 0;
1774    uint32 level = 0;
1775    uint32 latency = 0;
1776
1777    // get additional information from Player object
1778    if(target)
1779    {
1780        targetGUID = target->GetGUID();
1781        name = target->GetName();                           // re-read for case getSelectedPlayer() target
1782        accId = target->GetSession()->GetAccountId();
1783        money = target->GetMoney();
1784        total_player_time = target->GetTotalPlayedTime();
1785        level = target->getLevel();
1786        latency = target->GetSession()->GetLatency();
1787    }
1788    // get additional information from DB
1789    else
1790    {
1791        accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
1792        Player plr(m_session);                              // use current session for temporary load
1793        plr.MinimalLoadFromDB(NULL, targetGUID);
1794        money = plr.GetMoney();
1795        total_player_time = plr.GetTotalPlayedTime();
1796        level = plr.getLevel();
1797    }
1798
1799    std::string username = GetMangosString(LANG_ERROR);
1800    std::string last_ip = GetMangosString(LANG_ERROR);
1801    uint32 security = 0;
1802    std::string last_login = GetMangosString(LANG_ERROR);
1803
1804    QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
1805    if(result)
1806    {
1807        Field* fields = result->Fetch();
1808        username = fields[0].GetCppString();
1809        security = fields[1].GetUInt32();
1810        if(m_session->GetSecurity() >= security)
1811        {
1812            last_ip = fields[2].GetCppString();
1813            last_login = fields[3].GetCppString();
1814        }
1815        else
1816        {
1817            last_ip = "-";
1818            last_login = "-";
1819        }
1820
1821        delete result;
1822    }
1823
1824    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);
1825
1826    std::string timeStr = secsToTimeString(total_player_time,true,true);
1827    uint32 gold = money /GOLD;
1828    uint32 silv = (money % GOLD) / SILVER;
1829    uint32 copp = (money % GOLD) % SILVER;
1830    PSendSysMessage(LANG_PINFO_LEVEL,  timeStr.c_str(), level, gold,silv,copp );
1831
1832    if ( py && strncmp(py, "rep", 3) == 0 )
1833    {
1834        if(!target)
1835        {
1836            // rep option not implemented for offline case
1837            SendSysMessage(LANG_PINFO_NO_REP);
1838            SetSentErrorMessage(true);
1839            return false;
1840        }
1841
1842        char* FactionName;
1843        for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
1844        {
1845            FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
1846            if (factionEntry)
1847                FactionName = factionEntry->name[m_session->GetSessionDbcLocale()];
1848            else
1849                FactionName = "#Not found#";
1850            ReputationRank rank = target->GetReputationRank(factionEntry);
1851            std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
1852            std::ostringstream ss;
1853            ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
1854
1855            if(itr->second.Flags & FACTION_FLAG_VISIBLE)
1856                ss << GetMangosString(LANG_FACTION_VISIBLE);
1857            if(itr->second.Flags & FACTION_FLAG_AT_WAR)
1858                ss << GetMangosString(LANG_FACTION_ATWAR);
1859            if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
1860                ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
1861            if(itr->second.Flags & FACTION_FLAG_HIDDEN)
1862                ss << GetMangosString(LANG_FACTION_HIDDEN);
1863            if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
1864                ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
1865            if(itr->second.Flags & FACTION_FLAG_INACTIVE)
1866                ss << GetMangosString(LANG_FACTION_INACTIVE);
1867
1868            SendSysMessage(ss.str().c_str());
1869        }
1870    }
1871    return true;
1872}
1873
1874//show tickets
1875void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
1876{
1877    std::string name;
1878    if(!objmgr.GetPlayerNameByGUID(guid,name))
1879        name = GetMangosString(LANG_UNKNOWN);
1880
1881    PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text);
1882}
1883
1884//ticket commands
1885bool ChatHandler::HandleTicketCommand(const char* args)
1886{
1887    char* px = strtok((char*)args, " ");
1888
1889    // ticket<end>
1890    if (!px)
1891    {
1892        size_t count;
1893        QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket");
1894        if(result)
1895        {
1896            count = (*result)[0].GetUInt32();
1897            delete result;
1898        }
1899        else
1900            count = 0;
1901
1902        PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, m_session->GetPlayer()->isAcceptTickets() ?  GetMangosString(LANG_ON) : GetMangosString(LANG_OFF));
1903        return true;
1904    }
1905
1906    // ticket on
1907    if(strncmp(px,"on",3) == 0)
1908    {
1909        m_session->GetPlayer()->SetAcceptTicket(true);
1910        SendSysMessage(LANG_COMMAND_TICKETON);
1911        return true;
1912    }
1913
1914    // ticket off
1915    if(strncmp(px,"off",4) == 0)
1916    {
1917        m_session->GetPlayer()->SetAcceptTicket(false);
1918        SendSysMessage(LANG_COMMAND_TICKETOFF);
1919        return true;
1920    }
1921
1922    // ticket #num
1923    int num = atoi(px);
1924    if(num > 0)
1925    {
1926        QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC LIMIT %d,1",num-1);
1927
1928        if(!result)
1929        {
1930            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1931            delete result;
1932            SetSentErrorMessage(true);
1933            return false;
1934        }
1935
1936        Field* fields = result->Fetch();
1937
1938        uint64 guid = fields[0].GetUInt64();
1939        char const* text = fields[1].GetString();
1940        char const* time = fields[2].GetString();
1941
1942        ShowTicket(guid,text,time);
1943        delete result;
1944        return true;
1945    }
1946
1947    std::string name = px;
1948
1949    if(!normalizePlayerName(name))
1950    {
1951        SendSysMessage(LANG_PLAYER_NOT_FOUND);
1952        SetSentErrorMessage(true);
1953        return false;
1954    }
1955
1956    uint64 guid = objmgr.GetPlayerGUIDByName(name);
1957
1958    if(!guid)
1959        return false;
1960
1961    // ticket $char_name
1962    QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid));
1963
1964    if(!result)
1965        return false;
1966
1967    Field* fields = result->Fetch();
1968
1969    char const* text = fields[0].GetString();
1970    char const* time = fields[1].GetString();
1971
1972    ShowTicket(guid,text,time);
1973    delete result;
1974
1975    return true;
1976}
1977
1978uint32 ChatHandler::GetTicketIDByNum(uint32 num)
1979{
1980    QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket");
1981
1982    if(!result || num > result->GetRowCount())
1983    {
1984        PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1985        delete result;
1986        return 0;
1987    }
1988
1989    for(uint32 i = 1; i < num; ++i)
1990        result->NextRow();
1991
1992    Field* fields = result->Fetch();
1993
1994    uint32 id = fields[0].GetUInt32();
1995    delete result;
1996    return id;
1997}
1998
1999//dell all tickets
2000bool ChatHandler::HandleDelTicketCommand(const char *args)
2001{
2002    char* px = strtok((char*)args, " ");
2003    if (!px)
2004        return false;
2005
2006    // delticket all
2007    if(strncmp(px,"all",4) == 0)
2008    {
2009        QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket");
2010
2011        if(!result)
2012            return true;
2013
2014        // notify players about ticket deleting
2015        do
2016        {
2017            Field* fields = result->Fetch();
2018
2019            uint64 guid = fields[0].GetUInt64();
2020
2021            if(Player* sender = objmgr.GetPlayer(guid))
2022                sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2023
2024        }while(result->NextRow());
2025
2026        delete result;
2027
2028        CharacterDatabase.PExecute("DELETE FROM character_ticket");
2029        SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
2030        return true;
2031    }
2032
2033    int num = (uint32)atoi(px);
2034
2035    // delticket #num
2036    if(num > 0)
2037    {
2038        QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket LIMIT %i",num);
2039
2040        if(!result || uint64(num) > result->GetRowCount())
2041        {
2042            PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2043            delete result;
2044            SetSentErrorMessage(true);
2045            return false;
2046        }
2047
2048        for(int i = 1; i < num; ++i)
2049            result->NextRow();
2050
2051        Field* fields = result->Fetch();
2052
2053        uint32 id   = fields[0].GetUInt32();
2054        uint64 guid = fields[1].GetUInt64();
2055        delete result;
2056
2057        CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id);
2058
2059        // notify players about ticket deleting
2060        if(Player* sender = objmgr.GetPlayer(guid))
2061        {
2062            sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2063            PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName());
2064        }
2065        else
2066            SendSysMessage(LANG_COMMAND_TICKETDEL);
2067
2068        return true;
2069    }
2070
2071    std::string name = px;
2072
2073    if(!normalizePlayerName(name))
2074    {
2075        SendSysMessage(LANG_PLAYER_NOT_FOUND);
2076        SetSentErrorMessage(true);
2077        return false;
2078    }
2079
2080    uint64 guid = objmgr.GetPlayerGUIDByName(name);
2081
2082    if(!guid)
2083        return false;
2084
2085    // delticket $char_name
2086    CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid));
2087
2088    // notify players about ticket deleting
2089    if(Player* sender = objmgr.GetPlayer(guid))
2090        sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2091
2092    PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
2093    return true;
2094}
2095
2096//set spawn dist of creature
2097bool ChatHandler::HandleSpawnDistCommand(const char* args)
2098{
2099    if(!*args)
2100        return false;
2101
2102    float option = atof((char*)args);
2103    if (option < 0.0f)
2104    {
2105        SendSysMessage(LANG_BAD_VALUE);
2106        return false;
2107    }
2108
2109    MovementGeneratorType mtype = IDLE_MOTION_TYPE;
2110    if (option >0.0f)
2111        mtype = RANDOM_MOTION_TYPE;
2112
2113    Creature *pCreature = getSelectedCreature();
2114    uint32 u_guidlow = 0;
2115
2116    if (pCreature)
2117        u_guidlow = pCreature->GetDBTableGUIDLow();
2118    else
2119        return false;
2120
2121    pCreature->SetRespawnRadius((float)option);
2122    pCreature->SetDefaultMovementType(mtype);
2123    pCreature->GetMotionMaster()->Initialize();
2124    if(pCreature->isAlive())                                // dead creature will reset movement generator at respawn
2125    {
2126        pCreature->setDeathState(JUST_DIED);
2127        pCreature->Respawn();
2128    }
2129
2130    WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
2131    PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
2132    return true;
2133}
2134
2135bool ChatHandler::HandleSpawnTimeCommand(const char* args)
2136{
2137    if(!*args)
2138        return false;
2139
2140    char* stime = strtok((char*)args, " ");
2141
2142    if (!stime)
2143        return false;
2144
2145    int i_stime = atoi((char*)stime);
2146
2147    if (i_stime < 0)
2148    {
2149        SendSysMessage(LANG_BAD_VALUE);
2150        SetSentErrorMessage(true);
2151        return false;
2152    }
2153
2154    Creature *pCreature = getSelectedCreature();
2155    uint32 u_guidlow = 0;
2156
2157    if (pCreature)
2158        u_guidlow = pCreature->GetDBTableGUIDLow();
2159    else
2160        return false;
2161
2162    WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
2163    pCreature->SetRespawnDelay((uint32)i_stime);
2164    PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
2165
2166    return true;
2167}
2168
2169/**
2170 * Add a waypoint to a creature.
2171 *
2172 * The user can either select an npc or provide its GUID.
2173 *
2174 * The user can even select a visual waypoint - then the new waypoint
2175 * is placed *after* the selected one - this makes insertion of new
2176 * waypoints possible.
2177 *
2178 * eg:
2179 * .wp add 12345
2180 * -> adds a waypoint to the npc with the GUID 12345
2181 *
2182 * .wp add
2183 * -> adds a waypoint to the currently selected creature
2184 *
2185 *
2186 * @param args if the user did not provide a GUID, it is NULL
2187 *
2188 * @return true - command did succeed, false - something went wrong
2189 */
2190bool ChatHandler::HandleWpAddCommand(const char* args)
2191{
2192    sLog.outDebug("DEBUG: HandleWpAddCommand");
2193
2194    // optional
2195    char* guid_str = NULL;
2196
2197    if(*args)
2198    {
2199        guid_str = strtok((char*)args, " ");
2200    }
2201
2202    uint32 lowguid = 0;
2203    uint32 point = 0;
2204    Creature* target = getSelectedCreature();
2205    // Did player provide a GUID?
2206    if (!guid_str)
2207    {
2208        sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2209
2210        // No GUID provided
2211        // -> Player must have selected a creature
2212
2213        if(!target)
2214        {
2215            SendSysMessage(LANG_SELECT_CREATURE);
2216            SetSentErrorMessage(true);
2217            return false;
2218        }
2219        if (target->GetEntry() == VISUAL_WAYPOINT )
2220        {
2221            sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2222
2223            QueryResult *result =
2224                WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2225                target->GetGUIDLow() );
2226            if(!result)
2227            {
2228                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
2229                // User selected a visual spawnpoint -> get the NPC
2230                // Select NPC GUID
2231                // Since we compare float values, we have to deal with
2232                // some difficulties.
2233                // Here we search for all waypoints that only differ in one from 1 thousand
2234                // (0.001) - There is no other way to compare C++ floats with mySQL floats
2235                // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2236                const char* maxDIFF = "0.01";
2237                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 )",
2238                    target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2239                if(!result)
2240                {
2241                    PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
2242                    SetSentErrorMessage(true);
2243                    return false;
2244                }
2245            }
2246            do
2247            {
2248                Field *fields = result->Fetch();
2249                lowguid = fields[0].GetUInt32();
2250                point   = fields[1].GetUInt32();
2251            }while( result->NextRow() );
2252            delete result;
2253
2254            CreatureData const* data = objmgr.GetCreatureData(lowguid);
2255            if(!data)
2256            {
2257                PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2258                SetSentErrorMessage(true);
2259                return false;
2260            }
2261
2262            target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2263            if(!target)
2264            {
2265                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2266                SetSentErrorMessage(true);
2267                return false;
2268            }
2269        }
2270        else
2271        {
2272            lowguid = target->GetDBTableGUIDLow();
2273        }
2274    }
2275    else
2276    {
2277        sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2278
2279        // GUID provided
2280        // Warn if player also selected a creature
2281        // -> Creature selection is ignored <-
2282        if(target)
2283        {
2284            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2285        }
2286        lowguid = atoi((char*)guid_str);
2287
2288        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2289        if(!data)
2290        {
2291            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2292            SetSentErrorMessage(true);
2293            return false;
2294        }
2295
2296        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2297        if(!target)
2298        {
2299            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2300            SetSentErrorMessage(true);
2301            return false;
2302        }
2303    }
2304    // lowguid -> GUID of the NPC
2305    // point   -> number of the waypoint (if not 0)
2306    sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
2307
2308    sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2309
2310    Player* player = m_session->GetPlayer();
2311    WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
2312
2313    // update movement type
2314    if(target)
2315    {
2316        target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2317        target->GetMotionMaster()->Initialize();
2318        if(target->isAlive())                               // dead creature will reset movement generator at respawn
2319        {
2320            target->setDeathState(JUST_DIED);
2321            target->Respawn();
2322        }
2323        target->SaveToDB();
2324    }
2325    else
2326        WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
2327
2328    PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
2329
2330    return true;
2331}                                                           // HandleWpAddCommand
2332
2333/**
2334 * .wp modify emote | spell | text | del | move | add
2335 *
2336 * add -> add a WP after the selected visual waypoint
2337 *        User must select a visual waypoint and then issue ".wp modify add"
2338 *
2339 * emote <emoteID>
2340 *   User has selected a visual waypoint before.
2341 *   <emoteID> is added to this waypoint. Everytime the
2342 *   NPC comes to this waypoint, the emote is called.
2343 *
2344 * emote <GUID> <WPNUM> <emoteID>
2345 *   User has not selected visual waypoint before.
2346 *   For the waypoint <WPNUM> for the NPC with <GUID>
2347 *   an emote <emoteID> is added.
2348 *   Everytime the NPC comes to this waypoint, the emote is called.
2349 *
2350 *
2351 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2352 */
2353bool ChatHandler::HandleWpModifyCommand(const char* args)
2354{
2355    sLog.outDebug("DEBUG: HandleWpModifyCommand");
2356
2357    if(!*args)
2358        return false;
2359
2360    // first arg: add del text emote spell waittime move
2361    char* show_str = strtok((char*)args, " ");
2362    if (!show_str)
2363    {
2364        return false;
2365    }
2366
2367    std::string show = show_str;
2368    // Check
2369    // Remember: "show" must also be the name of a column!
2370    if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2")
2371        && (show != "text3") && (show != "text4") && (show != "text5")
2372        && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
2373        && (show != "model1") && (show != "model2") && (show != "orientation"))
2374    {
2375        return false;
2376    }
2377
2378    // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2379
2380    // Did user provide a GUID
2381    // or did the user select a creature?
2382    // -> variable lowguid is filled with the GUID of the NPC
2383    uint32 lowguid = 0;
2384    uint32 point = 0;
2385    uint32 wpGuid = 0;
2386    Creature* target = getSelectedCreature();
2387
2388    if(target)
2389    {
2390        sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2391
2392        // Did the user select a visual spawnpoint?
2393        if (target->GetEntry() != VISUAL_WAYPOINT )
2394        {
2395            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2396            SetSentErrorMessage(true);
2397            return false;
2398        }
2399
2400        wpGuid = target->GetGUIDLow();
2401
2402        // The visual waypoint
2403        QueryResult *result =
2404            WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2405            target->GetGUIDLow() );
2406        if(!result)
2407        {
2408            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
2409            SetSentErrorMessage(true);
2410            return false;
2411        }
2412        sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2413
2414        Field *fields = result->Fetch();
2415        lowguid = fields[0].GetUInt32();
2416        point   = fields[1].GetUInt32();
2417
2418        // Cleanup memory
2419        sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2420        delete result;
2421    }
2422    else
2423    {
2424        // User did provide <GUID> <WPNUM>
2425
2426        char* guid_str = strtok((char*)NULL, " ");
2427        if( !guid_str )
2428        {
2429            SendSysMessage(LANG_WAYPOINT_NOGUID);
2430            return false;
2431        }
2432        lowguid = atoi((char*)guid_str);
2433
2434        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2435        if(!data)
2436        {
2437            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2438            SetSentErrorMessage(true);
2439            return false;
2440        }
2441
2442        PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2443
2444        char* point_str = strtok((char*)NULL, " ");
2445        if( !point_str )
2446        {
2447            SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2448            return false;
2449        }
2450        point    = atoi((char*)point_str);
2451
2452        PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2453
2454        // Now we need the GUID of the visual waypoint
2455        // -> "del", "move", "add" command
2456
2457        QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
2458        if (!result)
2459        {
2460            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2461            SetSentErrorMessage(true);
2462            return false;
2463        }
2464
2465        Field *fields = result->Fetch();
2466        wpGuid  = fields[0].GetUInt32();
2467
2468        // Free memory
2469        delete result;
2470    }
2471
2472    char* arg_str = NULL;
2473    // Check for argument
2474    if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
2475    {
2476        // Text is enclosed in "<>", all other arguments not
2477        if( show.find("text") != std::string::npos )
2478            arg_str = strtok((char*)NULL, "<>");
2479        else
2480            arg_str = strtok((char*)NULL, " ");
2481
2482        if( !arg_str)
2483        {
2484            PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2485            return false;
2486        }
2487    }
2488
2489    sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2490
2491    // wpGuid  -> GUID of the waypoint creature
2492    // lowguid -> GUID of the NPC
2493    // point   -> waypoint number
2494
2495    // Special functions:
2496    // add - move - del -> no args commands
2497    // Add a waypoint after the selected visual
2498    if(show == "add" && target)
2499    {
2500        PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2501
2502        // Get the creature for which we read the waypoint
2503        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2504        if(!data)
2505        {
2506            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2507            SetSentErrorMessage(true);
2508            return false;
2509        }
2510
2511        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2512
2513        if( !npcCreature )
2514        {
2515            PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2516            SetSentErrorMessage(true);
2517            return false;
2518        }
2519
2520        sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2521
2522        // What to do:
2523        // Add the visual spawnpoint (DB only)
2524        // Adjust the waypoints
2525        // Respawn the owner of the waypoints
2526        sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
2527
2528        Player* chr = m_session->GetPlayer();
2529        Map *map = chr->GetMap();
2530
2531        if(npcCreature)
2532        {
2533            npcCreature->GetMotionMaster()->Initialize();
2534            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
2535            {
2536                npcCreature->setDeathState(JUST_DIED);
2537                npcCreature->Respawn();
2538            }
2539        }
2540
2541        // create the waypoint creature
2542        wpGuid = 0;
2543        Creature* wpCreature = new Creature;
2544        if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
2545        {
2546            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2547            delete wpCreature;
2548        }
2549        else
2550        {
2551            wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2552
2553            if(!wpCreature->IsPositionValid())
2554            {
2555                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());
2556                delete wpCreature;
2557            }
2558            else
2559            {
2560                wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2561                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2562                wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
2563                map->Add(wpCreature);
2564                wpGuid = wpCreature->GetGUIDLow();
2565            }
2566        }
2567
2568        WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
2569
2570        if(!wpGuid)
2571            return false;
2572
2573        PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2574        return true;
2575    }                                                       // add
2576
2577    if(show == "del" && target)
2578    {
2579        PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2580
2581        // Get the creature for which we read the waypoint
2582        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2583        if(!data)
2584        {
2585            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2586            SetSentErrorMessage(true);
2587            return false;
2588        }
2589
2590        Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2591
2592        // wpCreature
2593        Creature* wpCreature = NULL;
2594        if( wpGuid != 0 )
2595        {
2596            wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2597            wpCreature->DeleteFromDB();
2598            wpCreature->CleanupsBeforeDelete();
2599            wpCreature->AddObjectToRemoveList();
2600        }
2601
2602        // What to do:
2603        // Remove the visual spawnpoint
2604        // Adjust the waypoints
2605        // Respawn the owner of the waypoints
2606
2607        WaypointMgr.DeleteNode(lowguid, point);
2608
2609        if(npcCreature)
2610        {
2611            // Any waypoints left?
2612            QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
2613            if(!result2)
2614            {
2615                npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2616            }
2617            else
2618            {
2619                npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2620                delete result2;
2621            }
2622            npcCreature->GetMotionMaster()->Initialize();
2623            if(npcCreature->isAlive())                      // dead creature will reset movement generator at respawn
2624            {
2625                npcCreature->setDeathState(JUST_DIED);
2626                npcCreature->Respawn();
2627            }
2628            npcCreature->SaveToDB();
2629        }
2630
2631        PSendSysMessage(LANG_WAYPOINT_REMOVED);
2632        return true;
2633    }                                                       // del
2634
2635    if(show == "move" && target)
2636    {
2637        PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2638
2639        Player *chr = m_session->GetPlayer();
2640        Map *map = chr->GetMap();
2641        {
2642            // Get the creature for which we read the waypoint
2643            CreatureData const* data = objmgr.GetCreatureData(lowguid);
2644            if(!data)
2645            {
2646                PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2647                SetSentErrorMessage(true);
2648                return false;
2649            }
2650
2651            Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2652
2653            // wpCreature
2654            Creature* wpCreature = NULL;
2655            // What to do:
2656            // Move the visual spawnpoint
2657            // Respawn the owner of the waypoints
2658            if( wpGuid != 0 )
2659            {
2660                wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2661                wpCreature->DeleteFromDB();
2662                wpCreature->CleanupsBeforeDelete();
2663                wpCreature->AddObjectToRemoveList();
2664                // re-create
2665                Creature* wpCreature2 = new Creature;
2666                if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
2667                {
2668                    PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2669                    delete wpCreature2;
2670                    return false;
2671                }
2672
2673                wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2674
2675                if(!wpCreature2->IsPositionValid())
2676                {
2677                    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());
2678                    delete wpCreature2;
2679                    return false;
2680                }
2681
2682                wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2683                // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2684                wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
2685                map->Add(wpCreature2);
2686                //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2687            }
2688
2689            WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
2690
2691            if(npcCreature)
2692            {
2693                npcCreature->GetMotionMaster()->Initialize();
2694                if(npcCreature->isAlive())                  // dead creature will reset movement generator at respawn
2695                {
2696                    npcCreature->setDeathState(JUST_DIED);
2697                    npcCreature->Respawn();
2698                }
2699            }
2700            PSendSysMessage(LANG_WAYPOINT_CHANGED);
2701        }
2702        return true;
2703    }                                                       // move
2704
2705    // Create creature - npc that has the waypoint
2706    CreatureData const* data = objmgr.GetCreatureData(lowguid);
2707    if(!data)
2708    {
2709        PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2710        SetSentErrorMessage(true);
2711        return false;
2712    }
2713
2714    WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
2715
2716    Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2717    if(npcCreature)
2718    {
2719        npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2720        npcCreature->GetMotionMaster()->Initialize();
2721        if(npcCreature->isAlive())                          // dead creature will reset movement generator at respawn
2722        {
2723            npcCreature->setDeathState(JUST_DIED);
2724            npcCreature->Respawn();
2725        }
2726    }
2727    PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2728
2729    return true;
2730}
2731
2732/**
2733 * .wp show info | on | off
2734 *
2735 * info -> User has selected a visual waypoint before
2736 *
2737 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2738 *                        provided the GUID of the NPC and the number of
2739 *                        the waypoint.
2740 *
2741 * on -> User has selected an NPC; all visual waypoints for this
2742 *       NPC are added to the world
2743 *
2744 * on <GUID> -> User did not select an NPC - instead the GUID of the
2745 *              NPC is provided. All visual waypoints for this NPC
2746 *              are added from the world.
2747 *
2748 * off -> User has selected an NPC; all visual waypoints for this
2749 *        NPC are removed from the world.
2750 *
2751 * on <GUID> -> User did not select an NPC - instead the GUID of the
2752 *              NPC is provided. All visual waypoints for this NPC
2753 *              are removed from the world.
2754 *
2755 *
2756 */
2757bool ChatHandler::HandleWpShowCommand(const char* args)
2758{
2759    sLog.outDebug("DEBUG: HandleWpShowCommand");
2760
2761    if(!*args)
2762        return false;
2763
2764    // first arg: on, off, first, last
2765    char* show_str = strtok((char*)args, " ");
2766    if (!show_str)
2767    {
2768        return false;
2769    }
2770    // second arg: GUID (optional, if a creature is selected)
2771    char* guid_str = strtok((char*)NULL, " ");
2772    sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2773    //if (!guid_str) {
2774    //    return false;
2775    //}
2776
2777    // Did user provide a GUID
2778    // or did the user select a creature?
2779    // -> variable lowguid is filled with the GUID
2780    Creature* target = getSelectedCreature();
2781    // Did player provide a GUID?
2782    if (!guid_str)
2783    {
2784        sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2785        // No GUID provided
2786        // -> Player must have selected a creature
2787
2788        if(!target)
2789        {
2790            SendSysMessage(LANG_SELECT_CREATURE);
2791            SetSentErrorMessage(true);
2792            return false;
2793        }
2794    }
2795    else
2796    {
2797        sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2798        // GUID provided
2799        // Warn if player also selected a creature
2800        // -> Creature selection is ignored <-
2801        if(target)
2802        {
2803            SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2804        }
2805
2806        uint32 lowguid = atoi((char*)guid_str);
2807
2808        CreatureData const* data = objmgr.GetCreatureData(lowguid);
2809        if(!data)
2810        {
2811            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2812            SetSentErrorMessage(true);
2813            return false;
2814        }
2815
2816        target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2817
2818        if(!target)
2819        {
2820            PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2821            SetSentErrorMessage(true);
2822            return false;
2823        }
2824    }
2825
2826    uint32 lowguid = target->GetDBTableGUIDLow();
2827
2828    std::string show = show_str;
2829    uint32 Maxpoint;
2830
2831    sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
2832
2833    sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", target );
2834
2835    sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
2836    //PSendSysMessage("wpshow - show: %s", show);
2837
2838    // Show info for the selected waypoint
2839    if(show == "info")
2840    {
2841        PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
2842
2843        // Check if the user did specify a visual waypoint
2844        if( target->GetEntry() != VISUAL_WAYPOINT )
2845        {
2846            PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2847            SetSentErrorMessage(true);
2848            return false;
2849        }
2850
2851        //PSendSysMessage("wp on, GUID: %u", lowguid);
2852
2853        //pCreature->GetPositionX();
2854
2855        QueryResult *result =
2856            WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2857            target->GetGUID() );
2858        if(!result)
2859        {
2860            // Since we compare float values, we have to deal with
2861            // some difficulties.
2862            // Here we search for all waypoints that only differ in one from 1 thousand
2863            // (0.001) - There is no other way to compare C++ floats with mySQL floats
2864            // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2865            const char* maxDIFF = "0.01";
2866            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
2867
2868            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 )",
2869                target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2870            if(!result)
2871            {
2872                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2873                SetSentErrorMessage(true);
2874                return false;
2875            }
2876        }
2877        do
2878        {
2879            Field *fields = result->Fetch();
2880            uint32 creGUID          = fields[0].GetUInt32();
2881            uint32 point            = fields[1].GetUInt32();
2882            int waittime            = fields[2].GetUInt32();
2883            uint32 emote            = fields[3].GetUInt32();
2884            uint32 spell            = fields[4].GetUInt32();
2885            const char * text1      = fields[5].GetString();
2886            const char * text2      = fields[6].GetString();
2887            const char * text3      = fields[7].GetString();
2888            const char * text4      = fields[8].GetString();
2889            const char * text5      = fields[9].GetString();
2890            uint32 model1           = fields[10].GetUInt32();
2891            uint32 model2           = fields[11].GetUInt32();
2892
2893            // Get the creature for which we read the waypoint
2894            Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2895
2896            PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
2897            PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
2898            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
2899            PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
2900            PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
2901            PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
2902            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
2903            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
2904            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
2905            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
2906            PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
2907
2908        }while( result->NextRow() );
2909        // Cleanup memory
2910        delete result;
2911        return true;
2912    }
2913
2914    if(show == "on")
2915    {
2916        PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
2917
2918        QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
2919        if(!result)
2920        {
2921            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2922            SetSentErrorMessage(true);
2923            return false;
2924        }
2925        // Delete all visuals for this NPC
2926        QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
2927        if(result2)
2928        {
2929            bool hasError = false;
2930            do
2931            {
2932                Field *fields = result2->Fetch();
2933                uint32 wpguid = fields[0].GetUInt32();
2934                Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2935
2936                if(!pCreature)
2937                {
2938                    PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
2939                    hasError = true;
2940                    WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
2941                }
2942                else
2943                {
2944                    pCreature->DeleteFromDB();
2945                    pCreature->CleanupsBeforeDelete();
2946                    pCreature->AddObjectToRemoveList();
2947                }
2948
2949            }while( result2->NextRow() );
2950            delete result2;
2951            if( hasError )
2952            {
2953                PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2954                PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2955                PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2956            }
2957        }
2958
2959        do
2960        {
2961            Field *fields = result->Fetch();
2962            uint32 point    = fields[0].GetUInt32();
2963            float x         = fields[1].GetFloat();
2964            float y         = fields[2].GetFloat();
2965            float z         = fields[3].GetFloat();
2966
2967            uint32 id = VISUAL_WAYPOINT;
2968
2969            Player *chr = m_session->GetPlayer();
2970            Map *map = chr->GetMap();
2971            float o = chr->GetOrientation();
2972
2973            Creature* wpCreature = new Creature;
2974            if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
2975            {
2976                PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
2977                delete wpCreature;
2978                delete result;
2979                return false;
2980            }
2981
2982            wpCreature->Relocate(x, y, z, o);
2983
2984            if(!wpCreature->IsPositionValid())
2985            {
2986                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());
2987                delete wpCreature;
2988                delete result;
2989                return false;
2990            }
2991
2992            wpCreature->SetVisibility(VISIBILITY_OFF);
2993            sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
2994            // set "wpguid" column to the visual waypoint
2995            WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
2996
2997            wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2998            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2999            wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
3000            map->Add(wpCreature);
3001            //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
3002        }while( result->NextRow() );
3003
3004        // Cleanup memory
3005        delete result;
3006        return true;
3007    }
3008
3009    if(show == "first")
3010    {
3011        PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3012
3013        QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3014        if(!result)
3015        {
3016            PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3017            SetSentErrorMessage(true);
3018            return false;
3019        }
3020
3021        Field *fields = result->Fetch();
3022        float x         = fields[0].GetFloat();
3023        float y         = fields[1].GetFloat();
3024        float z         = fields[2].GetFloat();
3025        uint32 id = VISUAL_WAYPOINT;
3026
3027        Player *chr = m_session->GetPlayer();
3028        float o = chr->GetOrientation();
3029        Map *map = chr->GetMap();
3030
3031        Creature* pCreature = new Creature;
3032        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
3033        {
3034            PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3035            delete pCreature;
3036            delete result;
3037            return false;
3038        }
3039
3040        pCreature->Relocate(x, y, z, o);
3041
3042        if(!pCreature->IsPositionValid())
3043        {
3044            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());
3045            delete pCreature;
3046            delete result;
3047            return false;
3048        }
3049
3050        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3051        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3052        map->Add(pCreature);
3053        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3054
3055        // Cleanup memory
3056        delete result;
3057        return true;
3058    }
3059
3060    if(show == "last")
3061    {
3062        PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3063
3064        QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3065        if( result )
3066        {
3067            Maxpoint = (*result)[0].GetUInt32();
3068
3069            delete result;
3070        }
3071        else
3072            Maxpoint = 0;
3073
3074        result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3075        if(!result)
3076        {
3077            PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3078            SetSentErrorMessage(true);
3079            return false;
3080        }
3081        Field *fields = result->Fetch();
3082        float x         = fields[0].GetFloat();
3083        float y         = fields[1].GetFloat();
3084        float z         = fields[2].GetFloat();
3085        uint32 id = VISUAL_WAYPOINT;
3086
3087        Player *chr = m_session->GetPlayer();
3088        float o = chr->GetOrientation();
3089        Map *map = chr->GetMap();
3090
3091        Creature* pCreature = new Creature;
3092        if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3093        {
3094            PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3095            delete pCreature;
3096            delete result;
3097            return false;
3098        }
3099
3100        pCreature->Relocate(x, y, z, o);
3101
3102        if(!pCreature->IsPositionValid())
3103        {
3104            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());
3105            delete pCreature;
3106            delete result;
3107            return false;
3108        }
3109
3110        pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3111        pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3112        map->Add(pCreature);
3113        //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3114        // Cleanup memory
3115        delete result;
3116        return true;
3117    }
3118
3119    if(show == "off")
3120    {
3121        QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3122        if(!result)
3123        {
3124            SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3125            SetSentErrorMessage(true);
3126            return false;
3127        }
3128        bool hasError = false;
3129        do
3130        {
3131            Field *fields = result->Fetch();
3132            uint32 guid = fields[0].GetUInt32();
3133            Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3134
3135            //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3136
3137            if(!pCreature)
3138            {
3139                PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3140                hasError = true;
3141                WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3142            }
3143            else
3144            {
3145                pCreature->DeleteFromDB();
3146                pCreature->CleanupsBeforeDelete();
3147                pCreature->AddObjectToRemoveList();
3148            }
3149        }while(result->NextRow());
3150        // set "wpguid" column to "empty" - no visual waypoint spawned
3151        WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3152
3153        if( hasError )
3154        {
3155            PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3156            PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3157            PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3158        }
3159
3160        SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3161        // Cleanup memory
3162        delete result;
3163
3164        return true;
3165    }
3166
3167    PSendSysMessage("DEBUG: wpshow - no valid command found");
3168
3169    return true;
3170}                                                           // HandleWpShowCommand
3171
3172bool ChatHandler::HandleWpExportCommand(const char *args)
3173{
3174    if(!*args)
3175        return false;
3176
3177    // Next arg is: <GUID> <ARGUMENT>
3178
3179    // Did user provide a GUID
3180    // or did the user select a creature?
3181    // -> variable lowguid is filled with the GUID of the NPC
3182    uint32 lowguid = 0;
3183    Creature* target = getSelectedCreature();
3184    char* arg_str = NULL;
3185    if (target)
3186    {
3187        if (target->GetEntry() != VISUAL_WAYPOINT)
3188            lowguid = target->GetGUIDLow();
3189        else
3190        {
3191            QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3192            if (!result)
3193            {
3194                PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3195                return true;
3196            }
3197            Field *fields = result->Fetch();
3198            lowguid = fields[0].GetUInt32();;
3199            delete result;
3200        }
3201
3202        arg_str = strtok((char*)args, " ");
3203    }
3204    else
3205    {
3206        // user provided <GUID>
3207        char* guid_str = strtok((char*)args, " ");
3208        if( !guid_str )
3209        {
3210            SendSysMessage(LANG_WAYPOINT_NOGUID);
3211            return false;
3212        }
3213        lowguid = atoi((char*)guid_str);
3214
3215        arg_str = strtok((char*)NULL, " ");
3216    }
3217
3218    if( !arg_str)
3219    {
3220        PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3221        return false;
3222    }
3223
3224    PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3225
3226    QueryResult *result = WorldDatabase.PQuery(
3227    //          0      1           2           3           4            5       6       7         8      9      10     11     12     13     14     15
3228        "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 );
3229
3230    if (!result)
3231    {
3232        PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3233        SetSentErrorMessage(true);
3234        return false;
3235    }
3236
3237    std::ofstream outfile;
3238    outfile.open (arg_str);
3239
3240    do
3241    {
3242        Field *fields = result->Fetch();
3243
3244        outfile << "INSERT INTO creature_movement ";
3245        outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
3246
3247        outfile << "( ";
3248        outfile << fields[15].GetUInt32();                  // id
3249        outfile << ", ";
3250        outfile << fields[0].GetUInt32();                   // point
3251        outfile << ", ";
3252        outfile << fields[1].GetFloat();                    // position_x
3253        outfile << ", ";
3254        outfile << fields[2].GetFloat();                    // position_y
3255        outfile << ", ";
3256        outfile << fields[3].GetUInt32();                   // position_z
3257        outfile << ", ";
3258        outfile << fields[4].GetUInt32();                   // orientation
3259        outfile << ", ";
3260        outfile << fields[5].GetUInt32();                   // model1
3261        outfile << ", ";
3262        outfile << fields[6].GetUInt32();                   // model2
3263        outfile << ", ";
3264        outfile << fields[7].GetUInt16();                   // waittime
3265        outfile << ", ";
3266        outfile << fields[8].GetUInt32();                   // emote
3267        outfile << ", ";
3268        outfile << fields[9].GetUInt32();                   // spell
3269        outfile << ", ";
3270        const char *tmpChar = fields[10].GetString();
3271        if( !tmpChar )
3272        {
3273            outfile << "NULL";                              // text1
3274        }
3275        else
3276        {
3277            outfile << "'";
3278            outfile << tmpChar;                             // text1
3279            outfile << "'";
3280        }
3281        outfile << ", ";
3282        tmpChar = fields[11].GetString();
3283        if( !tmpChar )
3284        {
3285            outfile << "NULL";                              // text2
3286        }
3287        else
3288        {
3289            outfile << "'";
3290            outfile << tmpChar;                             // text2
3291            outfile << "'";
3292        }
3293        outfile << ", ";
3294        tmpChar = fields[12].GetString();
3295        if( !tmpChar )
3296        {
3297            outfile << "NULL";                              // text3
3298        }
3299        else
3300        {
3301            outfile << "'";
3302            outfile << tmpChar;                             // text3
3303            outfile << "'";
3304        }
3305        outfile << ", ";
3306        tmpChar = fields[13].GetString();
3307        if( !tmpChar )
3308        {
3309            outfile << "NULL";                              // text4
3310        }
3311        else
3312        {
3313            outfile << "'";
3314            outfile << tmpChar;                             // text4
3315            outfile << "'";
3316        }
3317        outfile << ", ";
3318        tmpChar = fields[14].GetString();
3319        if( !tmpChar )
3320        {
3321            outfile << "NULL";                              // text5
3322        }
3323        else
3324        {
3325            outfile << "'";
3326            outfile << tmpChar;                             // text5
3327            outfile << "'";
3328        }
3329        outfile << ");\n ";
3330
3331    } while( result->NextRow() );
3332    delete result;
3333
3334    PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3335    outfile.close();
3336
3337    return true;
3338}
3339
3340bool ChatHandler::HandleWpImportCommand(const char *args)
3341{
3342    if(!*args)
3343        return false;
3344
3345    char* arg_str = strtok((char*)args, " ");
3346    if (!arg_str)
3347        return false;
3348
3349    std::string line;
3350    std::ifstream infile (arg_str);
3351    if (infile.is_open())
3352    {
3353        while (! infile.eof() )
3354        {
3355            getline (infile,line);
3356            //cout << line << endl;
3357            QueryResult *result = WorldDatabase.PQuery(line.c_str());
3358            delete result;
3359        }
3360        infile.close();
3361    }
3362    PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3363
3364    return true;
3365}
3366
3367//rename characters
3368bool ChatHandler::HandleRenameCommand(const char* args)
3369{
3370    Player* target = NULL;
3371    uint64 targetGUID = 0;
3372    std::string oldname;
3373
3374    char* px = strtok((char*)args, " ");
3375
3376    if(px)
3377    {
3378        oldname = px;
3379
3380        if(!normalizePlayerName(oldname))
3381        {
3382            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3383            SetSentErrorMessage(true);
3384            return false;
3385        }
3386
3387        target = objmgr.GetPlayer(oldname.c_str());
3388
3389        if (!target)
3390            targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3391    }
3392
3393    if(!target && !targetGUID)
3394    {
3395        target = getSelectedPlayer();
3396    }
3397
3398    if(!target && !targetGUID)
3399    {
3400        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3401        SetSentErrorMessage(true);
3402        return false;
3403    }
3404
3405    if(target)
3406    {
3407        PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
3408        target->SetAtLoginFlag(AT_LOGIN_RENAME);
3409        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3410    }
3411    else
3412    {
3413        PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
3414        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3415    }
3416
3417    return true;
3418}
3419
3420//spawn go
3421bool ChatHandler::HandleGameObjectCommand(const char* args)
3422{
3423    if (!*args)
3424        return false;
3425
3426    char* pParam1 = strtok((char*)args, " ");
3427    if (!pParam1)
3428        return false;
3429
3430    uint32 id = atoi((char*)pParam1);
3431    if(!id)
3432        return false;
3433
3434    char* spawntimeSecs = strtok(NULL, " ");
3435
3436    const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
3437
3438    if (!goI)
3439    {
3440        PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
3441        SetSentErrorMessage(true);
3442        return false;
3443    }
3444
3445    Player *chr = m_session->GetPlayer();
3446    float x = float(chr->GetPositionX());
3447    float y = float(chr->GetPositionY());
3448    float z = float(chr->GetPositionZ());
3449    float o = float(chr->GetOrientation());
3450    Map *map = chr->GetMap();
3451
3452    float rot2 = sin(o/2);
3453    float rot3 = cos(o/2);
3454
3455    GameObject* pGameObj = new GameObject;
3456    uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
3457
3458    if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
3459    {
3460        delete pGameObj;
3461        return false;
3462    }
3463
3464    if( spawntimeSecs )
3465    {
3466        uint32 value = atoi((char*)spawntimeSecs);
3467        pGameObj->SetRespawnTime(value);
3468        //sLog.outDebug("*** spawntimeSecs: %d", value);
3469    }
3470
3471    // fill the gameobject data and save to the db
3472    pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3473
3474    // this will generate a new guid if the object is in an instance
3475    if(!pGameObj->LoadFromDB(db_lowGUID, map))
3476    {
3477        delete pGameObj;
3478        return false;
3479    }
3480
3481    sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
3482
3483    map->Add(pGameObj);
3484
3485    // TODO: is it really necessary to add both the real and DB table guid here ?
3486    objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
3487
3488    PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
3489    return true;
3490}
3491
3492//show animation
3493bool ChatHandler::HandleAnimCommand(const char* args)
3494{
3495    if (!*args)
3496        return false;
3497
3498    uint32 anim_id = atoi((char*)args);
3499    m_session->GetPlayer()->HandleEmoteCommand(anim_id);
3500    return true;
3501}
3502
3503//change standstate
3504bool ChatHandler::HandleStandStateCommand(const char* args)
3505{
3506    if (!*args)
3507        return false;
3508
3509    uint32 anim_id = atoi((char*)args);
3510    m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3511
3512    return true;
3513}
3514
3515bool ChatHandler::HandleAddHonorCommand(const char* args)
3516{
3517    if (!*args)
3518        return false;
3519
3520    Player *target = getSelectedPlayer();
3521    if(!target)
3522    {
3523        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3524        SetSentErrorMessage(true);
3525        return false;
3526    }
3527
3528    uint32 amount = (uint32)atoi(args);
3529    target->RewardHonor(NULL, 1, amount);
3530    return true;
3531}
3532
3533bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3534{
3535    Unit *target = getSelectedUnit();
3536    if(!target)
3537    {
3538        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3539        SetSentErrorMessage(true);
3540        return false;
3541    }
3542
3543    m_session->GetPlayer()->RewardHonor(target, 1);
3544    return true;
3545}
3546
3547bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3548{
3549    Player *target = getSelectedPlayer();
3550    if(!target)
3551    {
3552        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3553        SetSentErrorMessage(true);
3554        return false;
3555    }
3556
3557    target->UpdateHonorFields();
3558    return true;
3559}
3560
3561bool ChatHandler::HandleLookupEventCommand(const char* args)
3562{
3563    if(!*args)
3564        return false;
3565
3566    std::string namepart = args;
3567    std::wstring wnamepart;
3568
3569    // converting string that we try to find to lower case
3570    if(!Utf8toWStr(namepart,wnamepart))
3571        return false;
3572
3573    wstrToLower(wnamepart);
3574
3575    uint32 counter = 0;
3576
3577    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3578    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3579
3580    for(uint32 id = 0; id < events.size(); ++id )
3581    {
3582        GameEventData const& eventData = events[id];
3583
3584        std::string descr = eventData.description;
3585        if(descr.empty())
3586            continue;
3587
3588        if (Utf8FitTo(descr, wnamepart))
3589        {
3590            char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : "";
3591            PSendSysMessage(LANG_EVENT_ENTRY_LIST,id,id,descr.c_str(),active );
3592            ++counter;
3593        }
3594    }
3595
3596    if (counter==0)
3597        SendSysMessage(LANG_NOEVENTFOUND);
3598
3599    return true;
3600}
3601
3602bool ChatHandler::HandleEventActiveListCommand(const char* args)
3603{
3604    uint32 counter = 0;
3605
3606    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3607    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3608
3609    char const* active = GetMangosString(LANG_ACTIVE);
3610
3611    for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3612    {
3613        uint32 event_id = *itr;
3614        GameEventData const& eventData = events[event_id];
3615
3616        PSendSysMessage(LANG_EVENT_ENTRY_LIST,event_id,event_id,eventData.description.c_str(),active );
3617        ++counter;
3618    }
3619
3620    if (counter==0)
3621        SendSysMessage(LANG_NOEVENTFOUND);
3622
3623    return true;
3624}
3625
3626bool ChatHandler::HandleEventInfoCommand(const char* args)
3627{
3628    if(!*args)
3629        return false;
3630
3631    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3632    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3633    if(!cId)
3634        return false;
3635
3636    uint32 event_id = atoi(cId);
3637
3638    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3639
3640    if(event_id >=events.size())
3641    {
3642        SendSysMessage(LANG_EVENT_NOT_EXIST);
3643        SetSentErrorMessage(true);
3644        return false;
3645    }
3646
3647    GameEventData const& eventData = events[event_id];
3648    if(!eventData.isValid())
3649    {
3650        SendSysMessage(LANG_EVENT_NOT_EXIST);
3651        SetSentErrorMessage(true);
3652        return false;
3653    }
3654
3655    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3656    bool active = activeEvents.find(event_id) != activeEvents.end();
3657    char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : "";
3658
3659    std::string startTimeStr = TimeToTimestampStr(eventData.start);
3660    std::string endTimeStr = TimeToTimestampStr(eventData.end);
3661
3662    uint32 delay = gameeventmgr.NextCheck(event_id);
3663    time_t nextTime = time(NULL)+delay;
3664    std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3665
3666    std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3667    std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3668
3669    PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3670        startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3671        nextStr.c_str());
3672    return true;
3673}
3674
3675bool ChatHandler::HandleEventStartCommand(const char* args)
3676{
3677    if(!*args)
3678        return false;
3679
3680    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3681    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3682    if(!cId)
3683        return false;
3684
3685    int32 event_id = atoi(cId);
3686
3687    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3688
3689    if(event_id < 1 || event_id >=events.size())
3690    {
3691        SendSysMessage(LANG_EVENT_NOT_EXIST);
3692        SetSentErrorMessage(true);
3693        return false;
3694    }
3695
3696    GameEventData const& eventData = events[event_id];
3697    if(!eventData.isValid())
3698    {
3699        SendSysMessage(LANG_EVENT_NOT_EXIST);
3700        SetSentErrorMessage(true);
3701        return false;
3702    }
3703
3704    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3705    if(activeEvents.find(event_id) != activeEvents.end())
3706    {
3707        PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
3708        SetSentErrorMessage(true);
3709        return false;
3710    }
3711
3712    gameeventmgr.StartEvent(event_id,true);
3713    return true;
3714}
3715
3716bool ChatHandler::HandleEventStopCommand(const char* args)
3717{
3718    if(!*args)
3719        return false;
3720
3721    // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3722    char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3723    if(!cId)
3724        return false;
3725
3726    int32 event_id = atoi(cId);
3727
3728    GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3729
3730    if(event_id < 1 || event_id >=events.size())
3731    {
3732        SendSysMessage(LANG_EVENT_NOT_EXIST);
3733        SetSentErrorMessage(true);
3734        return false;
3735    }
3736
3737    GameEventData const& eventData = events[event_id];
3738    if(!eventData.isValid())
3739    {
3740        SendSysMessage(LANG_EVENT_NOT_EXIST);
3741        SetSentErrorMessage(true);
3742        return false;
3743    }
3744
3745    GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3746
3747    if(activeEvents.find(event_id) == activeEvents.end())
3748    {
3749        PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
3750        SetSentErrorMessage(true);
3751        return false;
3752    }
3753
3754    gameeventmgr.StopEvent(event_id,true);
3755    return true;
3756}
3757
3758bool ChatHandler::HandleCombatStopCommand(const char* args)
3759{
3760    Player *player;
3761
3762    if(*args)
3763    {
3764        std::string playername = args;
3765
3766        if(!normalizePlayerName(playername))
3767        {
3768            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3769            SetSentErrorMessage(true);
3770            return false;
3771        }
3772
3773        player = objmgr.GetPlayer(playername.c_str());
3774
3775        if(!player)
3776        {
3777            SendSysMessage(LANG_PLAYER_NOT_FOUND);
3778            SetSentErrorMessage(true);
3779            return false;
3780        }
3781    }
3782    else
3783    {
3784        player = getSelectedPlayer();
3785
3786        if (!player)
3787            player = m_session->GetPlayer();
3788    }
3789
3790    player->CombatStop();
3791    player->getHostilRefManager().deleteReferences();
3792    return true;
3793}
3794
3795bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3796{
3797    uint32 classmask = m_session->GetPlayer()->getClassMask();
3798
3799    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3800    {
3801        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3802        if( !skillInfo )
3803            continue;
3804
3805        if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
3806        {
3807            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3808            {
3809                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3810                if( !skillLine )
3811                    continue;
3812
3813                // skip racial skills
3814                if( skillLine->racemask != 0 )
3815                    continue;
3816
3817                // skip wrong class skills
3818                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3819                    continue;
3820
3821                if( skillLine->skillId != i || skillLine->forward_spellid )
3822                    continue;
3823
3824                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3825                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3826                    continue;
3827
3828                m_session->GetPlayer()->learnSpell(skillLine->spellId);
3829            }
3830        }
3831    }
3832
3833    SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
3834    return true;
3835}
3836
3837bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
3838{
3839    //  Learns all recipes of specified profession and sets skill to max
3840    //  Example: .learn all_recipes enchanting
3841
3842    Player* target = getSelectedPlayer();
3843    if( !target )
3844    {
3845        SendSysMessage(LANG_PLAYER_NOT_FOUND);
3846        return false;
3847    }
3848
3849    if(!*args)
3850        return false;
3851
3852    std::wstring wnamepart;
3853
3854    if(!Utf8toWStr(args,wnamepart))
3855        return false;
3856
3857    uint32 counter = 0;                                     // Counter for figure out that we found smth.
3858
3859    // converting string that we try to find to lower case
3860    wstrToLower( wnamepart );
3861
3862    uint32 classmask = m_session->GetPlayer()->getClassMask();
3863
3864    for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3865    {
3866        SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3867        if( !skillInfo )
3868            continue;
3869
3870        if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
3871            skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
3872            continue;
3873
3874        int loc = m_session->GetSessionDbcLocale();
3875        std::string name = skillInfo->name[loc];
3876
3877        if(Utf8FitTo(name, wnamepart))
3878        {
3879            for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3880            {
3881                SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3882                if( !skillLine )
3883                    continue;
3884
3885                if( skillLine->skillId != i || skillLine->forward_spellid )
3886                    continue;
3887
3888                // skip racial skills
3889                if( skillLine->racemask != 0 )
3890                    continue;
3891
3892                // skip wrong class skills
3893                if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3894                    continue;
3895
3896                SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3897                if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3898                    continue;
3899
3900                if( !target->HasSpell(spellInfo->Id) )
3901                    m_session->GetPlayer()->learnSpell(skillLine->spellId);
3902            }
3903
3904            uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
3905            target->SetSkill(skillInfo->id, maxLevel, maxLevel);
3906            PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
3907            return true;
3908        }
3909    }
3910
3911    return false;
3912}
3913
3914bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
3915{
3916 
3917    if(!*args)
3918        return false;
3919
3920    std::string ip = strtok((char*)args, " ");
3921    char* limit_str = strtok(NULL, " ");
3922    int32 limit = limit_str ? atoi(limit_str) : -1;
3923
3924    loginDatabase.escape_string(ip);
3925
3926    QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str());
3927
3928    return LookupPlayerSearchCommand(result,limit);
3929}
3930
3931bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
3932{
3933    if(!*args)
3934        return false;
3935
3936    std::string account = strtok((char*)args, " ");
3937    char* limit_str = strtok(NULL, " ");
3938    int32 limit = limit_str ? atoi(limit_str) : -1;
3939
3940    if(!AccountMgr::normilizeString(account))
3941        return false;
3942
3943    loginDatabase.escape_string(account);
3944
3945    QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE username = '%s'", account.c_str());
3946
3947    return LookupPlayerSearchCommand(result,limit);
3948}
3949
3950bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
3951{
3952 
3953    if(!*args)
3954        return false;
3955
3956    std::string email = strtok((char*)args, " ");
3957    char* limit_str = strtok(NULL, " ");
3958    int32 limit = limit_str ? atoi(limit_str) : -1;
3959
3960    loginDatabase.escape_string(email);
3961
3962    QueryResult* result = loginDatabase.PQuery("SELECT id,username FROM account WHERE email = '%s'", email.c_str());
3963
3964    return LookupPlayerSearchCommand(result,limit);
3965}
3966
3967bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
3968{
3969    if(!result)
3970    {
3971        PSendSysMessage(LANG_NO_PLAYERS_FOUND);
3972        SetSentErrorMessage(true);
3973        return false;
3974    }
3975
3976    int i =0;
3977    do
3978    {
3979        Field* fields = result->Fetch();
3980        uint32 acc_id = fields[0].GetUInt32();
3981        std::string acc_name = fields[1].GetCppString();
3982       
3983        QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
3984        if(chars)
3985        {
3986            PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
3987
3988            uint64 guid = 0;
3989            std::string name;
3990
3991            do
3992            {
3993                Field* charfields = chars->Fetch();
3994                guid = charfields[0].GetUInt64();
3995                name = charfields[1].GetCppString();
3996
3997                PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
3998                ++i;
3999
4000            } while( chars->NextRow() && ( limit == -1 || i < limit ) );
4001
4002            delete chars;
4003        }
4004    } while(result->NextRow());
4005
4006    delete result;
4007
4008    return true;
4009}
Note: See TracBrowser for help on using the browser.