[4400] * sql/updates/Makefile.am: Added missing SQL updates.
[mangos-git.git] / src / game / Level2.cpp
blobb3013d759b13b52099c60f88b9b506a92bbd4587
1 /*
2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
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.
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.
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
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 "WaypointMovementGenerator.h"
35 #include "GameEvent.h"
37 #include <iostream>
38 #include <fstream>
40 //mute player for some times
41 bool ChatHandler::HandleMuteCommand(const char* args)
43 if (!*args)
44 return false;
46 char *charname = strtok((char*)args, " ");
47 if (!charname)
48 return false;
50 std::string cname = charname;
52 char *timetonotspeak = strtok(NULL, " ");
53 if(!timetonotspeak)
54 return false;
56 uint32 notspeaktime = (uint32) atoi(timetonotspeak);
58 normalizePlayerName(cname);
59 uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
60 if(!guid)
62 SendSysMessage(LANG_PLAYER_NOT_FOUND);
63 return true;
66 Player *chr = objmgr.GetPlayer(guid);
68 // check security
69 uint32 account_id = 0;
70 uint32 security = 0;
72 if (chr)
74 account_id = chr->GetSession()->GetAccountId();
75 security = chr->GetSession()->GetSecurity();
77 else
79 account_id = objmgr.GetPlayerAccountIdByGUID(guid);
80 security = objmgr.GetSecurityByAccount(account_id);
83 if(security >= m_session->GetSecurity())
85 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
86 return true;
89 time_t mutetime = time(NULL) + notspeaktime*60;
91 if (chr)
92 chr->GetSession()->m_muteTime = mutetime;
94 loginDatabase.PExecute("UPDATE `account` SET `mutetime` = " I64FMTD " WHERE `id` = '%u'",uint64(mutetime), account_id );
96 if(chr)
97 PSendSysMessage(chr->GetSession(), LANG_YOUR_CHAT_DISABLED, notspeaktime);
99 PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
101 return true;
104 //unmute player
105 bool ChatHandler::HandleUnmuteCommand(const char* args)
107 if (!*args)
108 return false;
110 char *charname = strtok((char*)args, " ");
111 if (!charname)
112 return false;
114 std::string cname = charname;
116 normalizePlayerName(cname);
117 uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
118 if(!guid)
120 SendSysMessage(LANG_PLAYER_NOT_FOUND);
121 return true;
124 Player *chr = objmgr.GetPlayer(guid);
126 // check security
127 uint32 account_id = 0;
128 uint32 security = 0;
130 if (chr)
132 account_id = chr->GetSession()->GetAccountId();
133 security = chr->GetSession()->GetSecurity();
135 else
137 account_id = objmgr.GetPlayerAccountIdByGUID(guid);
138 security = objmgr.GetSecurityByAccount(account_id);
141 if(security >= m_session->GetSecurity())
143 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
144 return true;
147 if (chr)
149 if(chr->CanSpeak())
151 SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
152 return true;
155 chr->GetSession()->m_muteTime = 0;
158 loginDatabase.PExecute("UPDATE `account` SET `mutetime` = '0' WHERE `id` = '%u'", account_id );
160 if(chr)
161 PSendSysMessage(chr->GetSession(), LANG_YOUR_CHAT_ENABLED);
163 PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
164 return true;
167 bool ChatHandler::HandleTargetObjectCommand(const char* args)
169 Player* pl = m_session->GetPlayer();
170 QueryResult *result;
171 char eventFilter[200];
172 char eventFilter2[200];
173 const GameEvent::ActiveEvents *ActiveEventsList = gameeventmgr.GetActiveEventList();
174 GameEvent::ActiveEvents::const_iterator itr;
175 bool initString = false;
176 strcpy(eventFilter, " AND (`event` IS NULL OR ");
177 strcpy(eventFilter2, " AND (`event` IS NULL OR (");
178 for (itr = ActiveEventsList->begin(); itr != ActiveEventsList->end(); ++itr)
180 if (initString)
182 strcat(eventFilter, " OR ");
183 strcat(eventFilter2, " AND ");
185 sprintf(eventFilter, "%s`event`=%u", eventFilter, *itr);
186 sprintf(eventFilter2, "%s`event`<>-%u", eventFilter2, *itr);
187 initString = true;
189 if (initString)
191 strcat(eventFilter,")");
192 strcat(eventFilter2,"))");
194 else
196 strcpy(eventFilter,"");
197 strcpy(eventFilter2,"");
199 if(*args)
201 int32 id = atoi((char*)args);
202 if(id)
203 result = sDatabase.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
207 std::string name = args;
208 sDatabase.escape_string(name);
209 result = sDatabase.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 '%%%s%%' ORDER BY `order` ASC LIMIT 1",
212 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
215 else
216 result = sDatabase.PQuery("SELECT `gameobject`.`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` LEFT OUTER JOIN `game_event_gameobject` on `gameobject`.`guid`=`game_event_gameobject`.`guid` WHERE `map` = %i%s%s ORDER BY `order` ASC LIMIT 1", m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter,eventFilter2);
218 if (!result)
220 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
221 return true;
224 Field *fields = result->Fetch();
225 uint32 guid = fields[0].GetUInt32();
226 uint32 id = fields[1].GetUInt32();
227 float x = fields[2].GetFloat();
228 float y = fields[3].GetFloat();
229 float z = fields[4].GetFloat();
230 float o = fields[5].GetFloat();
231 int mapid = fields[6].GetUInt16();
232 delete result;
234 const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
236 if (!goI)
238 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
239 return false;
242 PSendSysMessage(LANG_GAMEOBJECT_DETAIL, goI->name, guid, id, x, y, z, mapid, o);
244 return true;
247 //teleport to gameobject
248 bool ChatHandler::HandleGoObjectCommand(const char* args)
250 if(!*args)
251 return false;
253 Player* _player = m_session->GetPlayer();
255 if(_player->isInFlight())
257 SendSysMessage(LANG_YOU_IN_FLIGHT);
258 return true;
261 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
262 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
263 if(!cId)
264 return false;
266 int32 guid = atoi(cId);
267 if(!guid)
268 return false;
270 QueryResult *result = sDatabase.PQuery("SELECT `position_x`,`position_y`,`position_z`,`orientation`,`map` FROM `gameobject` WHERE `guid` = '%i'",guid);
271 if (!result)
273 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
274 return true;
277 Field *fields = result->Fetch();
278 float x = fields[0].GetFloat();
279 float y = fields[1].GetFloat();
280 float z = fields[2].GetFloat();
281 float ort = fields[3].GetFloat();
282 int mapid = fields[4].GetUInt16();
283 delete result;
285 if(!MapManager::IsValidMapCoord(mapid,x,y))
287 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
288 return true;
291 _player->SetRecallPosition(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
293 _player->TeleportTo(mapid, x, y, z, ort);
294 return true;
297 /** \brief Teleport the GM to the specified creature
299 * .gocreature <GUID> --> TP using creature.guid
300 * .gocreature azuregos --> TP player to the mob with this name
301 * Warning: If there is more than one mob with this name
302 * you will be teleported to the first one that is found.
303 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
304 * Warning: If there is more than one mob with this "id"
305 * you will be teleported to the first one that is found.
307 //teleport to creature
308 bool ChatHandler::HandleGoCreatureCommand(const char* args)
311 if(!*args)
312 return false;
313 Player* _player = m_session->GetPlayer();
315 if(_player->isInFlight())
317 SendSysMessage(LANG_YOU_IN_FLIGHT);
318 return true;
321 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
322 char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
323 if (!pParam1)
324 return false;
326 std::ostringstream whereClause;
328 // User wants to teleport to the NPC's template entry
329 if( strcmp(pParam1, "id") == 0 )
331 //sLog.outError("DEBUG: ID found");
333 // Get the "creature_template.entry"
334 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
335 char* tail = strtok(NULL,"");
336 if(!tail)
337 return false;
338 char* cId = extractKeyFromLink(tail,"Hcreature_entry");
339 if(!cId)
340 return false;
342 int32 tEntry = atoi(cId);
343 //sLog.outError("DEBUG: ID value: %d", tEntry);
344 if(!tEntry)
345 return false;
347 whereClause << "WHERE `id` = '" << tEntry << "'";
349 else
351 //sLog.outError("DEBUG: ID *not found*");
353 int32 guid = atoi(pParam1);
355 // Number is invalid - maybe the user specified the mob's name
356 if(!guid)
358 std::string name = pParam1;
359 sDatabase.escape_string(name);
360 whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name like '" << name << "'";
362 else
364 whereClause << "WHERE `guid` = '" << guid << "'";
367 //sLog.outError("DEBUG: %s", whereClause.c_str());
369 QueryResult *result = sDatabase.PQuery("SELECT `position_x`,`position_y`,`position_z`,`orientation`,`map` FROM `creature` %s", whereClause.str().c_str() );
370 if (!result)
372 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
373 return true;
375 if( result->GetRowCount() > 1 )
377 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
380 Field *fields = result->Fetch();
381 float x = fields[0].GetFloat();
382 float y = fields[1].GetFloat();
383 float z = fields[2].GetFloat();
384 float ort = fields[3].GetFloat();
385 int mapid = fields[4].GetUInt16();
387 delete result;
389 if(!MapManager::IsValidMapCoord(mapid,x,y))
391 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
392 return true;
395 _player->SetRecallPosition(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
397 _player->TeleportTo(mapid, x, y, z, ort);
398 return true;
401 bool ChatHandler::HandleGUIDCommand(const char* args)
403 uint64 guid = m_session->GetPlayer()->GetSelection();
405 if (guid == 0)
407 SendSysMessage(LANG_NO_SELECTION);
408 return true;
411 PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
412 return true;
415 bool ChatHandler::HandleNameCommand(const char* args)
417 /* Temp. disabled
418 if(!*args)
419 return false;
421 if(strlen((char*)args)>75)
423 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
424 return true;
427 for (uint8 i = 0; i < strlen(args); i++)
429 if(!isalpha(args[i]) && args[i]!=' ')
431 SendSysMessage(LANG_CHARS_ONLY);
432 return false;
436 uint64 guid;
437 guid = m_session->GetPlayer()->GetSelection();
438 if (guid == 0)
440 SendSysMessage(LANG_NO_SELECTION);
441 return true;
444 Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), guid);
446 if(!pCreature)
448 SendSysMessage(LANG_SELECT_CREATURE);
449 return true;
452 pCreature->SetName(args);
453 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
454 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
456 pCreature->SaveToDB();
459 return true;
462 bool ChatHandler::HandleSubNameCommand(const char* args)
464 /* Temp. disabled
466 if(!*args)
467 args = "";
469 if(strlen((char*)args)>75)
472 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
473 return true;
476 for (uint8 i = 0; i < strlen(args); i++)
478 if(!isalpha(args[i]) && args[i]!=' ')
480 SendSysMessage(LANG_CHARS_ONLY);
481 return false;
484 uint64 guid;
485 guid = m_session->GetPlayer()->GetSelection();
486 if (guid == 0)
488 SendSysMessage(LANG_NO_SELECTION);
489 return true;
492 Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), guid);
494 if(!pCreature)
496 SendSysMessage(LANG_SELECT_CREATURE);
497 return true;
500 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
501 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
503 pCreature->SaveToDB();
505 return true;
508 //move item to other slot
509 bool ChatHandler::HandleItemMoveCommand(const char* args)
511 if(!*args)
512 return false;
513 uint8 srcslot, dstslot;
515 char* pParam1 = strtok((char*)args, " ");
516 if (!pParam1)
517 return false;
519 char* pParam2 = strtok(NULL, " ");
520 if (!pParam2)
521 return false;
523 srcslot = (uint8)atoi(pParam1);
524 dstslot = (uint8)atoi(pParam2);
526 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
527 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
529 if(srcslot==dstslot)
530 return true;
532 m_session->GetPlayer()->SwapItem( src, dst );
534 return true;
537 //add spawn of creature
538 bool ChatHandler::HandleAddSpwCommand(const char* args)
540 if(!*args)
541 return false;
542 char* charID = strtok((char*)args, " ");
543 if (!charID)
544 return false;
546 uint32 id = atoi(charID);
548 Player *chr = m_session->GetPlayer();
549 float x = chr->GetPositionX();
550 float y = chr->GetPositionY();
551 float z = chr->GetPositionZ();
552 float o = chr->GetOrientation();
554 Creature* pCreature = new Creature(chr);
555 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id))
557 delete pCreature;
558 return false;
561 pCreature->SaveToDB();
563 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
564 pCreature->LoadFromDB(pCreature->GetGUIDLow(), chr->GetInstanceId());
566 MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
568 return true;
571 bool ChatHandler::HandleDeleteCommand(const char* args)
573 Creature *unit = getSelectedCreature();
574 if(!unit || unit->isPet() || unit->isTotem())
576 SendSysMessage(LANG_SELECT_CREATURE);
577 return true;
580 unit->CombatStop(true);
582 unit->DeleteFromDB();
584 unit->CleanupsBeforeDelete();
585 ObjectAccessor::Instance().AddObjectToRemoveList(unit);
587 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
589 return true;
592 //delete object by selection or guid
593 bool ChatHandler::HandleDelObjectCommand(const char* args)
595 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
596 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
597 if(!cId)
598 return false;
600 uint32 lowguid = atoi(cId);
601 if(!lowguid)
602 return false;
604 GameObject* obj = ObjectAccessor::Instance().GetGameObject(*m_session->GetPlayer(), MAKE_GUID(lowguid, HIGHGUID_GAMEOBJECT));
606 if(!obj)
608 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
609 return true;
612 uint64 owner_guid = obj->GetOwnerGUID();
613 if(owner_guid)
615 Unit* owner = ObjectAccessor::Instance().GetUnit(*m_session->GetPlayer(),owner_guid);
616 if(!owner && GUID_HIPART(owner_guid)!=HIGHGUID_PLAYER)
618 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
619 return true;
622 owner->RemoveGameObject(obj,false);
625 obj->SetRespawnTime(0); // not save respawn time
626 obj->Delete();
627 obj->DeleteFromDB();
629 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
631 return true;
634 //turn selected object
635 bool ChatHandler::HandleTurnObjectCommand(const char* args)
637 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
638 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
639 if(!cId)
640 return false;
642 uint32 lowguid = atoi(cId);
644 GameObject* obj = ObjectAccessor::Instance().GetGameObject(*m_session->GetPlayer(), MAKE_GUID(lowguid, HIGHGUID_GAMEOBJECT));
646 if(!obj)
648 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
649 return true;
652 char* po = strtok(NULL, " ");
653 float o;
655 if (po)
657 o = (float)atof(po);
659 else
661 Player *chr = m_session->GetPlayer();
662 o = chr->GetOrientation();
665 float rot2 = sin(o/2);
666 float rot3 = cos(o/2);
668 obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
670 obj->SetFloatValue(GAMEOBJECT_FACING, o);
671 obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
672 obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
674 obj->SaveToDB();
675 obj->Refresh();
677 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o);
679 return true;
682 //move selected creature
683 bool ChatHandler::HandleMoveCreatureCommand(const char* args)
685 if(!*args) return false;
686 uint32 lowguid = 0;
688 Creature* pCreature = getSelectedCreature();
690 if(!pCreature)
692 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
693 char* cId = extractKeyFromLink((char*)args,"Hcreature");
694 if(!cId)
695 return false;
697 uint32 lowguid = atoi(cId);
699 if(lowguid)
700 pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
702 // Attempting creature load from DB
703 if(!pCreature)
705 QueryResult *result = sDatabase.PQuery( "SELECT `guid`,`map` FROM `creature` WHERE `guid` = '%u'",lowguid);
706 if(!result)
708 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
709 return true;
712 Field* fields = result->Fetch();
713 lowguid = fields[0].GetUInt32();
715 uint32 map_id = fields[1].GetUInt32();
716 delete result;
718 if(m_session->GetPlayer()->GetMapId()!=map_id)
720 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
721 return true;
724 else
726 lowguid = pCreature->GetDBTableGUIDLow();
729 else
731 lowguid = pCreature->GetDBTableGUIDLow();
733 float x, y, z, o;
734 x = m_session->GetPlayer()->GetPositionX();
735 y = m_session->GetPlayer()->GetPositionY();
736 z = m_session->GetPlayer()->GetPositionZ();
737 o = m_session->GetPlayer()->GetOrientation();
738 if (pCreature)
740 pCreature->SetRespawnCoord(x, y, z);
741 MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
742 (*pCreature)->Initialize();
743 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
745 pCreature->setDeathState(JUST_DIED);
746 pCreature->RemoveCorpse();
747 pCreature->Respawn();
751 sDatabase.PExecuteLog("UPDATE `creature` SET `spawn_position_x` = '%f', `spawn_position_y` = '%f', `spawn_position_z` = '%f', `spawn_orientation` = '%f',`position_x` = '%f', `position_y` = '%f', `position_z` = '%f', `orientation` = '%f' WHERE `guid` = '%u'", x, y, z, o, x, y, z, o, lowguid);
752 PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
753 return true;
756 //move selected object
757 bool ChatHandler::HandleMoveObjectCommand(const char* args)
759 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
760 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
761 if(!cId)
762 return false;
764 uint32 lowguid = atoi(cId);
766 GameObject* obj = ObjectAccessor::Instance().GetGameObject(*m_session->GetPlayer(), MAKE_GUID(lowguid, HIGHGUID_GAMEOBJECT));
768 if(!obj)
770 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
771 return true;
774 char* px = strtok(NULL, " ");
775 char* py = strtok(NULL, " ");
776 char* pz = strtok(NULL, " ");
778 if (!px)
780 Player *chr = m_session->GetPlayer();
782 Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
783 map->Remove(obj,false);
785 obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
786 obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
787 obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
788 obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
790 map->Add(obj);
792 else
794 if(!py || !pz)
795 return false;
797 float x = (float)atof(px);
798 float y = (float)atof(py);
799 float z = (float)atof(pz);
801 if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y))
803 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
804 return true;
807 Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
808 map->Remove(obj,false);
810 obj->Relocate(x, y, z, obj->GetOrientation());
811 obj->SetFloatValue(GAMEOBJECT_POS_X, x);
812 obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
813 obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
815 map->Add(obj);
818 obj->SaveToDB();
819 obj->Refresh();
821 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
823 return true;
826 //demorph player or unit
827 bool ChatHandler::HandleDeMorphCommand(const char* args)
829 Unit *target = getSelectedUnit();
830 if(!target)
831 target = m_session->GetPlayer();
833 target->DeMorph();
835 return true;
838 //add item in vendorlist
839 bool ChatHandler::HandleAddVendorItemCommand(const char* args)
841 if (!*args)
842 return false;
844 Creature* vendor = getSelectedCreature();
845 if (!vendor || !vendor->isVendor())
847 SendSysMessage(LANG_COMMAND_VENDORSELECTION);
848 return true;
851 char* pitem = strtok((char*)args, " ");
852 uint32 itemId = atol(pitem);
853 if (!pitem)
855 SendSysMessage(LANG_COMMAND_ADDVENDORITEMSEND);
856 return true;
859 char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
860 uint32 maxcount = 0;
861 if (fmaxcount)
862 maxcount = atol(fmaxcount);
864 char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
865 uint32 incrtime = 0;
866 if (fincrtime)
867 incrtime = atol(fincrtime);
869 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
870 if(!pProto)
872 PSendSysMessage(LANG_ITEM_NOT_FOUND, itemId);
873 return true;
876 // load vendor items if not yet
877 vendor->LoadGoods();
879 if(vendor->FindItem(itemId))
881 PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,itemId);
882 return true;
885 if (vendor->GetItemCount() >= MAX_VENDOR_ITEMS)
887 SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
888 return true;
891 // add to DB and to current ingame vendor
892 sDatabase.PExecuteLog("INSERT INTO `npc_vendor` (`entry`,`item`,`maxcount`,`incrtime`) VALUES('%u','%u','%u','%u')",vendor->GetEntry(), itemId, maxcount,incrtime);
893 vendor->AddItem(itemId,maxcount,incrtime);
894 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime);
895 return false;
898 //del item from vendor list
899 bool ChatHandler::HandleDelVendorItemCommand(const char* args)
901 if (!*args)
902 return false;
904 Creature* vendor = getSelectedCreature();
905 if (!vendor || !vendor->isVendor())
907 SendSysMessage(LANG_COMMAND_VENDORSELECTION);
908 return true;
911 char* pitem = strtok((char*)args, " ");
912 uint32 itemId = atol(pitem);
914 ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
915 if(!pProto)
917 PSendSysMessage(LANG_ITEM_NOT_FOUND, itemId);
918 return true;
921 // load vendor items if not yet
922 vendor->LoadGoods();
924 if (!vendor->RemoveItem(itemId))
926 PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
927 return true;
930 sDatabase.PExecuteLog("DELETE FROM `npc_vendor` WHERE `entry`='%u' AND `item`='%u'",vendor->GetEntry(), itemId);
931 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
932 return true;
935 //add move for creature
936 bool ChatHandler::HandleAddMoveCommand(const char* args)
938 if(!*args)
939 return false;
941 char* guid_str = strtok((char*)args, " ");
942 char* wait_str = strtok((char*)NULL, " ");
944 uint32 lowguid = atoi((char*)guid_str);
946 Creature* pCreature = NULL;
948 if(lowguid)
949 pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
951 // attempt check creature existance by DB
952 if(!pCreature)
954 QueryResult *result = sDatabase.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",lowguid);
955 if(!result)
957 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
958 return true;
960 delete result;
962 else
964 // obtain real GUID for DB operations
965 lowguid = pCreature->GetDBTableGUIDLow();
968 int wait = wait_str ? atoi(wait_str) : 0;
970 if(wait < 0)
971 wait = 0;
973 uint32 point;
975 QueryResult *result = sDatabase.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid);
976 if( result )
978 point = (*result)[0].GetUInt32()+1;
980 delete result;
982 else
983 point = 0;
985 Player* player = m_session->GetPlayer();
987 sDatabase.PExecuteLog("INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`,`waittime`) VALUES ('%u','%u','%f', '%f', '%f','%u')",
988 lowguid, point, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), wait);
990 // update movement type
991 sDatabase.PExecuteLog("UPDATE `creature` SET `MovementType` = '%u' WHERE `guid` = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
992 if(pCreature)
994 pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
995 (*pCreature)->Initialize();
996 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
998 pCreature->setDeathState(JUST_DIED);
999 pCreature->RemoveCorpse();
1000 pCreature->Respawn();
1004 SendSysMessage(LANG_WAYPOINT_ADDED);
1006 return true;
1010 * Set the movement type for an NPC.<br/>
1011 * <br/>
1012 * Valid movement types are:
1013 * <ul>
1014 * <li> stay - NPC wont move </li>
1015 * <li> random - NPC will move randomly according to the spawndist </li>
1016 * <li> way - NPC will move with given waypoints set </li>
1017 * </ul>
1018 * additional parameter: NODEL - so no waypoints are deleted, if you
1019 * change the movement type
1021 bool ChatHandler::HandleSetMoveTypeCommand(const char* args)
1023 if(!*args)
1024 return false;
1026 // 3 arguments:
1027 // GUID (optional - you can also select the creature)
1028 // stay|random|way (determines the kind of movement)
1029 // NODEL (optional - tells the system NOT to delete any waypoints)
1030 // this is very handy if you want to do waypoints, that are
1031 // later switched on/off according to special events (like escort
1032 // quests, etc)
1033 char* guid_str = strtok((char*)args, " ");
1034 char* type_str = strtok((char*)NULL, " ");
1035 char* dontdel_str = strtok((char*)NULL, " ");
1037 bool doNotDelete = false;
1039 if(!guid_str)
1040 return false;
1042 uint32 lowguid = 0;
1043 Creature* pCreature = NULL;
1045 if( dontdel_str )
1047 //sLog.outError("DEBUG: All 3 params are set");
1049 // All 3 params are set
1050 // GUID
1051 // type
1052 // doNotDEL
1053 if( stricmp( dontdel_str, "NODEL" ) == 0 )
1055 //sLog.outError("DEBUG: doNotDelete = true;");
1056 doNotDelete = true;
1059 else
1061 // Only 2 params - but maybe NODEL is set
1062 if( type_str )
1064 sLog.outError("DEBUG: Only 2 params ");
1065 if( stricmp( type_str, "NODEL" ) == 0 )
1067 //sLog.outError("DEBUG: type_str, NODEL ");
1068 doNotDelete = true;
1069 type_str = NULL;
1074 if(!type_str) // case .setmovetype $move_type (with selected creature)
1076 type_str = guid_str;
1077 pCreature = getSelectedCreature();
1078 if(!pCreature)
1079 return false;
1080 lowguid = pCreature->GetDBTableGUIDLow();
1082 else // case .setmovetype #creature_guid $move_type (with selected creature)
1084 lowguid = atoi((char*)guid_str);
1085 if(lowguid)
1086 pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1088 // attempt check creature existance by DB
1089 if(!pCreature)
1091 QueryResult *result = sDatabase.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",lowguid);
1092 if(!result)
1094 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1095 return true;
1097 delete result;
1099 else
1101 lowguid = pCreature->GetDBTableGUIDLow();
1105 // now lowguid is low guid really existed creature
1106 // and pCreature point (maybe) to this creature or NULL
1108 MovementGeneratorType move_type;
1110 std::string type = type_str;
1112 if(type == "stay")
1113 move_type = IDLE_MOTION_TYPE;
1114 else if(type == "random")
1115 move_type = RANDOM_MOTION_TYPE;
1116 else if(type == "way")
1117 move_type = WAYPOINT_MOTION_TYPE;
1118 else
1119 return false;
1121 // update movement type
1122 sDatabase.BeginTransaction();
1123 sDatabase.PExecuteLog("UPDATE `creature` SET `MovementType` = '%u' WHERE `guid` = '%u'", move_type,lowguid);
1124 if( doNotDelete == false )
1126 //sLog.outError("DEBUG: doNotDelete == false");
1127 sDatabase.PExecuteLog("DELETE FROM `creature_movement` WHERE `id` = '%u'",lowguid);
1129 sDatabase.CommitTransaction();
1130 if(pCreature)
1132 pCreature->SetDefaultMovementType(move_type);
1133 (*pCreature)->Initialize();
1134 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1136 pCreature->setDeathState(JUST_DIED);
1137 pCreature->RemoveCorpse();
1138 pCreature->Respawn();
1141 if( doNotDelete == false )
1143 PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1145 else
1147 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1150 return true;
1151 } // HandleSetMoveTypeCommand
1153 //change level of creature or pet
1154 bool ChatHandler::HandleChangeLevelCommand(const char* args)
1156 if (!*args)
1157 return false;
1159 uint8 lvl = (uint8) atoi((char*)args);
1160 if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1162 SendSysMessage(LANG_BAD_VALUE);
1163 return true;
1166 Creature* pCreature = getSelectedCreature();
1167 if(!pCreature)
1169 SendSysMessage(LANG_SELECT_CREATURE);
1170 return true;
1173 if(pCreature->isPet())
1175 ((Pet*)pCreature)->GivePetLevel(lvl);
1177 else
1179 pCreature->SetMaxHealth( 100 + 30*lvl);
1180 pCreature->SetHealth( 100 + 30*lvl);
1181 pCreature->SetLevel( lvl);
1184 pCreature->SaveToDB();
1186 return true;
1189 //set npcflag of creature
1190 bool ChatHandler::HandleNPCFlagCommand(const char* args)
1192 if (!*args)
1193 return false;
1195 uint32 npcFlags = (uint32) atoi((char*)args);
1197 Creature* pCreature = getSelectedCreature();
1199 if(!pCreature)
1201 SendSysMessage(LANG_SELECT_CREATURE);
1202 return true;
1205 pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1207 sDatabase.PExecuteLog("UPDATE `creature_template` SET `npcflag` = '%u' WHERE `entry` = '%u'", npcFlags, pCreature->GetEntry());
1209 SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1211 uint32 entry = pCreature->GetUInt32Value( OBJECT_FIELD_ENTRY );
1212 m_session->SendCreatureQuery( entry, pCreature->GetGUID() );
1214 return true;
1217 //set model of creature
1218 bool ChatHandler::HandleSetModelCommand(const char* args)
1220 if (!*args)
1221 return false;
1223 uint32 displayId = (uint32) atoi((char*)args);
1225 Creature *pCreature = getSelectedCreature();
1227 if(!pCreature)
1229 SendSysMessage(LANG_SELECT_CREATURE);
1230 return true;
1233 pCreature->SetUInt32Value(UNIT_FIELD_DISPLAYID, displayId);
1235 pCreature->SaveToDB();
1237 return true;
1240 //morph creature or player
1241 bool ChatHandler::HandleMorphCommand(const char* args)
1243 if (!*args)
1244 return false;
1246 uint16 display_id = (uint16)atoi((char*)args);
1248 Unit *target = getSelectedUnit();
1249 if(!target)
1250 target = m_session->GetPlayer();
1252 target->SetUInt32Value(UNIT_FIELD_DISPLAYID, display_id);
1254 return true;
1257 //set faction of creature or go
1258 bool ChatHandler::HandleFactionIdCommand(const char* args)
1260 if (!*args)
1261 return false;
1263 uint32 factionId = (uint32) atoi((char*)args);
1265 if (!sFactionTemplateStore.LookupEntry(factionId))
1267 PSendSysMessage(LANG_WRONG_FACTION, factionId);
1268 return true;
1271 Creature* pCreature = getSelectedCreature();
1273 if(!pCreature)
1275 SendSysMessage(LANG_SELECT_CREATURE);
1276 return true;
1279 pCreature->setFaction(factionId);
1281 // faction is set in creature_template - not inside creature
1282 //pCreature->SaveToDB(); -- obsolete
1283 sDatabase.PExecuteLog("UPDATE `creature_template` SET `faction` = '%u' WHERE `entry` = '%u'", factionId, pCreature->GetEntry());
1285 return true;
1288 //kick player
1289 bool ChatHandler::HandleKickPlayerCommand(const char *args)
1291 char* kickName = strtok((char*)args, " ");
1292 if (!kickName)
1294 Player* player = getSelectedPlayer();
1296 if(!player)
1298 SendSysMessage(LANG_NO_CHAR_SELECTED);
1299 return true;
1302 if(player==m_session->GetPlayer())
1304 SendSysMessage(LANG_COMMAND_KICKSELF);
1305 return true;
1308 player->GetSession()->KickPlayer();
1310 else
1312 std::string name = kickName;
1313 normalizePlayerName(name);
1315 if(name==m_session->GetPlayer()->GetName())
1317 SendSysMessage(LANG_COMMAND_KICKSELF);
1318 return true;
1321 if(sWorld.KickPlayer(name))
1323 PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
1325 else
1326 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
1329 return true;
1332 //show info of player
1333 bool ChatHandler::HandlePInfoCommand(const char* args)
1335 Player* target = NULL;
1336 uint64 targetGUID = 0;
1338 char* px = strtok((char*)args, " ");
1339 char* py = NULL;
1341 std::string name;
1343 if (px)
1345 name = px;
1346 normalizePlayerName(name);
1347 target = objmgr.GetPlayer(name.c_str());
1348 if (target)
1349 py = strtok(NULL, " ");
1350 else
1352 targetGUID = objmgr.GetPlayerGUIDByName(name);
1353 if(targetGUID)
1354 py = strtok(NULL, " ");
1355 else
1356 py = px;
1360 if(!target && !targetGUID)
1362 target = getSelectedPlayer();
1365 if(!target && !targetGUID)
1367 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1368 return true;
1371 uint32 accId = 0;
1372 uint32 money = 0;
1373 uint32 total_player_time = 0;
1374 uint32 level = 0;
1376 // get additional information from Player object
1377 if(target)
1379 targetGUID = target->GetGUID();
1380 name = target->GetName(); // re-read for case getSelectedPlayer() target
1381 accId = target->GetSession()->GetAccountId();
1382 money = target->GetMoney();
1383 total_player_time = target->GetTotalPlayedTime();
1384 level = target->getLevel();
1386 // get additional information from DB
1387 else
1389 accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
1390 Player plr(m_session); // use current session for temporary load
1391 plr.MinimalLoadFromDB(NULL, targetGUID);
1392 money = plr.GetMoney();
1393 total_player_time = plr.GetTotalPlayedTime();
1394 level = plr.getLevel();
1397 std::string username = LANG_ERROR;
1398 std::string last_ip = LANG_ERROR;
1399 uint32 security = 0;
1401 QueryResult* result = loginDatabase.PQuery("SELECT `username`,`gmlevel`,`last_ip` FROM `account` WHERE `id` = '%u'",accId);
1402 if(result)
1404 Field* fields = result->Fetch();
1405 username = fields[0].GetCppString();
1406 security = fields[1].GetUInt32();
1407 if(m_session->GetSecurity() >= security)
1408 last_ip = fields[2].GetCppString();
1409 else
1410 last_ip = "-";
1412 delete result;
1415 PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":LANG_OFFLINE), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str());
1417 std::string timeStr = secsToTimeString(total_player_time,true,true);
1418 uint32 gold = money /GOLD;
1419 uint32 silv = (money % GOLD) / SILVER;
1420 uint32 copp = (money % GOLD) % SILVER;
1421 PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
1423 if ( py && strncmp(py, "rep", 3) == 0 )
1425 if(!target)
1427 // rep option not implemented for offline case
1428 SendSysMessage(LANG_PINFO_NO_REP);
1429 return true;
1432 static const char* ReputationRankStr[MAX_REPUTATION_RANK] = {"Hated", "Hostile", "Unfriendly", "Neutral", "Friendly", "Honored", "Reverted", "Exalted"};
1433 char* FactionName;
1434 for(FactionsList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
1436 FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
1437 if (factionEntry)
1438 FactionName = factionEntry->name[sWorld.GetDBClang()];
1439 else
1440 FactionName = "#Not found#";
1441 ReputationRank Rank = target->GetReputationRank(factionEntry);
1443 PSendSysMessage("Id:%4d %s %s %5d %1x", itr->second.ID, FactionName, ReputationRankStr[Rank], target->GetReputation(factionEntry), itr->second.Flags);
1446 return true;
1449 //show tickets
1450 void ChatHandler::ShowTicket(uint64 guid, uint32 category, char const* text)
1452 std::string name;
1453 if(!objmgr.GetPlayerNameByGUID(guid,name))
1454 name = LANG_UNKNOWN;
1456 PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),category,text);
1459 //ticket commands
1460 bool ChatHandler::HandleTicketCommand(const char* args)
1462 char* px = strtok((char*)args, " ");
1464 // ticket<end>
1465 if (!px)
1467 QueryResult *result = sDatabase.Query("SELECT `ticket_id` FROM `character_ticket`");
1468 size_t count = result ? result->GetRowCount() : 0;
1470 PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count,m_session->GetPlayer()->isAcceptTickets() ? LANG_ON : LANG_OFF);
1471 delete result;
1472 return true;
1475 // ticket on
1476 if(strncmp(px,"on",3) == 0)
1478 m_session->GetPlayer()->SetAcceptTicket(true);
1479 SendSysMessage(LANG_COMMAND_TICKETON);
1480 return true;
1483 // ticket off
1484 if(strncmp(px,"off",4) == 0)
1486 m_session->GetPlayer()->SetAcceptTicket(false);
1487 SendSysMessage(LANG_COMMAND_TICKETOFF);
1488 return true;
1491 // ticket #num
1492 int num = atoi(px);
1493 if(num > 0)
1495 QueryResult *result = sDatabase.Query("SELECT `guid`,`ticket_category`,`ticket_text` FROM `character_ticket`");
1497 if(!result || uint64(num) > result->GetRowCount())
1499 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1500 delete result;
1501 return true;
1504 for(int i = 1; i < num; ++i)
1505 result->NextRow();
1507 Field* fields = result->Fetch();
1509 uint64 guid = fields[0].GetUInt64();
1510 uint32 category = fields[1].GetUInt32();
1511 char const* text = fields[2].GetString();
1513 ShowTicket(guid,category,text);
1514 delete result;
1515 return true;
1518 std::string name = px;
1519 normalizePlayerName(name);
1520 //sDatabase.escape_string(name); // prevent SQL injection - normal name don't must changed by this call
1522 uint64 guid = objmgr.GetPlayerGUIDByName(name);
1524 if(!guid)
1525 return false;
1527 // ticket $char_name
1528 QueryResult *result = sDatabase.PQuery("SELECT `guid`,`ticket_category`,`ticket_text` FROM `character_ticket` WHERE `guid` = '%u'",GUID_LOPART(guid));
1530 if(!result)
1531 return false;
1533 Field* fields = result->Fetch();
1535 uint32 category = fields[1].GetUInt32();
1536 char const* text = fields[2].GetString();
1538 ShowTicket(guid,category,text);
1539 delete result;
1541 return true;
1544 uint32 ChatHandler::GetTicketIDByNum(uint32 num)
1546 QueryResult *result = sDatabase.Query("SELECT `ticket_id` FROM `character_ticket`");
1548 if(!result || num > result->GetRowCount())
1550 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1551 delete result;
1552 return 0;
1555 for(uint32 i = 1; i < num; ++i)
1556 result->NextRow();
1558 Field* fields = result->Fetch();
1560 uint32 id = fields[0].GetUInt32();
1561 delete result;
1562 return id;
1565 //dell all tickets
1566 bool ChatHandler::HandleDelTicketCommand(const char *args)
1568 char* px = strtok((char*)args, " ");
1569 if (!px)
1570 return false;
1572 // delticket all
1573 if(strncmp(px,"all",4) == 0)
1575 QueryResult *result = sDatabase.Query("SELECT `guid` FROM `character_ticket`");
1577 if(!result)
1578 return true;
1580 // notify players about ticket deleting
1583 Field* fields = result->Fetch();
1585 uint64 guid = fields[0].GetUInt64();
1587 if(Player* sender = objmgr.GetPlayer(guid))
1588 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
1590 }while(result->NextRow());
1592 delete result;
1594 sDatabase.PExecute("DELETE FROM `character_ticket`");
1595 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
1596 return true;
1599 int num = (uint32)atoi(px);
1601 // delticket #num
1602 if(num > 0)
1604 QueryResult *result = sDatabase.PQuery("SELECT `ticket_id`,`guid` FROM `character_ticket` LIMIT '%i'",num);
1606 if(!result || uint64(num) > result->GetRowCount())
1608 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1609 delete result;
1610 return true;
1613 for(int i = 1; i < num; ++i)
1614 result->NextRow();
1616 Field* fields = result->Fetch();
1618 uint32 id = fields[0].GetUInt32();
1619 uint64 guid = fields[1].GetUInt64();
1620 delete result;
1622 sDatabase.PExecute("DELETE FROM `character_ticket` WHERE `ticket_id` = '%u'", id);
1624 // notify players about ticket deleting
1625 if(Player* sender = objmgr.GetPlayer(guid))
1627 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
1628 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName());
1630 else
1631 SendSysMessage(LANG_COMMAND_TICKETDEL);
1633 return true;
1636 std::string name = px;
1637 normalizePlayerName(name);
1638 //sDatabase.escape_string(name); // prevent SQL injection - normal name don't must changed by this call
1640 uint64 guid = objmgr.GetPlayerGUIDByName(name);
1642 if(!guid)
1643 return false;
1645 // delticket $char_name
1646 sDatabase.PExecute("DELETE FROM `character_ticket` WHERE `guid` = '%u'",GUID_LOPART(guid));
1648 // notify players about ticket deleting
1649 if(Player* sender = objmgr.GetPlayer(guid))
1650 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
1652 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
1653 return true;
1656 //set spawn dist of creature
1657 bool ChatHandler::HandleSpawnDistCommand(const char* args)
1659 if(!*args)
1660 return false;
1662 int option = atoi((char*)args);
1663 if (option < 0)
1665 SendSysMessage(LANG_BAD_VALUE);
1666 return false;
1669 int mtype=0; // MovementType
1670 if (option > 0)
1671 mtype=1;
1673 Creature *pCreature = getSelectedCreature();
1674 uint64 u_guid = 0;
1676 if (pCreature)
1677 u_guid = pCreature->GetDBTableGUIDLow();
1678 else
1679 return false;
1681 sDatabase.PExecuteLog("UPDATE `creature` SET `spawndist`=%i, `MovementType`=%i WHERE `guid`=%u",option,mtype,u_guid);
1682 PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
1683 return true;
1686 bool ChatHandler::HandleSpawnTimeCommand(const char* args)
1688 if(!*args)
1689 return false;
1691 char* stime = strtok((char*)args, " ");
1693 if (!stime)
1694 return false;
1696 int i_stime = atoi((char*)stime);
1698 if (i_stime < 0)
1700 SendSysMessage(LANG_BAD_VALUE);
1701 return true;
1704 Creature *pCreature = getSelectedCreature();
1705 uint64 u_guid = 0;
1707 if (pCreature)
1708 u_guid = pCreature->GetDBTableGUIDLow();
1709 else
1710 return false;
1712 sDatabase.PExecuteLog("UPDATE `creature` SET `spawntimesecs`=%i WHERE `guid`=%u",i_stime,u_guid);
1713 PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
1715 return true;
1719 * Add a waypoint to a creature.
1721 * The user can either select an npc or provide its GUID.
1723 * The user can even select a visual waypoint - then the new waypoint
1724 * is placed *after* the selected one - this makes insertion of new
1725 * waypoints possible.
1727 * eg:
1728 * .wp add 12345
1729 * -> adds a waypoint to the npc with the GUID 12345
1731 * .wp add
1732 * -> adds a waypoint to the currently selected creature
1735 * @param args if the user did not provide a GUID, it is NULL
1737 * @return true - command did succeed, false - something went wrong
1739 bool ChatHandler::HandleWpAddCommand(const char* args)
1741 sLog.outDebug("DEBUG: HandleWpAddCommand");
1743 // optional
1744 char* guid_str = NULL;
1746 if(*args)
1748 guid_str = strtok((char*)args, " ");
1751 uint32 lowguid = 0;
1752 uint32 point = 0;
1753 Unit* target = getSelectedCreature();
1754 // Did player provide a GUID?
1755 if (!guid_str)
1757 sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
1759 // No GUID provided
1760 // -> Player must have selected a creature
1762 if(!target)
1764 SendSysMessage(LANG_SELECT_CREATURE);
1765 return true;
1767 if (target->GetEntry() == VISUAL_WAYPOINT )
1769 sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
1771 QueryResult *result =
1772 sDatabase.PQuery( "SELECT `id`, `point` FROM `creature_movement` WHERE `wpguid` = %u",
1773 target->GetGUIDLow() );
1774 if(!result)
1776 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
1777 // User selected a visual spawnpoint -> get the NPC
1778 // Select NPC GUID
1779 // Since we compare float values, we have to deal with
1780 // some difficulties.
1781 // Here we search for all waypoints that only differ in one from 1 thousand
1782 // (0.001) - There is no other way to compare C++ floats with mySQL floats
1783 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
1784 const char* maxDIFF = "0.01";
1785 result = sDatabase.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 )",
1786 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
1787 if(!result)
1789 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
1790 return true;
1795 Field *fields = result->Fetch();
1796 lowguid = fields[0].GetUInt32();
1797 point = fields[1].GetUInt32();
1798 }while( result->NextRow() );
1799 delete result;
1801 else
1803 lowguid = target->GetGUIDLow();
1807 else
1809 sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
1811 // GUID provided
1812 // Warn if player also selected a creature
1813 // -> Creature selection is ignored <-
1814 if(target)
1816 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
1818 lowguid = atoi((char*)guid_str);
1820 // lowguid -> GUID of the NPC
1821 // point -> number of the waypoint (if not 0)
1822 sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
1824 Creature* pCreature = NULL;
1826 if(lowguid)
1827 pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1829 // attempt check creature existance by DB
1830 if(!pCreature)
1832 QueryResult *result = sDatabase.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",lowguid);
1833 if(!result)
1835 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
1836 return true;
1838 delete result;
1841 sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
1843 QueryResult *result = sDatabase.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid);
1844 if( result )
1846 point = (*result)[0].GetUInt32()+1;
1847 delete result;
1849 else
1850 point = 1;
1852 Player* player = m_session->GetPlayer();
1854 sDatabase.PExecuteLog("INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`) VALUES ('%u','%u','%f', '%f', '%f', '%f')",
1855 lowguid, point, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation());
1857 // update movement type
1858 sDatabase.PExecuteLog("UPDATE `creature` SET `MovementType` = '%u' WHERE `guid` = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1859 if(pCreature)
1861 pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1862 (*pCreature)->Initialize();
1863 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1865 pCreature->setDeathState(JUST_DIED);
1866 pCreature->RemoveCorpse();
1867 pCreature->Respawn();
1871 PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
1873 return true;
1874 } // HandleWpAddCommand
1877 * .wp modify emote | spell | text | del | move | add
1879 * add -> add a WP after the selected visual waypoint
1880 * User must select a visual waypoint and then issue ".wp modify add"
1882 * emote <emoteID>
1883 * User has selected a visual waypoint before.
1884 * <emoteID> is added to this waypoint. Everytime the
1885 * NPC comes to this waypoint, the emote is called.
1887 * emote <GUID> <WPNUM> <emoteID>
1888 * User has not selected visual waypoint before.
1889 * For the waypoint <WPNUM> for the NPC with <GUID>
1890 * an emote <emoteID> is added.
1891 * Everytime the NPC comes to this waypoint, the emote is called.
1894 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
1896 bool ChatHandler::HandleWpModifyCommand(const char* args)
1898 sLog.outDebug("DEBUG: HandleWpModifyCommand");
1900 if(!*args)
1901 return false;
1903 // first arg: add del text emote spell waittime move
1904 char* show_str = strtok((char*)args, " ");
1905 if (!show_str)
1907 return false;
1910 std::string show = show_str;
1911 // Check
1912 // Remember: "show" must also be the name of a column!
1913 if( (show != "emote") && (show != "spell") && (show != "aiscript")
1914 && (show != "text1") && (show != "text2") && (show != "text3") && (show != "text4") && (show != "text5")
1915 && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
1916 && (show != "model1") && (show != "model2") && (show != "orientation")
1917 && (show != "import") && (show != "export") )
1919 return false;
1922 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
1923 char* arg_str = NULL;
1925 // Did user provide a GUID
1926 // or did the user select a creature?
1927 // -> variable lowguid is filled with the GUID of the NPC
1928 uint32 lowguid = 0;
1929 uint32 point = 0;
1930 uint32 wpGuid = 0;
1931 Unit* target = getSelectedCreature();
1933 if(target)
1935 sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
1937 // The visual waypoint
1938 Creature* wpCreature = NULL;
1940 wpGuid = target->GetGUIDLow();
1942 // Did the user select a visual spawnpoint?
1943 if(wpGuid)
1944 wpCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(wpGuid,HIGHGUID_UNIT));
1946 // attempt check creature existance by DB
1947 if(!wpCreature)
1949 QueryResult *result = sDatabase.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",wpGuid);
1950 if(!result)
1952 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, wpGuid);
1953 return true;
1955 delete result;
1957 // User did select a visual waypoint?
1958 // Check the creature
1959 if (wpCreature->GetEntry() != VISUAL_WAYPOINT )
1961 if( (show != "export") && (show != "import") )
1963 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
1964 return true;
1966 lowguid = wpGuid;
1967 arg_str = strtok((char*)NULL, " ");
1969 else
1971 QueryResult *result =
1972 sDatabase.PQuery( "SELECT `id`, `point` FROM `creature_movement` WHERE `wpguid` = %u",
1973 target->GetGUIDLow() );
1974 if(!result)
1976 sLog.outDebug("DEBUG: HandleWpModifyCommand - No waypoint found - used 'wpguid'");
1978 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
1979 // Select waypoint number from database
1980 // Since we compare float values, we have to deal with
1981 // some difficulties.
1982 // Here we search for all waypoints that only differ in one from 1 thousand
1983 // (0.001) - There is no other way to compare C++ floats with mySQL floats
1984 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
1985 const char* maxDIFF = "0.01";
1986 result = sDatabase.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 )",
1987 wpCreature->GetPositionX(), maxDIFF, wpCreature->GetPositionY(), maxDIFF, wpCreature->GetPositionZ(), maxDIFF);
1988 if(!result)
1990 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
1991 return true;
1994 sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
1998 Field *fields = result->Fetch();
1999 lowguid = fields[0].GetUInt32();
2000 point = fields[1].GetUInt32();
2001 }while( result->NextRow() );
2003 // Cleanup memory
2004 sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2005 delete result;
2006 // We have the waypoint number and the GUID of the "master npc"
2007 // Text is enclosed in "<>", all other arguments not
2008 if( show.find("text") != std::string::npos )
2010 arg_str = strtok((char*)NULL, "<>");
2012 else
2014 arg_str = strtok((char*)NULL, " ");
2018 else
2020 // User did provide <GUID> <WPNUM>
2021 char* guid_str = strtok((char*)NULL, " ");
2022 char* point_str = strtok((char*)NULL, " ");
2024 // Text is enclosed in "<>", all other arguments not
2025 if( show.find("text") != std::string::npos )
2027 arg_str = strtok((char*)NULL, "<>");
2029 else
2031 arg_str = strtok((char*)NULL, " ");
2034 if( !guid_str )
2036 SendSysMessage(LANG_WAYPOINT_NOGUID);
2037 return false;
2039 if( !point_str )
2041 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2042 return false;
2044 if( (show != "del") && (show != "move") && (show != "add") )
2046 if( !arg_str )
2048 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show.c_str());
2049 return false;
2052 lowguid = atoi((char*)guid_str);
2053 PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2054 point = atoi((char*)point_str);
2055 PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2057 // Now we need the GUID of the visual waypoint
2058 // -> "del", "move", "add" command
2060 QueryResult *result = sDatabase.PQuery( "SELECT `wpguid` FROM `creature_movement` WHERE `id` = '%u' AND `point` = '%u'", lowguid, point);
2061 if(result)
2065 Field *fields = result->Fetch();
2066 wpGuid = fields[0].GetUInt32();
2067 }while( result->NextRow() );
2069 // Free memory
2070 delete result;
2072 else
2074 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2075 // Select waypoint number from database
2076 QueryResult *result = sDatabase.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point`='%d' AND `id` = '%u'", point, lowguid);
2077 if(!result)
2079 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2080 return true;
2083 Field *fields = result->Fetch();
2084 float x = fields[0].GetFloat();
2085 float y = fields[1].GetFloat();
2086 float z = fields[2].GetFloat();
2087 // Cleanup memory
2088 delete result;
2090 // Select waypoint number from database
2091 // Since we compare float values, we have to deal with
2092 // some difficulties.
2093 // Here we search for all waypoints that only differ in one from 1 thousand
2094 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2095 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2096 const char* maxDIFF = "0.01";
2098 result = sDatabase.PQuery( "SELECT `guid` FROM `creature` WHERE (abs(`position_x` - %f) <= %s ) and (abs(`position_y` - %f) <= %s ) and (abs(`position_z` - %f) <= %s ) and `id`=%d",
2099 x, maxDIFF, y, maxDIFF, z, maxDIFF, VISUAL_WAYPOINT);
2100 if(!result)
2102 PSendSysMessage(LANG_WAYPOINT_WPCREATNOTFOUND, VISUAL_WAYPOINT);
2103 return true;
2107 Field *fields = result->Fetch();
2108 wpGuid = fields[0].GetUInt32();
2109 }while( result->NextRow() );
2111 // Free memory
2112 delete result;
2116 sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2118 // Check for argument
2119 if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add") && (show != "aiscript"))
2121 if( arg_str == NULL )
2123 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2124 return false;
2127 // wpGuid -> GUID of the waypoint creature
2128 // lowguid -> GUID of the NPC
2129 // point -> waypoint number
2131 // Special functions:
2132 // add - move - del -> no args commands
2133 // Add a waypoint after the selected visual
2134 if(show == "add")
2136 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2138 // Get the creature for which we read the waypoint
2139 Creature* npcCreature = NULL;
2140 npcCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), MAKE_GUID(lowguid, HIGHGUID_UNIT));
2142 if( !npcCreature )
2144 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2145 return true;
2147 else
2149 // obtain real GUID for DB operations
2150 lowguid = npcCreature->GetDBTableGUIDLow();
2152 sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2154 // What to do:
2155 // Add the visual spawnpoint (DB only)
2156 // Adjust the waypoints
2157 // Respawn the owner of the waypoints
2158 sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- SELECT MAX(`point`)");
2159 QueryResult *result = sDatabase.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid);
2160 uint32 maxPoint = 0;
2161 if( result )
2163 maxPoint = (*result)[0].GetUInt32();
2164 delete result;
2166 for( uint32 i=maxPoint; i>point; i-- )
2168 sDatabase.PExecuteLog("UPDATE `creature_movement` SET point=point+1 WHERE id='%u' AND point='%u'", lowguid, i);
2171 Player* chr = m_session->GetPlayer();
2172 sDatabase.PExecuteLog("INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES ('%u','%u','%f', '%f', '%f')",
2173 lowguid, point+1, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
2175 if(npcCreature)
2177 (*npcCreature)->Initialize();
2178 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2180 npcCreature->setDeathState(JUST_DIED);
2181 npcCreature->RemoveCorpse();
2182 npcCreature->Respawn();
2186 Creature* wpCreature = new Creature(chr);
2187 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(),
2188 chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation(), VISUAL_WAYPOINT))
2190 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2191 delete wpCreature;
2192 return false;
2194 sDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '%u' WHERE `id` = '%u' and `point` = '%u'", wpCreature->GetGUIDLow(), lowguid, point+1);
2196 wpCreature->SaveToDB();
2197 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2198 wpCreature->LoadFromDB(wpCreature->GetGUIDLow(), chr->GetInstanceId());
2199 MapManager::Instance().GetMap(wpCreature->GetMapId(), wpCreature)->Add(wpCreature);
2201 PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2202 return true;
2203 } // add
2205 if(show == "del")
2207 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2209 // Get the creature for which we read the waypoint
2210 Creature* npcCreature = NULL;
2211 npcCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid, HIGHGUID_UNIT));
2213 // wpCreature
2214 Creature* wpCreature = NULL;
2215 if( wpGuid != 0 )
2217 wpCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(wpGuid, HIGHGUID_UNIT));
2218 wpCreature->CombatStop(true);
2219 wpCreature->DeleteFromDB();
2220 ObjectAccessor::Instance().AddObjectToRemoveList(wpCreature);
2223 // What to do:
2224 // Remove the visual spawnpoint
2225 // Adjust the waypoints
2226 // Respawn the owner of the waypoints
2228 sDatabase.PExecuteLog("DELETE FROM `creature_movement` WHERE id='%u' AND point='%u'",
2229 lowguid, point);
2230 sDatabase.PExecuteLog("UPDATE `creature_movement` SET point=point-1 WHERE id='%u' AND point>'%u'",
2231 lowguid, point);
2233 if(npcCreature)
2235 // Any waypoints left?
2236 QueryResult *result2 = sDatabase.PQuery( "SELECT `point` FROM `creature_movement` WHERE `id` = '%u'",lowguid);
2237 if(!result2)
2239 npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2241 else
2243 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2244 delete result2;
2246 (*npcCreature)->Initialize();
2247 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2249 npcCreature->setDeathState(JUST_DIED);
2250 npcCreature->RemoveCorpse();
2251 npcCreature->Respawn();
2255 PSendSysMessage(LANG_WAYPOINT_REMOVED);
2256 return true;
2257 } // del
2259 if(show == "move")
2261 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2263 Player *chr = m_session->GetPlayer();
2265 // Get the creature for which we read the waypoint
2266 Creature* npcCreature = NULL;
2267 npcCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
2269 // wpCreature
2270 Creature* wpCreature = NULL;
2271 // What to do:
2272 // Move the visual spawnpoint
2273 // Respawn the owner of the waypoints
2274 if( wpGuid != 0 )
2276 wpCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(wpGuid, HIGHGUID_UNIT));
2277 wpCreature->CombatStop(true);
2278 wpCreature->DeleteFromDB();
2279 ObjectAccessor::Instance().AddObjectToRemoveList(wpCreature);
2280 // re-create
2281 Creature* wpCreature2 = new Creature(chr);
2282 if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(),
2283 chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation(), VISUAL_WAYPOINT))
2285 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2286 delete wpCreature2;
2287 return false;
2289 wpCreature2->SaveToDB();
2290 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2291 wpCreature2->LoadFromDB(wpCreature2->GetGUIDLow(), chr->GetInstanceId());
2292 MapManager::Instance().GetMap(npcCreature->GetMapId(), npcCreature)->Add(wpCreature2);
2293 //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2296 sDatabase.PExecuteLog("UPDATE `creature_movement` SET `position_x` = '%f',`position_y` = '%f',`position_z` = '%f' where `id` = '%u' AND point='%u'",
2297 chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), lowguid, point );
2299 if(npcCreature)
2301 (*npcCreature)->Initialize();
2302 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2304 npcCreature->setDeathState(JUST_DIED);
2305 npcCreature->RemoveCorpse();
2306 npcCreature->Respawn();
2309 PSendSysMessage(LANG_WAYPOINT_CHANGED);
2311 return true;
2312 } // move
2314 if(show == "export")
2316 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
2318 std::ofstream outfile;
2319 outfile.open (arg_str);
2321 QueryResult *result = sDatabase.PQuery(
2322 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2323 "SELECT `point`, `position_x`, `position_y`, `position_z`, `orientation`, `model1`, `model2`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `aiscript`, `id` FROM `creature_movement` WHERE `id` = '%u' ORDER BY `point`", lowguid );
2325 if( result )
2329 Field *fields = result->Fetch();
2331 outfile << "insert into creature_movement ";
2332 outfile << "( `id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `model1`, `model2`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `aiscript` ) values ";
2334 //sLog.outDebug("( ");
2335 outfile << "( ";
2336 //sLog.outDebug("id");
2337 outfile << fields[16].GetUInt32(); // id
2338 outfile << ", ";
2339 //sLog.outDebug("point");
2340 outfile << fields[0].GetUInt32(); // point
2341 outfile << ", ";
2342 //sLog.outDebug("position_x");
2343 outfile << fields[1].GetFloat(); // position_x
2344 outfile << ", ";
2345 //sLog.outDebug("position_y");
2346 outfile << fields[2].GetFloat(); // position_y
2347 outfile << ", ";
2348 //sLog.outDebug("position_z");
2349 outfile << fields[3].GetUInt32(); // position_z
2350 outfile << ", ";
2351 //sLog.outDebug("orientation");
2352 outfile << fields[4].GetUInt32(); // orientation
2353 outfile << ", ";
2354 //sLog.outDebug("model1");
2355 outfile << fields[5].GetUInt32(); // model1
2356 outfile << ", ";
2357 //sLog.outDebug("model2");
2358 outfile << fields[6].GetUInt32(); // model2
2359 outfile << ", ";
2360 //sLog.outDebug("waittime");
2361 outfile << fields[7].GetUInt16(); // waittime
2362 outfile << ", ";
2363 //sLog.outDebug("emote");
2364 outfile << fields[8].GetUInt32(); // emote
2365 outfile << ", ";
2366 //sLog.outDebug("spell");
2367 outfile << fields[9].GetUInt32(); // spell
2368 outfile << ", ";
2369 //sLog.outDebug("text1");
2370 const char *tmpChar = fields[10].GetString();
2371 if( !tmpChar )
2373 outfile << "NULL"; // text1
2375 else
2377 outfile << "'";
2378 outfile << tmpChar; // text1
2379 outfile << "'";
2381 outfile << ", ";
2382 //sLog.outDebug("text2");
2383 tmpChar = fields[11].GetString();
2384 if( !tmpChar )
2386 outfile << "NULL"; // text2
2388 else
2390 outfile << "'";
2391 outfile << tmpChar; // text2
2392 outfile << "'";
2394 outfile << ", ";
2395 //sLog.outDebug("text3");
2396 tmpChar = fields[12].GetString();
2397 if( !tmpChar )
2399 outfile << "NULL"; // text3
2401 else
2403 outfile << "'";
2404 outfile << tmpChar; // text3
2405 outfile << "'";
2407 outfile << ", ";
2408 //sLog.outDebug("text4");
2409 tmpChar = fields[13].GetString();
2410 if( !tmpChar )
2412 outfile << "NULL"; // text4
2414 else
2416 outfile << "'";
2417 outfile << tmpChar; // text4
2418 outfile << "'";
2420 outfile << ", ";
2421 //sLog.outDebug("text5");
2422 tmpChar = fields[14].GetString();
2423 if( !tmpChar )
2425 outfile << "NULL"; // text5
2427 else
2429 outfile << "'";
2430 outfile << tmpChar; // text5
2431 outfile << "'";
2433 outfile << ", ";
2434 //sLog.outDebug("aiscript");
2435 tmpChar = fields[15].GetString();
2436 if( !tmpChar )
2438 outfile << "NULL"; // aiscript
2440 else
2442 outfile << "'";
2443 outfile << tmpChar; // aiscript
2444 outfile << "'";
2446 outfile << ");\n ";
2448 } while( result->NextRow() );
2449 delete result;
2451 PSendSysMessage(LANG_WAYPOINT_EXPORTED);
2453 else
2455 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
2456 outfile << LANG_WAYPOINT_NOTHINGTOEXPORT;
2458 outfile.close();
2460 return true;
2462 if(show == "import")
2464 PSendSysMessage("DEBUG: wp import, GUID: %u", lowguid);
2466 std::string line;
2467 std::ifstream infile (arg_str);
2468 if (infile.is_open())
2470 while (! infile.eof() )
2472 getline (infile,line);
2473 //cout << line << endl;
2474 QueryResult *result = sDatabase.PQuery(line.c_str());
2475 delete result;
2477 infile.close();
2479 PSendSysMessage(LANG_WAYPOINT_IMPORTED);
2481 return true;
2484 // Create creature - npc that has the waypoint
2485 Creature* npcCreature = NULL;
2487 if(lowguid)
2488 npcCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
2490 // attempt check creature existance by DB
2491 if(!npcCreature)
2493 if(!objmgr.GetCreatureData(lowguid))
2495 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2496 return true;
2500 const char *text = arg_str;
2502 if( text == 0 )
2504 // show_str check for present in list of correct values, no sql injection possible
2505 sDatabase.PExecuteLog("UPDATE `creature_movement` SET %s=NULL WHERE id='%u' AND point='%u'",
2506 show_str, lowguid, point);
2508 else
2510 // show_str check for present in list of correct values, no sql injection possible
2511 std::string text2 = text;
2512 sDatabase.escape_string(text2);
2513 sDatabase.PExecuteLog("UPDATE `creature_movement` SET %s='%s' WHERE id='%u' AND point='%u'",
2514 show_str, text2.c_str(), lowguid, point);
2517 if(npcCreature)
2519 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2520 (*npcCreature)->Initialize();
2521 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2523 npcCreature->setDeathState(JUST_DIED);
2524 npcCreature->RemoveCorpse();
2525 npcCreature->Respawn();
2528 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2530 return true;
2534 * .wp show info | on | off
2536 * info -> User has selected a visual waypoint before
2538 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2539 * provided the GUID of the NPC and the number of
2540 * the waypoint.
2542 * on -> User has selected an NPC; all visual waypoints for this
2543 * NPC are added to the world
2545 * on <GUID> -> User did not select an NPC - instead the GUID of the
2546 * NPC is provided. All visual waypoints for this NPC
2547 * are added from the world.
2549 * off -> User has selected an NPC; all visual waypoints for this
2550 * NPC are removed from the world.
2552 * on <GUID> -> User did not select an NPC - instead the GUID of the
2553 * NPC is provided. All visual waypoints for this NPC
2554 * are removed from the world.
2558 bool ChatHandler::HandleWpShowCommand(const char* args)
2560 sLog.outDebug("DEBUG: HandleWpShowCommand");
2562 if(!*args)
2563 return false;
2565 // first arg: on, off, first, last
2566 char* show_str = strtok((char*)args, " ");
2567 if (!show_str)
2569 return false;
2571 // second arg: GUID (optional, if a creature is selected)
2572 char* guid_str = strtok((char*)NULL, " ");
2573 sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2574 //if (!guid_str) {
2575 // return false;
2578 // Did user provide a GUID
2579 // or did the user select a creature?
2580 // -> variable lowguid is filled with the GUID
2581 uint32 lowguid = 0;
2582 Unit* target = getSelectedCreature();
2583 // Did player provide a GUID?
2584 if (!guid_str)
2586 sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2587 // No GUID provided
2588 // -> Player must have selected a creature
2590 if(!target)
2592 SendSysMessage(LANG_SELECT_CREATURE);
2593 return true;
2595 lowguid = target->GetGUIDLow();
2597 else
2599 sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2600 // GUID provided
2601 // Warn if player also selected a creature
2602 // -> Creature selection is ignored <-
2603 if(target)
2605 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2607 lowguid = atoi((char*)guid_str);
2610 sLog.outDebug("DEBUG: HandleWpShowCommand: danach");
2612 std::string show = show_str;
2613 uint32 Maxpoint;
2615 Creature* pCreature = NULL;
2617 sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
2618 if(lowguid)
2619 pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
2621 sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", pCreature );
2622 // attempt check creature existance by DB
2623 if(!pCreature)
2625 if(!objmgr.GetCreatureData(lowguid))
2627 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2628 return true;
2632 sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
2633 //PSendSysMessage("wpshow - show: %s", show);
2635 // Show info for the selected waypoint
2636 if(show == "info")
2638 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
2640 // Check if the user did specify a visual waypoint
2641 if( pCreature->GetEntry() != VISUAL_WAYPOINT )
2643 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2644 return true;
2647 //PSendSysMessage("wp on, GUID: %u", lowguid);
2649 //pCreature->GetPositionX();
2651 QueryResult *result =
2652 sDatabase.PQuery( "SELECT `id`, `point`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `model1`, `model2`, `aiscript` FROM `creature_movement` WHERE `wpguid` = %u",
2653 pCreature->GetGUID() );
2654 if(!result)
2656 // Since we compare float values, we have to deal with
2657 // some difficulties.
2658 // Here we search for all waypoints that only differ in one from 1 thousand
2659 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2660 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2661 const char* maxDIFF = "0.01";
2662 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, pCreature->GetGUID());
2664 result = sDatabase.PQuery( "SELECT `id`, `point`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `model1`, `model2`, `aiscript` FROM `creature_movement` WHERE (abs(`position_x` - %f) <= %s ) and (abs(`position_y` - %f) <= %s ) and (abs(`position_z` - %f) <= %s )",
2665 pCreature->GetPositionX(), maxDIFF, pCreature->GetPositionY(), maxDIFF, pCreature->GetPositionZ(), maxDIFF);
2666 if(!result)
2668 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2669 return true;
2674 Field *fields = result->Fetch();
2675 uint32 creGUID = fields[0].GetUInt32();
2676 uint32 point = fields[1].GetUInt32();
2677 int waittime = fields[2].GetUInt32();
2678 uint32 emote = fields[3].GetUInt32();
2679 uint32 spell = fields[4].GetUInt32();
2680 const char * text1 = fields[5].GetString();
2681 const char * text2 = fields[6].GetString();
2682 const char * text3 = fields[7].GetString();
2683 const char * text4 = fields[8].GetString();
2684 const char * text5 = fields[9].GetString();
2685 uint32 model1 = fields[10].GetUInt32();
2686 uint32 model2 = fields[11].GetUInt32();
2687 const char * aiscript = fields[12].GetString();
2688 // Get the creature for which we read the waypoint
2689 Creature* wpCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(creGUID,HIGHGUID_UNIT));
2691 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
2692 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
2693 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
2694 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
2695 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
2696 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
2697 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
2698 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
2699 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
2700 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
2701 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
2702 PSendSysMessage(LANG_WAYPOINT_INFO_AISCRIPT, aiscript);
2704 }while( result->NextRow() );
2705 // Cleanup memory
2706 delete result;
2707 return true;
2710 if(show == "on")
2712 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
2714 QueryResult *result = sDatabase.PQuery( "SELECT `point`, `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `id` = '%u'",lowguid);
2715 if(!result)
2717 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2718 return true;
2720 // Delete all visuals for this NPC
2721 QueryResult *result2 = sDatabase.PQuery( "SELECT `wpguid` FROM `creature_movement` WHERE `id` = '%u' and wpguid <> 0", lowguid);
2722 if(result2)
2724 bool hasError = false;
2727 Field *fields = result2->Fetch();
2728 uint32 wpguid = fields[0].GetUInt32();
2729 Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(wpguid,HIGHGUID_UNIT));
2731 if(!pCreature)
2733 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
2734 hasError = true;
2735 sDatabase.PExecuteLog("DELETE FROM `creature` WHERE `guid` = '%u'", wpguid);
2737 else
2739 pCreature->CombatStop(true);
2740 pCreature->DeleteFromDB();
2741 ObjectAccessor::Instance().AddObjectToRemoveList(pCreature);
2744 }while( result2->NextRow() );
2745 delete result2;
2746 if( hasError )
2748 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2749 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2750 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2756 Field *fields = result->Fetch();
2757 uint32 point = fields[0].GetUInt32();
2758 float x = fields[1].GetFloat();
2759 float y = fields[2].GetFloat();
2760 float z = fields[3].GetFloat();
2762 uint32 id = VISUAL_WAYPOINT;
2764 Player *chr = m_session->GetPlayer();
2765 float o = chr->GetOrientation();
2767 Creature* wpCreature = new Creature(chr);
2768 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id))
2770 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
2771 delete wpCreature;
2772 delete result;
2773 return false;
2775 wpCreature->SetVisibility(VISIBILITY_OFF);
2776 sLog.outDebug("DEBUG: UPDATE `creature_movement` SET `wpguid` = '%u");
2777 // set "wpguid" column to the visual waypoint
2778 sDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '%u' WHERE `id` = '%u' and `point` = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
2780 wpCreature->SaveToDB();
2781 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2782 wpCreature->LoadFromDB(wpCreature->GetGUIDLow(), chr->GetInstanceId());
2783 MapManager::Instance().GetMap(wpCreature->GetMapId(), wpCreature)->Add(wpCreature);
2784 //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
2785 }while( result->NextRow() );
2787 // Cleanup memory
2788 delete result;
2789 return true;
2792 if(show == "first")
2794 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
2796 QueryResult *result = sDatabase.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point`='1' AND `id` = '%u'",lowguid);
2797 if(!result)
2799 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2800 return true;
2803 Field *fields = result->Fetch();
2804 float x = fields[0].GetFloat();
2805 float y = fields[1].GetFloat();
2806 float z = fields[2].GetFloat();
2807 uint32 id = VISUAL_WAYPOINT;
2809 Player *chr = m_session->GetPlayer();
2810 float o = chr->GetOrientation();
2812 Creature* pCreature = new Creature(chr);
2813 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id))
2815 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
2816 delete pCreature;
2817 delete result;
2818 return false;
2821 pCreature->SaveToDB();
2822 pCreature->LoadFromDB(pCreature->GetGUIDLow(), chr->GetInstanceId());
2823 MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
2824 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
2826 // Cleanup memory
2827 delete result;
2828 return true;
2831 if(show == "last")
2833 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
2835 QueryResult *result = sDatabase.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid);
2836 if( result )
2838 Maxpoint = (*result)[0].GetUInt32();
2840 delete result;
2842 else
2843 Maxpoint = 0;
2845 result = sDatabase.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point` ='%u' AND `id` = '%u'",Maxpoint, lowguid);
2846 if(!result)
2848 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
2849 return true;
2851 Field *fields = result->Fetch();
2852 float x = fields[0].GetFloat();
2853 float y = fields[1].GetFloat();
2854 float z = fields[2].GetFloat();
2855 uint32 id = VISUAL_WAYPOINT;
2857 Player *chr = m_session->GetPlayer();
2858 float o = chr->GetOrientation();
2860 Creature* pCreature = new Creature(chr);
2861 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), chr->GetMapId(), x, y, z, o, id))
2863 PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
2864 delete pCreature;
2865 delete result;
2866 return false;
2869 pCreature->SaveToDB();
2870 pCreature->LoadFromDB(pCreature->GetGUIDLow(), chr->GetInstanceId());
2871 MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);
2872 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
2873 // Cleanup memory
2874 delete result;
2875 return true;
2878 if(show == "off")
2880 QueryResult *result = sDatabase.PQuery("SELECT `guid` FROM `creature` WHERE `id` = '%d'", VISUAL_WAYPOINT);
2881 if(!result)
2883 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
2884 return true;
2886 bool hasError = false;
2889 Field *fields = result->Fetch();
2890 uint32 guid = fields[0].GetUInt32();
2891 Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(),MAKE_GUID(guid,HIGHGUID_UNIT));
2893 //Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), guid);
2895 if(!pCreature)
2897 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
2898 hasError = true;
2899 sDatabase.PExecuteLog("DELETE FROM `creature` WHERE `guid` = '%u'", guid);
2901 else
2903 pCreature->CombatStop(true);
2905 pCreature->DeleteFromDB();
2907 ObjectAccessor::Instance().AddObjectToRemoveList(pCreature);
2909 }while(result->NextRow());
2910 // set "wpguid" column to "empty" - no visual waypoint spawned
2911 sDatabase.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '0'");
2913 if( hasError )
2915 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2916 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2917 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2920 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
2921 // Cleanup memory
2922 delete result;
2924 return true;
2927 PSendSysMessage("DEBUG: wpshow - no valid command found");
2929 return true;
2930 } // HandleWpShowCommand
2932 //rename character
2933 bool ChatHandler::HandleRenameCommand(const char* args)
2935 Player* target = NULL;
2936 uint64 targetGUID = 0;
2937 std::string oldname;
2939 char* px = strtok((char*)args, " ");
2941 if(px)
2943 oldname = px;
2944 normalizePlayerName(oldname);
2945 //sDatabase.escape_string(oldname);
2946 target = objmgr.GetPlayer(oldname.c_str());
2948 if (!target)
2949 targetGUID = objmgr.GetPlayerGUIDByName(oldname);
2952 if(!target && !targetGUID)
2954 target = getSelectedPlayer();
2957 if(!target && !targetGUID)
2959 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2960 return true;
2963 if(target)
2965 PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
2966 target->SetNeedRename(true);
2967 sDatabase.PExecute("UPDATE `character` SET `rename` = '1' WHERE `guid` = '%u'", target->GetGUIDLow());
2969 else
2971 PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
2972 sDatabase.PExecute("UPDATE `character` SET `rename` = '1' WHERE `guid` = '%u'", GUID_LOPART(targetGUID));
2975 return true;
2978 //spawn go
2979 bool ChatHandler::HandleGameObjectCommand(const char* args)
2981 if (!*args)
2982 return false;
2984 char* pParam1 = strtok((char*)args, " ");
2985 uint32 id = atoi((char*)pParam1);
2986 if(!id)
2987 return false;
2989 char* lootID = strtok(NULL, " ");
2990 char* spawntimeSecs = strtok(NULL, " ");
2992 const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
2994 if (!goI)
2996 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
2997 return false;
3000 Player *chr = m_session->GetPlayer();
3001 float x = float(chr->GetPositionX());
3002 float y = float(chr->GetPositionY());
3003 float z = float(chr->GetPositionZ());
3004 float o = float(chr->GetOrientation());
3006 float rot2 = sin(o/2);
3007 float rot3 = cos(o/2);
3009 GameObject* pGameObj = new GameObject(chr);
3010 uint32 lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
3012 if(!pGameObj->Create(lowGUID, goI->id, chr->GetMapId(), x, y, z, o, 0, 0, rot2, rot3, 0, 0))
3014 delete pGameObj;
3015 return false;
3017 //pGameObj->SetZoneId(chr->GetZoneId());
3018 pGameObj->SetMapId(chr->GetMapId());
3019 //pGameObj->SetNameId(id);
3020 sLog.outDebug(LANG_GAMEOBJECT_CURRENT, goI->name, lowGUID, x, y, z, o);
3022 if( lootID )
3024 uint32 value = atoi((char*)lootID);
3025 pGameObj->lootid = value;
3026 //sLog.outDebug("*** LOOT: %d", value);
3029 if( spawntimeSecs )
3031 uint32 value = atoi((char*)spawntimeSecs);
3032 pGameObj->SetRespawnTime(value);
3033 //sLog.outDebug("*** spawntimeSecs: %d", value);
3036 pGameObj->SaveToDB();
3037 MapManager::Instance().GetMap(pGameObj->GetMapId(), pGameObj)->Add(pGameObj);
3039 PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,lowGUID,x,y,z);
3041 return true;
3044 //show animation
3045 bool ChatHandler::HandleAnimCommand(const char* args)
3047 if (!*args)
3048 return false;
3050 uint32 anim_id = atoi((char*)args);
3052 WorldPacket data( SMSG_EMOTE, (8+4) );
3053 data << anim_id << m_session->GetPlayer( )->GetGUID();
3054 WPAssert(data.size() == 12);
3055 MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(), m_session->GetPlayer())->MessageBoardcast(m_session->GetPlayer(), &data, true);
3056 return true;
3059 //change standstate
3060 bool ChatHandler::HandleStandStateCommand(const char* args)
3062 if (!*args)
3063 return false;
3065 uint32 anim_id = atoi((char*)args);
3066 m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3068 return true;