[7923] Search all available locale skill names in .learn all_recipes
[getmangos.git] / src / game / Level2.cpp
blob7cd09d8ce668ee52e028f88beeff13be5e700ce7
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
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 "ObjectMgr.h"
22 #include "Player.h"
23 #include "Item.h"
24 #include "GameObject.h"
25 #include "Opcodes.h"
26 #include "Chat.h"
27 #include "ObjectAccessor.h"
28 #include "MapManager.h"
29 #include "Language.h"
30 #include "World.h"
31 #include "GameEventMgr.h"
32 #include "SpellMgr.h"
33 #include "PoolHandler.h"
34 #include "AccountMgr.h"
35 #include "GMTicketMgr.h"
36 #include "WaypointManager.h"
37 #include "Util.h"
38 #include <cctype>
39 #include <iostream>
40 #include <fstream>
41 #include <map>
42 #include "GlobalEvents.h"
44 #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
46 static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
48 LANG_REP_HATED, LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL,
49 LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED, LANG_REP_EXALTED
52 //mute player for some times
53 bool ChatHandler::HandleMuteCommand(const char* args)
55 char* nameStr;
56 char* delayStr;
57 extractOptFirstArg((char*)args,&nameStr,&delayStr);
58 if(!delayStr)
59 return false;
61 Player* target;
62 uint64 target_guid;
63 std::string target_name;
64 if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
65 return false;
67 uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
69 // find only player from same account if any
70 if(!target)
72 if(WorldSession* session = sWorld.FindSession(account_id))
73 target = session->GetPlayer();
76 uint32 notspeaktime = (uint32) atoi(delayStr);
78 // must have strong lesser security level
79 if(HasLowerSecurity (target,target_guid,true))
80 return false;
82 time_t mutetime = time(NULL) + notspeaktime*60;
84 if (target)
85 target->GetSession()->m_muteTime = mutetime;
87 loginDatabase.PExecute("UPDATE account SET mutetime = " UI64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
89 if(target)
90 ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
92 std::string nameLink = playerLink(target_name);
94 PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);
95 return true;
98 //unmute player
99 bool ChatHandler::HandleUnmuteCommand(const char* args)
101 Player* target;
102 uint64 target_guid;
103 std::string target_name;
104 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
105 return false;
107 uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
109 // find only player from same account if any
110 if(!target)
112 if(WorldSession* session = sWorld.FindSession(account_id))
113 target = session->GetPlayer();
116 // must have strong lesser security level
117 if(HasLowerSecurity (target,target_guid,true))
118 return false;
120 if (target)
122 if(target->CanSpeak())
124 SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
125 SetSentErrorMessage(true);
126 return false;
129 target->GetSession()->m_muteTime = 0;
132 loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
134 if(target)
135 ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
137 std::string nameLink = playerLink(target_name);
139 PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());
140 return true;
143 bool ChatHandler::HandleGoTriggerCommand(const char* args)
145 Player* _player = m_session->GetPlayer();
147 if (!*args)
148 return false;
150 char *atId = strtok((char*)args, " ");
151 if (!atId)
152 return false;
154 int32 i_atId = atoi(atId);
156 if(!i_atId)
157 return false;
159 AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
160 if (!at)
162 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
163 SetSentErrorMessage(true);
164 return false;
167 if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
169 PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
170 SetSentErrorMessage(true);
171 return false;
174 // stop flight if need
175 if(_player->isInFlight())
177 _player->GetMotionMaster()->MovementExpired();
178 _player->m_taxi.ClearTaxiDestinations();
180 // save only in non-flight case
181 else
182 _player->SaveRecallPosition();
184 _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
185 return true;
188 bool ChatHandler::HandleGoGraveyardCommand(const char* args)
190 Player* _player = m_session->GetPlayer();
192 if (!*args)
193 return false;
195 char *gyId = strtok((char*)args, " ");
196 if (!gyId)
197 return false;
199 int32 i_gyId = atoi(gyId);
201 if(!i_gyId)
202 return false;
204 WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
205 if (!gy)
207 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
208 SetSentErrorMessage(true);
209 return false;
212 if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
214 PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
215 SetSentErrorMessage(true);
216 return false;
219 // stop flight if need
220 if(_player->isInFlight())
222 _player->GetMotionMaster()->MovementExpired();
223 _player->m_taxi.ClearTaxiDestinations();
225 // save only in non-flight case
226 else
227 _player->SaveRecallPosition();
229 _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
230 return true;
233 /** \brief Teleport the GM to the specified creature
235 * .gocreature <GUID> --> TP using creature.guid
236 * .gocreature azuregos --> TP player to the mob with this name
237 * Warning: If there is more than one mob with this name
238 * you will be teleported to the first one that is found.
239 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
240 * Warning: If there is more than one mob with this "id"
241 * you will be teleported to the first one that is found.
243 //teleport to creature
244 bool ChatHandler::HandleGoCreatureCommand(const char* args)
246 if(!*args)
247 return false;
248 Player* _player = m_session->GetPlayer();
250 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
251 char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
252 if (!pParam1)
253 return false;
255 std::ostringstream whereClause;
257 // User wants to teleport to the NPC's template entry
258 if( strcmp(pParam1, "id") == 0 )
260 //sLog.outError("DEBUG: ID found");
262 // Get the "creature_template.entry"
263 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
264 char* tail = strtok(NULL,"");
265 if(!tail)
266 return false;
267 char* cId = extractKeyFromLink(tail,"Hcreature_entry");
268 if(!cId)
269 return false;
271 int32 tEntry = atoi(cId);
272 //sLog.outError("DEBUG: ID value: %d", tEntry);
273 if(!tEntry)
274 return false;
276 whereClause << "WHERE id = '" << tEntry << "'";
278 else
280 //sLog.outError("DEBUG: ID *not found*");
282 int32 guid = atoi(pParam1);
284 // Number is invalid - maybe the user specified the mob's name
285 if(!guid)
287 std::string name = pParam1;
288 WorldDatabase.escape_string(name);
289 whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
291 else
293 whereClause << "WHERE guid = '" << guid << "'";
296 //sLog.outError("DEBUG: %s", whereClause.c_str());
298 QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
299 if (!result)
301 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
302 SetSentErrorMessage(true);
303 return false;
305 if( result->GetRowCount() > 1 )
307 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
310 Field *fields = result->Fetch();
311 float x = fields[0].GetFloat();
312 float y = fields[1].GetFloat();
313 float z = fields[2].GetFloat();
314 float ort = fields[3].GetFloat();
315 int mapid = fields[4].GetUInt16();
317 delete result;
319 if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
321 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
322 SetSentErrorMessage(true);
323 return false;
326 // stop flight if need
327 if(_player->isInFlight())
329 _player->GetMotionMaster()->MovementExpired();
330 _player->m_taxi.ClearTaxiDestinations();
332 // save only in non-flight case
333 else
334 _player->SaveRecallPosition();
336 _player->TeleportTo(mapid, x, y, z, ort);
337 return true;
340 //teleport to gameobject
341 bool ChatHandler::HandleGoObjectCommand(const char* args)
343 if(!*args)
344 return false;
346 Player* _player = m_session->GetPlayer();
348 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
349 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
350 if(!cId)
351 return false;
353 int32 guid = atoi(cId);
354 if(!guid)
355 return false;
357 float x, y, z, ort;
358 int mapid;
360 // by DB guid
361 if (GameObjectData const* go_data = objmgr.GetGOData(guid))
363 x = go_data->posX;
364 y = go_data->posY;
365 z = go_data->posZ;
366 ort = go_data->orientation;
367 mapid = go_data->mapid;
369 else
371 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
372 SetSentErrorMessage(true);
373 return false;
376 if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
378 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
379 SetSentErrorMessage(true);
380 return false;
383 // stop flight if need
384 if(_player->isInFlight())
386 _player->GetMotionMaster()->MovementExpired();
387 _player->m_taxi.ClearTaxiDestinations();
389 // save only in non-flight case
390 else
391 _player->SaveRecallPosition();
393 _player->TeleportTo(mapid, x, y, z, ort);
394 return true;
397 bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
399 Player* pl = m_session->GetPlayer();
400 QueryResult *result;
401 GameEventMgr::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
402 if(*args)
404 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
405 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
406 if(!cId)
407 return false;
409 uint32 id = atol(cId);
411 if(id)
412 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",
413 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
414 else
416 std::string name = cId;
417 WorldDatabase.escape_string(name);
418 result = WorldDatabase.PQuery(
419 "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_ "
420 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
421 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
424 else
426 std::ostringstream eventFilter;
427 eventFilter << " AND (event IS NULL ";
428 bool initString = true;
430 for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
432 if (initString)
434 eventFilter << "OR event IN (" <<*itr;
435 initString =false;
437 else
438 eventFilter << "," << *itr;
441 if (!initString)
442 eventFilter << "))";
443 else
444 eventFilter << ")";
446 result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
447 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
448 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
449 m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
452 if (!result)
454 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
455 return true;
458 bool found = false;
459 float x, y, z, o;
460 uint32 lowguid, id;
461 uint16 mapid, pool_id;
465 Field *fields = result->Fetch();
466 lowguid = fields[0].GetUInt32();
467 id = fields[1].GetUInt32();
468 x = fields[2].GetFloat();
469 y = fields[3].GetFloat();
470 z = fields[4].GetFloat();
471 o = fields[5].GetFloat();
472 mapid = fields[6].GetUInt16();
473 pool_id = poolhandler.IsPartOfAPool(lowguid, TYPEID_GAMEOBJECT);
474 if (!pool_id || (pool_id && poolhandler.IsSpawnedObject(pool_id, lowguid, TYPEID_GAMEOBJECT)))
475 found = true;
476 } while( result->NextRow() && (!found) );
478 delete result;
480 if (!found)
482 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
483 return false;
486 GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
488 if (!goI)
490 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
491 return false;
494 GameObject* target = m_session->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
496 PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
498 if(target)
500 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
501 if(curRespawnDelay < 0)
502 curRespawnDelay = 0;
504 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
505 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
507 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
509 return true;
512 //delete object by selection or guid
513 bool ChatHandler::HandleGameObjectDeleteCommand(const char* args)
515 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
516 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
517 if(!cId)
518 return false;
520 uint32 lowguid = atoi(cId);
521 if(!lowguid)
522 return false;
524 GameObject* obj = NULL;
526 // by DB guid
527 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
528 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
530 if(!obj)
532 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
533 SetSentErrorMessage(true);
534 return false;
537 uint64 owner_guid = obj->GetOwnerGUID();
538 if(owner_guid)
540 Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
541 if(!owner || !IS_PLAYER_GUID(owner_guid))
543 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
544 SetSentErrorMessage(true);
545 return false;
548 owner->RemoveGameObject(obj,false);
551 obj->SetRespawnTime(0); // not save respawn time
552 obj->Delete();
553 obj->DeleteFromDB();
555 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
557 return true;
560 //turn selected object
561 bool ChatHandler::HandleGameObjectTurnCommand(const char* args)
563 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
564 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
565 if(!cId)
566 return false;
568 uint32 lowguid = atoi(cId);
569 if(!lowguid)
570 return false;
572 GameObject* obj = NULL;
574 // by DB guid
575 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
576 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
578 if(!obj)
580 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
581 SetSentErrorMessage(true);
582 return false;
585 char* po = strtok(NULL, " ");
586 float o;
588 if (po)
590 o = (float)atof(po);
592 else
594 Player *chr = m_session->GetPlayer();
595 o = chr->GetOrientation();
598 Map* map = obj->GetMap();
599 map->Remove(obj,false);
601 obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
602 obj->UpdateRotationFields();
604 map->Add(obj);
606 obj->SaveToDB();
607 obj->Refresh();
609 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow(), o);
611 return true;
614 //move selected object
615 bool ChatHandler::HandleGameObjectMoveCommand(const char* args)
617 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
618 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
619 if(!cId)
620 return false;
622 uint32 lowguid = atoi(cId);
623 if(!lowguid)
624 return false;
626 GameObject* obj = NULL;
628 // by DB guid
629 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
630 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
632 if(!obj)
634 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
635 SetSentErrorMessage(true);
636 return false;
639 char* px = strtok(NULL, " ");
640 char* py = strtok(NULL, " ");
641 char* pz = strtok(NULL, " ");
643 if (!px)
645 Player *chr = m_session->GetPlayer();
647 Map* map = obj->GetMap();
648 map->Remove(obj,false);
650 obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
651 obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
652 obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
653 obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
655 map->Add(obj);
657 else
659 if(!py || !pz)
660 return false;
662 float x = (float)atof(px);
663 float y = (float)atof(py);
664 float z = (float)atof(pz);
666 if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
668 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
669 SetSentErrorMessage(true);
670 return false;
673 Map* map = obj->GetMap();
674 map->Remove(obj,false);
676 obj->Relocate(x, y, z, obj->GetOrientation());
677 obj->SetFloatValue(GAMEOBJECT_POS_X, x);
678 obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
679 obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
681 map->Add(obj);
684 obj->SaveToDB();
685 obj->Refresh();
687 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
689 return true;
692 //spawn go
693 bool ChatHandler::HandleGameObjectAddCommand(const char* args)
695 if (!*args)
696 return false;
698 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
699 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
700 if(!cId)
701 return false;
703 uint32 id = atol(cId);
704 if(!id)
705 return false;
707 char* spawntimeSecs = strtok(NULL, " ");
709 const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
711 if (!goI)
713 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
714 SetSentErrorMessage(true);
715 return false;
718 Player *chr = m_session->GetPlayer();
719 float x = float(chr->GetPositionX());
720 float y = float(chr->GetPositionY());
721 float z = float(chr->GetPositionZ());
722 float o = float(chr->GetOrientation());
723 Map *map = chr->GetMap();
725 GameObject* pGameObj = new GameObject;
726 uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
728 if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
730 delete pGameObj;
731 return false;
734 if( spawntimeSecs )
736 uint32 value = atoi((char*)spawntimeSecs);
737 pGameObj->SetRespawnTime(value);
738 //sLog.outDebug("*** spawntimeSecs: %d", value);
741 // fill the gameobject data and save to the db
742 pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()),chr->GetPhaseMaskForSpawn());
744 // this will generate a new guid if the object is in an instance
745 if(!pGameObj->LoadFromDB(db_lowGUID, map))
747 delete pGameObj;
748 return false;
751 sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
753 map->Add(pGameObj);
755 // TODO: is it really necessary to add both the real and DB table guid here ?
756 objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
758 PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
759 return true;
762 //set pahsemask for selected object
763 bool ChatHandler::HandleGameObjectPhaseCommand(const char* args)
765 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
766 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
767 if(!cId)
768 return false;
770 uint32 lowguid = atoi(cId);
771 if(!lowguid)
772 return false;
774 GameObject* obj = NULL;
776 // by DB guid
777 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
778 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
780 if(!obj)
782 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
783 SetSentErrorMessage(true);
784 return false;
787 char* phaseStr = strtok (NULL, " ");
788 uint32 phasemask = phaseStr? atoi(phaseStr) : 0;
789 if ( phasemask == 0 )
791 SendSysMessage(LANG_BAD_VALUE);
792 SetSentErrorMessage(true);
793 return false;
796 obj->SetPhaseMask(phasemask,true);
797 obj->SaveToDB();
798 return true;
801 bool ChatHandler::HandleGameObjectNearCommand(const char* args)
803 float distance = (!*args) ? 10 : atol(args);
804 uint32 count = 0;
806 Player* pl = m_session->GetPlayer();
807 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
808 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
809 "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
810 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
811 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
813 if (result)
817 Field *fields = result->Fetch();
818 uint32 guid = fields[0].GetUInt32();
819 uint32 entry = fields[1].GetUInt32();
820 float x = fields[2].GetFloat();
821 float y = fields[3].GetFloat();
822 float z = fields[4].GetFloat();
823 int mapid = fields[5].GetUInt16();
825 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
827 if(!gInfo)
828 continue;
830 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
832 ++count;
833 } while (result->NextRow());
835 delete result;
838 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
839 return true;
842 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
844 uint64 guid = m_session->GetPlayer()->GetSelection();
846 if (guid == 0)
848 SendSysMessage(LANG_NO_SELECTION);
849 SetSentErrorMessage(true);
850 return false;
853 PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
854 return true;
857 bool ChatHandler::HandleLookupFactionCommand(const char* args)
859 if (!*args)
860 return false;
862 // Can be NULL at console call
863 Player *target = getSelectedPlayer ();
865 std::string namepart = args;
866 std::wstring wnamepart;
868 if (!Utf8toWStr (namepart,wnamepart))
869 return false;
871 // converting string that we try to find to lower case
872 wstrToLower (wnamepart);
874 uint32 counter = 0; // Counter for figure out that we found smth.
876 for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
878 FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
879 if (factionEntry)
881 FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
883 int loc = GetSessionDbcLocale();
884 std::string name = factionEntry->name[loc];
885 if(name.empty())
886 continue;
888 if (!Utf8FitTo(name, wnamepart))
890 loc = 0;
891 for(; loc < MAX_LOCALE; ++loc)
893 if(loc==GetSessionDbcLocale())
894 continue;
896 name = factionEntry->name[loc];
897 if(name.empty())
898 continue;
900 if (Utf8FitTo(name, wnamepart))
901 break;
905 if(loc < MAX_LOCALE)
907 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
908 // or "id - [faction] [no reputation]" format
909 std::ostringstream ss;
910 if (m_session)
911 ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
912 else
913 ss << id << " - " << name << " " << localeNames[loc];
915 if (repState) // and then target!=NULL also
917 ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
918 std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
920 ss << " " << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ")";
922 if(repState->Flags & FACTION_FLAG_VISIBLE)
923 ss << GetMangosString(LANG_FACTION_VISIBLE);
924 if(repState->Flags & FACTION_FLAG_AT_WAR)
925 ss << GetMangosString(LANG_FACTION_ATWAR);
926 if(repState->Flags & FACTION_FLAG_PEACE_FORCED)
927 ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
928 if(repState->Flags & FACTION_FLAG_HIDDEN)
929 ss << GetMangosString(LANG_FACTION_HIDDEN);
930 if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
931 ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
932 if(repState->Flags & FACTION_FLAG_INACTIVE)
933 ss << GetMangosString(LANG_FACTION_INACTIVE);
935 else
936 ss << GetMangosString(LANG_FACTION_NOREPUTATION);
938 SendSysMessage(ss.str().c_str());
939 counter++;
944 if (counter == 0) // if counter == 0 then we found nth
945 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
946 return true;
949 bool ChatHandler::HandleModifyRepCommand(const char * args)
951 if (!*args) return false;
953 Player* target = NULL;
954 target = getSelectedPlayer();
956 if(!target)
958 SendSysMessage(LANG_PLAYER_NOT_FOUND);
959 SetSentErrorMessage(true);
960 return false;
963 // check online security
964 if (HasLowerSecurity(target, 0))
965 return false;
967 char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
968 if(!factionTxt)
969 return false;
971 uint32 factionId = atoi(factionTxt);
973 int32 amount = 0;
974 char *rankTxt = strtok(NULL, " ");
975 if (!factionTxt || !rankTxt)
976 return false;
978 amount = atoi(rankTxt);
979 if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
981 std::string rankStr = rankTxt;
982 std::wstring wrankStr;
983 if(!Utf8toWStr(rankStr,wrankStr))
984 return false;
985 wstrToLower( wrankStr );
987 int r = 0;
988 amount = -42000;
989 for (; r < MAX_REPUTATION_RANK; ++r)
991 std::string rank = GetMangosString(ReputationRankStrIndex[r]);
992 if(rank.empty())
993 continue;
995 std::wstring wrank;
996 if(!Utf8toWStr(rank,wrank))
997 continue;
999 wstrToLower(wrank);
1001 if(wrank.substr(0,wrankStr.size())==wrankStr)
1003 char *deltaTxt = strtok(NULL, " ");
1004 if (deltaTxt)
1006 int32 delta = atoi(deltaTxt);
1007 if ((delta < 0) || (delta > ReputationMgr::PointsInRank[r] -1))
1009 PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1));
1010 SetSentErrorMessage(true);
1011 return false;
1013 amount += delta;
1015 break;
1017 amount += ReputationMgr::PointsInRank[r];
1019 if (r >= MAX_REPUTATION_RANK)
1021 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
1022 SetSentErrorMessage(true);
1023 return false;
1027 FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
1029 if (!factionEntry)
1031 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
1032 SetSentErrorMessage(true);
1033 return false;
1036 if (factionEntry->reputationListID < 0)
1038 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[GetSessionDbcLocale()], factionId);
1039 SetSentErrorMessage(true);
1040 return false;
1043 target->GetReputationMgr().SetReputation(factionEntry,amount);
1044 PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[GetSessionDbcLocale()], factionId,
1045 GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry));
1046 return true;
1049 //-----------------------Npc Commands-----------------------
1050 //add spawn of creature
1051 bool ChatHandler::HandleNpcAddCommand(const char* args)
1053 if(!*args)
1054 return false;
1055 char* charID = extractKeyFromLink((char*)args,"Hcreature_entry");
1056 if(!charID)
1057 return false;
1059 char* team = strtok(NULL, " ");
1060 int32 teamval = 0;
1061 if (team) { teamval = atoi(team); }
1062 if (teamval < 0) { teamval = 0; }
1064 uint32 id = atoi(charID);
1066 Player *chr = m_session->GetPlayer();
1067 float x = chr->GetPositionX();
1068 float y = chr->GetPositionY();
1069 float z = chr->GetPositionZ();
1070 float o = chr->GetOrientation();
1071 Map *map = chr->GetMap();
1073 Creature* pCreature = new Creature;
1074 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval))
1076 delete pCreature;
1077 return false;
1080 pCreature->Relocate(x,y,z,o);
1082 if(!pCreature->IsPositionValid())
1084 sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
1085 delete pCreature;
1086 return false;
1089 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
1091 uint32 db_guid = pCreature->GetDBTableGUIDLow();
1093 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
1094 pCreature->LoadFromDB(db_guid, map);
1096 map->Add(pCreature);
1097 objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
1098 return true;
1101 //add item in vendorlist
1102 bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args)
1104 if (!*args)
1105 return false;
1107 char* pitem = extractKeyFromLink((char*)args,"Hitem");
1108 if (!pitem)
1110 SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1111 SetSentErrorMessage(true);
1112 return false;
1115 uint32 itemId = atol(pitem);
1117 char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
1118 uint32 maxcount = 0;
1119 if (fmaxcount)
1120 maxcount = atol(fmaxcount);
1122 char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
1123 uint32 incrtime = 0;
1124 if (fincrtime)
1125 incrtime = atol(fincrtime);
1127 char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
1128 uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
1130 Creature* vendor = getSelectedCreature();
1132 uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
1134 if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
1136 SetSentErrorMessage(true);
1137 return false;
1140 objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
1142 ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1144 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
1145 return true;
1148 //del item from vendor list
1149 bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args)
1151 if (!*args)
1152 return false;
1154 Creature* vendor = getSelectedCreature();
1155 if (!vendor || !vendor->isVendor())
1157 SendSysMessage(LANG_COMMAND_VENDORSELECTION);
1158 SetSentErrorMessage(true);
1159 return false;
1162 char* pitem = extractKeyFromLink((char*)args,"Hitem");
1163 if (!pitem)
1165 SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1166 SetSentErrorMessage(true);
1167 return false;
1169 uint32 itemId = atol(pitem);
1171 if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
1173 PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
1174 SetSentErrorMessage(true);
1175 return false;
1178 ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1180 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
1181 return true;
1184 //add move for creature
1185 bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
1187 if(!*args)
1188 return false;
1190 char* guid_str = strtok((char*)args, " ");
1191 char* wait_str = strtok((char*)NULL, " ");
1193 uint32 lowguid = atoi((char*)guid_str);
1195 Creature* pCreature = NULL;
1197 /* FIXME: impossible without entry
1198 if(lowguid)
1199 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1202 // attempt check creature existence by DB data
1203 if(!pCreature)
1205 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1206 if(!data)
1208 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1209 SetSentErrorMessage(true);
1210 return false;
1213 else
1215 // obtain real GUID for DB operations
1216 lowguid = pCreature->GetDBTableGUIDLow();
1219 int wait = wait_str ? atoi(wait_str) : 0;
1221 if(wait < 0)
1222 wait = 0;
1224 Player* player = m_session->GetPlayer();
1226 WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
1228 // update movement type
1229 WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1230 if(pCreature)
1232 pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1233 pCreature->GetMotionMaster()->Initialize();
1234 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1236 pCreature->setDeathState(JUST_DIED);
1237 pCreature->Respawn();
1239 pCreature->SaveToDB();
1242 SendSysMessage(LANG_WAYPOINT_ADDED);
1244 return true;
1247 //change level of creature or pet
1248 bool ChatHandler::HandleNpcChangeLevelCommand(const char* args)
1250 if (!*args)
1251 return false;
1253 uint8 lvl = (uint8) atoi((char*)args);
1254 if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1256 SendSysMessage(LANG_BAD_VALUE);
1257 SetSentErrorMessage(true);
1258 return false;
1261 Creature* pCreature = getSelectedCreature();
1262 if(!pCreature)
1264 SendSysMessage(LANG_SELECT_CREATURE);
1265 SetSentErrorMessage(true);
1266 return false;
1269 if(pCreature->isPet())
1271 if(((Pet*)pCreature)->getPetType()==HUNTER_PET)
1273 pCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(lvl)/4);
1274 pCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
1276 ((Pet*)pCreature)->GivePetLevel(lvl);
1278 else
1280 pCreature->SetMaxHealth( 100 + 30*lvl);
1281 pCreature->SetHealth( 100 + 30*lvl);
1282 pCreature->SetLevel( lvl);
1283 pCreature->SaveToDB();
1286 return true;
1289 //set npcflag of creature
1290 bool ChatHandler::HandleNpcFlagCommand(const char* args)
1292 if (!*args)
1293 return false;
1295 uint32 npcFlags = (uint32) atoi((char*)args);
1297 Creature* pCreature = getSelectedCreature();
1299 if(!pCreature)
1301 SendSysMessage(LANG_SELECT_CREATURE);
1302 SetSentErrorMessage(true);
1303 return false;
1306 pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1308 WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
1310 SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1312 return true;
1315 bool ChatHandler::HandleNpcDeleteCommand(const char* args)
1317 Creature* unit = NULL;
1319 if(*args)
1321 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1322 char* cId = extractKeyFromLink((char*)args,"Hcreature");
1323 if(!cId)
1324 return false;
1326 uint32 lowguid = atoi(cId);
1327 if(!lowguid)
1328 return false;
1330 if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
1331 unit = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
1333 else
1334 unit = getSelectedCreature();
1336 if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())
1338 SendSysMessage(LANG_SELECT_CREATURE);
1339 SetSentErrorMessage(true);
1340 return false;
1343 // Delete the creature
1344 unit->CombatStop();
1345 unit->DeleteFromDB();
1346 unit->CleanupsBeforeDelete();
1347 unit->AddObjectToRemoveList();
1349 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
1351 return true;
1354 //move selected creature
1355 bool ChatHandler::HandleNpcMoveCommand(const char* args)
1357 uint32 lowguid = 0;
1359 Creature* pCreature = getSelectedCreature();
1361 if(!pCreature)
1363 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1364 char* cId = extractKeyFromLink((char*)args,"Hcreature");
1365 if(!cId)
1366 return false;
1368 lowguid = atoi(cId);
1370 /* FIXME: impossibel without entry
1371 if(lowguid)
1372 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1375 // Attempting creature load from DB data
1376 if(!pCreature)
1378 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1379 if(!data)
1381 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1382 SetSentErrorMessage(true);
1383 return false;
1386 uint32 map_id = data->mapid;
1388 if(m_session->GetPlayer()->GetMapId()!=map_id)
1390 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
1391 SetSentErrorMessage(true);
1392 return false;
1395 else
1397 lowguid = pCreature->GetDBTableGUIDLow();
1400 else
1402 lowguid = pCreature->GetDBTableGUIDLow();
1405 float x = m_session->GetPlayer()->GetPositionX();
1406 float y = m_session->GetPlayer()->GetPositionY();
1407 float z = m_session->GetPlayer()->GetPositionZ();
1408 float o = m_session->GetPlayer()->GetOrientation();
1410 if (pCreature)
1412 if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
1414 const_cast<CreatureData*>(data)->posX = x;
1415 const_cast<CreatureData*>(data)->posY = y;
1416 const_cast<CreatureData*>(data)->posZ = z;
1417 const_cast<CreatureData*>(data)->orientation = o;
1419 pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o);
1420 pCreature->GetMotionMaster()->Initialize();
1421 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1423 pCreature->setDeathState(JUST_DIED);
1424 pCreature->Respawn();
1428 WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
1429 PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
1430 return true;
1433 /**HandleNpcSetMoveTypeCommand
1434 * Set the movement type for an NPC.<br/>
1435 * <br/>
1436 * Valid movement types are:
1437 * <ul>
1438 * <li> stay - NPC wont move </li>
1439 * <li> random - NPC will move randomly according to the spawndist </li>
1440 * <li> way - NPC will move with given waypoints set </li>
1441 * </ul>
1442 * additional parameter: NODEL - so no waypoints are deleted, if you
1443 * change the movement type
1445 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
1447 if(!*args)
1448 return false;
1450 // 3 arguments:
1451 // GUID (optional - you can also select the creature)
1452 // stay|random|way (determines the kind of movement)
1453 // NODEL (optional - tells the system NOT to delete any waypoints)
1454 // this is very handy if you want to do waypoints, that are
1455 // later switched on/off according to special events (like escort
1456 // quests, etc)
1457 char* guid_str = strtok((char*)args, " ");
1458 char* type_str = strtok((char*)NULL, " ");
1459 char* dontdel_str = strtok((char*)NULL, " ");
1461 bool doNotDelete = false;
1463 if(!guid_str)
1464 return false;
1466 uint32 lowguid = 0;
1467 Creature* pCreature = NULL;
1469 if( dontdel_str )
1471 //sLog.outError("DEBUG: All 3 params are set");
1473 // All 3 params are set
1474 // GUID
1475 // type
1476 // doNotDEL
1477 if( stricmp( dontdel_str, "NODEL" ) == 0 )
1479 //sLog.outError("DEBUG: doNotDelete = true;");
1480 doNotDelete = true;
1483 else
1485 // Only 2 params - but maybe NODEL is set
1486 if( type_str )
1488 sLog.outError("DEBUG: Only 2 params ");
1489 if( stricmp( type_str, "NODEL" ) == 0 )
1491 //sLog.outError("DEBUG: type_str, NODEL ");
1492 doNotDelete = true;
1493 type_str = NULL;
1498 if(!type_str) // case .setmovetype $move_type (with selected creature)
1500 type_str = guid_str;
1501 pCreature = getSelectedCreature();
1502 if(!pCreature || pCreature->isPet())
1503 return false;
1504 lowguid = pCreature->GetDBTableGUIDLow();
1506 else // case .setmovetype #creature_guid $move_type (with selected creature)
1508 lowguid = atoi((char*)guid_str);
1510 /* impossible without entry
1511 if(lowguid)
1512 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1515 // attempt check creature existence by DB data
1516 if(!pCreature)
1518 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1519 if(!data)
1521 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1522 SetSentErrorMessage(true);
1523 return false;
1526 else
1528 lowguid = pCreature->GetDBTableGUIDLow();
1532 // now lowguid is low guid really existed creature
1533 // and pCreature point (maybe) to this creature or NULL
1535 MovementGeneratorType move_type;
1537 std::string type = type_str;
1539 if(type == "stay")
1540 move_type = IDLE_MOTION_TYPE;
1541 else if(type == "random")
1542 move_type = RANDOM_MOTION_TYPE;
1543 else if(type == "way")
1544 move_type = WAYPOINT_MOTION_TYPE;
1545 else
1546 return false;
1548 // update movement type
1549 if(doNotDelete == false)
1550 WaypointMgr.DeletePath(lowguid);
1552 if(pCreature)
1554 pCreature->SetDefaultMovementType(move_type);
1555 pCreature->GetMotionMaster()->Initialize();
1556 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1558 pCreature->setDeathState(JUST_DIED);
1559 pCreature->Respawn();
1561 pCreature->SaveToDB();
1563 if( doNotDelete == false )
1565 PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1567 else
1569 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1572 return true;
1575 //set model of creature
1576 bool ChatHandler::HandleNpcSetModelCommand(const char* args)
1578 if (!*args)
1579 return false;
1581 uint32 displayId = (uint32) atoi((char*)args);
1583 Creature *pCreature = getSelectedCreature();
1585 if(!pCreature || pCreature->isPet())
1587 SendSysMessage(LANG_SELECT_CREATURE);
1588 SetSentErrorMessage(true);
1589 return false;
1592 pCreature->SetDisplayId(displayId);
1593 pCreature->SetNativeDisplayId(displayId);
1595 pCreature->SaveToDB();
1597 return true;
1599 //set faction of creature
1600 bool ChatHandler::HandleNpcFactionIdCommand(const char* args)
1602 if (!*args)
1603 return false;
1605 uint32 factionId = (uint32) atoi((char*)args);
1607 if (!sFactionTemplateStore.LookupEntry(factionId))
1609 PSendSysMessage(LANG_WRONG_FACTION, factionId);
1610 SetSentErrorMessage(true);
1611 return false;
1614 Creature* pCreature = getSelectedCreature();
1616 if(!pCreature)
1618 SendSysMessage(LANG_SELECT_CREATURE);
1619 SetSentErrorMessage(true);
1620 return false;
1623 pCreature->setFaction(factionId);
1625 // faction is set in creature_template - not inside creature
1627 // update in memory
1628 if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
1630 const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
1631 const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
1634 // and DB
1635 WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
1637 return true;
1639 //set spawn dist of creature
1640 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
1642 if(!*args)
1643 return false;
1645 float option = atof((char*)args);
1646 if (option < 0.0f)
1648 SendSysMessage(LANG_BAD_VALUE);
1649 return false;
1652 MovementGeneratorType mtype = IDLE_MOTION_TYPE;
1653 if (option >0.0f)
1654 mtype = RANDOM_MOTION_TYPE;
1656 Creature *pCreature = getSelectedCreature();
1657 uint32 u_guidlow = 0;
1659 if (pCreature)
1660 u_guidlow = pCreature->GetDBTableGUIDLow();
1661 else
1662 return false;
1664 pCreature->SetRespawnRadius((float)option);
1665 pCreature->SetDefaultMovementType(mtype);
1666 pCreature->GetMotionMaster()->Initialize();
1667 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1669 pCreature->setDeathState(JUST_DIED);
1670 pCreature->Respawn();
1673 WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
1674 PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
1675 return true;
1677 //spawn time handling
1678 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
1680 if(!*args)
1681 return false;
1683 char* stime = strtok((char*)args, " ");
1685 if (!stime)
1686 return false;
1688 int i_stime = atoi((char*)stime);
1690 if (i_stime < 0)
1692 SendSysMessage(LANG_BAD_VALUE);
1693 SetSentErrorMessage(true);
1694 return false;
1697 Creature *pCreature = getSelectedCreature();
1698 uint32 u_guidlow = 0;
1700 if (pCreature)
1701 u_guidlow = pCreature->GetDBTableGUIDLow();
1702 else
1703 return false;
1705 WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
1706 pCreature->SetRespawnDelay((uint32)i_stime);
1707 PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
1709 return true;
1711 //npc follow handling
1712 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
1714 Player *player = m_session->GetPlayer();
1715 Creature *creature = getSelectedCreature();
1717 if(!creature)
1719 PSendSysMessage(LANG_SELECT_CREATURE);
1720 SetSentErrorMessage(true);
1721 return false;
1724 // Follow player - Using pet's default dist and angle
1725 creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
1727 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
1728 return true;
1730 //npc unfollow handling
1731 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
1733 Player *player = m_session->GetPlayer();
1734 Creature *creature = getSelectedCreature();
1736 if(!creature)
1738 PSendSysMessage(LANG_SELECT_CREATURE);
1739 SetSentErrorMessage(true);
1740 return false;
1743 if (creature->GetMotionMaster()->empty() ||
1744 creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
1746 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
1747 SetSentErrorMessage(true);
1748 return false;
1751 TargetedMovementGenerator<Creature> const* mgen
1752 = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
1754 if(mgen->GetTarget()!=player)
1756 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
1757 SetSentErrorMessage(true);
1758 return false;
1761 // reset movement
1762 creature->GetMotionMaster()->MovementExpired(true);
1764 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
1765 return true;
1767 //npc tame handling
1768 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
1770 Creature *creatureTarget = getSelectedCreature ();
1771 if (!creatureTarget || creatureTarget->isPet ())
1773 PSendSysMessage (LANG_SELECT_CREATURE);
1774 SetSentErrorMessage (true);
1775 return false;
1778 Player *player = m_session->GetPlayer ();
1780 if(player->GetPetGUID ())
1782 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET);
1783 SetSentErrorMessage (true);
1784 return false;
1787 CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo();
1789 if (!cInfo->isTameable ())
1791 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
1792 SetSentErrorMessage (true);
1793 return false;
1796 // Everything looks OK, create new pet
1797 Pet* pet = player->CreateTamedPetFrom (creatureTarget);
1798 if (!pet)
1800 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
1801 SetSentErrorMessage (true);
1802 return false;
1805 // place pet before player
1806 float x,y,z;
1807 player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE);
1808 pet->Relocate (x,y,z,M_PI-player->GetOrientation ());
1810 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
1811 pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
1813 // calculate proper level
1814 uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel();
1816 // prepare visual effect for levelup
1817 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
1819 // add to world
1820 pet->GetMap()->Add((Creature*)pet);
1822 // visual effect for levelup
1823 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
1825 // caster have pet now
1826 player->SetPet(pet);
1828 pet->SavePetToDB(PET_SAVE_AS_CURRENT);
1829 player->PetSpellInitialize();
1831 return true;
1833 //npc phasemask handling
1834 //change phasemask of creature or pet
1835 bool ChatHandler::HandleNpcSetPhaseCommand(const char* args)
1837 if (!*args)
1838 return false;
1840 uint32 phasemask = (uint32) atoi((char*)args);
1841 if ( phasemask == 0 )
1843 SendSysMessage(LANG_BAD_VALUE);
1844 SetSentErrorMessage(true);
1845 return false;
1848 Creature* pCreature = getSelectedCreature();
1849 if(!pCreature)
1851 SendSysMessage(LANG_SELECT_CREATURE);
1852 SetSentErrorMessage(true);
1853 return false;
1856 pCreature->SetPhaseMask(phasemask,true);
1858 if(!pCreature->isPet())
1859 pCreature->SaveToDB();
1861 return true;
1863 //npc deathstate handling
1864 bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args)
1866 if (!*args)
1867 return false;
1869 Creature* pCreature = getSelectedCreature();
1870 if(!pCreature || pCreature->isPet())
1872 SendSysMessage(LANG_SELECT_CREATURE);
1873 SetSentErrorMessage(true);
1874 return false;
1877 if (strncmp(args, "on", 3) == 0)
1878 pCreature->SetDeadByDefault(true);
1879 else if (strncmp(args, "off", 4) == 0)
1880 pCreature->SetDeadByDefault(false);
1881 else
1883 SendSysMessage(LANG_USE_BOL);
1884 SetSentErrorMessage(true);
1885 return false;
1888 pCreature->SaveToDB();
1889 pCreature->Respawn();
1891 return true;
1894 //TODO: NpcCommands that need to be fixed :
1896 bool ChatHandler::HandleNpcNameCommand(const char* /*args*/)
1898 /* Temp. disabled
1899 if(!*args)
1900 return false;
1902 if(strlen((char*)args)>75)
1904 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
1905 return true;
1908 for (uint8 i = 0; i < strlen(args); ++i)
1910 if(!isalpha(args[i]) && args[i]!=' ')
1912 SendSysMessage(LANG_CHARS_ONLY);
1913 return false;
1917 uint64 guid;
1918 guid = m_session->GetPlayer()->GetSelection();
1919 if (guid == 0)
1921 SendSysMessage(LANG_NO_SELECTION);
1922 return true;
1925 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1927 if(!pCreature)
1929 SendSysMessage(LANG_SELECT_CREATURE);
1930 return true;
1933 pCreature->SetName(args);
1934 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
1935 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1937 pCreature->SaveToDB();
1940 return true;
1943 bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
1945 /* Temp. disabled
1947 if(!*args)
1948 args = "";
1950 if(strlen((char*)args)>75)
1953 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
1954 return true;
1957 for (uint8 i = 0; i < strlen(args); i++)
1959 if(!isalpha(args[i]) && args[i]!=' ')
1961 SendSysMessage(LANG_CHARS_ONLY);
1962 return false;
1965 uint64 guid;
1966 guid = m_session->GetPlayer()->GetSelection();
1967 if (guid == 0)
1969 SendSysMessage(LANG_NO_SELECTION);
1970 return true;
1973 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1975 if(!pCreature)
1977 SendSysMessage(LANG_SELECT_CREATURE);
1978 return true;
1981 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
1982 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1984 pCreature->SaveToDB();
1986 return true;
1989 //move item to other slot
1990 bool ChatHandler::HandleItemMoveCommand(const char* args)
1992 if(!*args)
1993 return false;
1994 uint8 srcslot, dstslot;
1996 char* pParam1 = strtok((char*)args, " ");
1997 if (!pParam1)
1998 return false;
2000 char* pParam2 = strtok(NULL, " ");
2001 if (!pParam2)
2002 return false;
2004 srcslot = (uint8)atoi(pParam1);
2005 dstslot = (uint8)atoi(pParam2);
2007 if(srcslot==dstslot)
2008 return true;
2010 if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
2011 return false;
2013 if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
2014 return false;
2016 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
2017 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
2019 m_session->GetPlayer()->SwapItem( src, dst );
2021 return true;
2024 //demorph player or unit
2025 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
2027 Unit *target = getSelectedUnit();
2028 if(!target)
2029 target = m_session->GetPlayer();
2032 // check online security
2033 else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
2034 return false;
2036 target->DeMorph();
2038 return true;
2041 //morph creature or player
2042 bool ChatHandler::HandleModifyMorphCommand(const char* args)
2044 if (!*args)
2045 return false;
2047 uint16 display_id = (uint16)atoi((char*)args);
2049 Unit *target = getSelectedUnit();
2050 if(!target)
2051 target = m_session->GetPlayer();
2053 // check online security
2054 else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
2055 return false;
2057 target->SetDisplayId(display_id);
2059 return true;
2062 //kick player
2063 bool ChatHandler::HandleKickPlayerCommand(const char *args)
2065 Player* target;
2066 if(!extractPlayerTarget((char*)args,&target))
2067 return false;
2069 if (m_session && target==m_session->GetPlayer())
2071 SendSysMessage(LANG_COMMAND_KICKSELF);
2072 SetSentErrorMessage(true);
2073 return false;
2076 // check online security
2077 if (HasLowerSecurity(target, 0))
2078 return false;
2080 // send before target pointer invalidate
2081 PSendSysMessage(LANG_COMMAND_KICKMESSAGE,GetNameLink(target).c_str());
2082 target->GetSession()->KickPlayer();
2083 return true;
2086 //set temporary phase mask for player
2087 bool ChatHandler::HandleModifyPhaseCommand(const char* args)
2089 if (!*args)
2090 return false;
2092 uint32 phasemask = (uint32)atoi((char*)args);
2094 Unit *target = getSelectedUnit();
2095 if(!target)
2096 target = m_session->GetPlayer();
2098 // check online security
2099 else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
2100 return false;
2102 target->SetPhaseMask(phasemask,true);
2104 return true;
2107 //show info of player
2108 bool ChatHandler::HandlePInfoCommand(const char* args)
2110 Player* target;
2111 uint64 target_guid;
2112 std::string target_name;
2113 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
2114 return false;
2116 uint32 accId = 0;
2117 uint32 money = 0;
2118 uint32 total_player_time = 0;
2119 uint32 level = 0;
2120 uint32 latency = 0;
2122 // get additional information from Player object
2123 if(target)
2125 // check online security
2126 if (HasLowerSecurity(target, 0))
2127 return false;
2129 accId = target->GetSession()->GetAccountId();
2130 money = target->GetMoney();
2131 total_player_time = target->GetTotalPlayedTime();
2132 level = target->getLevel();
2133 latency = target->GetSession()->GetLatency();
2135 // get additional information from DB
2136 else
2138 // check offline security
2139 if (HasLowerSecurity(NULL, target_guid))
2140 return false;
2142 // 0
2143 QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid));
2144 if (!result)
2145 return false;
2147 Field *fields = result->Fetch();
2148 total_player_time = fields[0].GetUInt32();
2149 delete result;
2151 Tokens data;
2152 if (!Player::LoadValuesArrayFromDB(data,target_guid))
2153 return false;
2155 money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
2156 level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
2157 accId = objmgr.GetPlayerAccountIdByGUID(target_guid);
2160 std::string username = GetMangosString(LANG_ERROR);
2161 std::string last_ip = GetMangosString(LANG_ERROR);
2162 uint32 security = 0;
2163 std::string last_login = GetMangosString(LANG_ERROR);
2165 QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
2166 if(result)
2168 Field* fields = result->Fetch();
2169 username = fields[0].GetCppString();
2170 security = fields[1].GetUInt32();
2172 if(!m_session || m_session->GetSecurity() >= security)
2174 last_ip = fields[2].GetCppString();
2175 last_login = fields[3].GetCppString();
2177 else
2179 last_ip = "-";
2180 last_login = "-";
2183 delete result;
2186 std::string nameLink = playerLink(target_name);
2188 PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
2190 std::string timeStr = secsToTimeString(total_player_time,true,true);
2191 uint32 gold = money /GOLD;
2192 uint32 silv = (money % GOLD) / SILVER;
2193 uint32 copp = (money % GOLD) % SILVER;
2194 PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
2196 return true;
2199 //show tickets
2200 void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
2202 std::string name;
2203 if(!objmgr.GetPlayerNameByGUID(guid,name))
2204 name = GetMangosString(LANG_UNKNOWN);
2206 std::string nameLink = playerLink(name);
2208 PSendSysMessage(LANG_COMMAND_TICKETVIEW, nameLink.c_str(),time,text);
2211 //ticket commands
2212 bool ChatHandler::HandleTicketCommand(const char* args)
2214 char* px = strtok((char*)args, " ");
2216 // ticket<end>
2217 if (!px)
2219 if(!m_session)
2221 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2222 SetSentErrorMessage(true);
2223 return false;
2226 size_t count = ticketmgr.GetTicketCount();
2228 bool accept = m_session->GetPlayer()->isAcceptTickets();
2230 PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ? GetMangosString(LANG_ON) : GetMangosString(LANG_OFF));
2231 return true;
2234 // ticket on
2235 if(strncmp(px,"on",3) == 0)
2237 if(!m_session)
2239 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2240 SetSentErrorMessage(true);
2241 return false;
2244 m_session->GetPlayer()->SetAcceptTicket(true);
2245 SendSysMessage(LANG_COMMAND_TICKETON);
2246 return true;
2249 // ticket off
2250 if(strncmp(px,"off",4) == 0)
2252 if(!m_session)
2254 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2255 SetSentErrorMessage(true);
2256 return false;
2259 m_session->GetPlayer()->SetAcceptTicket(false);
2260 SendSysMessage(LANG_COMMAND_TICKETOFF);
2261 return true;
2264 // ticket #num
2265 int num = atoi(px);
2266 if(num > 0)
2268 QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
2270 if(!result)
2272 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2273 SetSentErrorMessage(true);
2274 return false;
2277 Field* fields = result->Fetch();
2279 uint32 guid = fields[0].GetUInt32();
2280 char const* text = fields[1].GetString();
2281 char const* time = fields[2].GetString();
2283 ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
2284 delete result;
2285 return true;
2288 uint64 target_guid;
2289 if(!extractPlayerTarget(px,NULL,&target_guid))
2290 return false;
2292 // ticket $char_name
2293 GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(target_guid));
2294 if(!ticket)
2295 return false;
2297 std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
2299 ShowTicket(target_guid, ticket->GetText(), time.c_str());
2301 return true;
2304 //dell all tickets
2305 bool ChatHandler::HandleDelTicketCommand(const char *args)
2307 char* px = strtok((char*)args, " ");
2308 if (!px)
2309 return false;
2311 // delticket all
2312 if(strncmp(px,"all",4) == 0)
2314 ticketmgr.DeleteAll();
2315 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
2316 return true;
2319 int num = (uint32)atoi(px);
2321 // delticket #num
2322 if(num > 0)
2324 QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
2325 if(!result)
2327 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2328 SetSentErrorMessage(true);
2329 return false;
2331 Field* fields = result->Fetch();
2332 uint32 guid = fields[0].GetUInt32();
2333 delete result;
2335 ticketmgr.Delete(guid);
2337 //notify player
2338 if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
2340 pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2341 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, GetNameLink(pl).c_str());
2343 else
2344 PSendSysMessage(LANG_COMMAND_TICKETDEL);
2346 return true;
2349 Player* target;
2350 uint64 target_guid;
2351 std::string target_name;
2352 if(!extractPlayerTarget(px,&target,&target_guid,&target_name))
2353 return false;
2355 // delticket $char_name
2356 ticketmgr.Delete(GUID_LOPART(target_guid));
2358 // notify players about ticket deleting
2359 if(target)
2360 target->GetSession()->SendGMTicketGetTicket(0x0A,0);
2362 std::string nameLink = playerLink(target_name);
2364 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());
2365 return true;
2369 * Add a waypoint to a creature.
2371 * The user can either select an npc or provide its GUID.
2373 * The user can even select a visual waypoint - then the new waypoint
2374 * is placed *after* the selected one - this makes insertion of new
2375 * waypoints possible.
2377 * eg:
2378 * .wp add 12345
2379 * -> adds a waypoint to the npc with the GUID 12345
2381 * .wp add
2382 * -> adds a waypoint to the currently selected creature
2385 * @param args if the user did not provide a GUID, it is NULL
2387 * @return true - command did succeed, false - something went wrong
2389 bool ChatHandler::HandleWpAddCommand(const char* args)
2391 sLog.outDebug("DEBUG: HandleWpAddCommand");
2393 // optional
2394 char* guid_str = NULL;
2396 if(*args)
2398 guid_str = strtok((char*)args, " ");
2401 uint32 lowguid = 0;
2402 uint32 point = 0;
2403 Creature* target = getSelectedCreature();
2404 // Did player provide a GUID?
2405 if (!guid_str)
2407 sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2409 // No GUID provided
2410 // -> Player must have selected a creature
2412 if(!target || target->isPet())
2414 SendSysMessage(LANG_SELECT_CREATURE);
2415 SetSentErrorMessage(true);
2416 return false;
2418 if (target->GetEntry() == VISUAL_WAYPOINT )
2420 sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2422 QueryResult *result =
2423 WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2424 target->GetGUIDLow() );
2425 if(!result)
2427 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
2428 // User selected a visual spawnpoint -> get the NPC
2429 // Select NPC GUID
2430 // Since we compare float values, we have to deal with
2431 // some difficulties.
2432 // Here we search for all waypoints that only differ in one from 1 thousand
2433 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2434 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2435 const char* maxDIFF = "0.01";
2436 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 )",
2437 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2438 if(!result)
2440 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
2441 SetSentErrorMessage(true);
2442 return false;
2447 Field *fields = result->Fetch();
2448 lowguid = fields[0].GetUInt32();
2449 point = fields[1].GetUInt32();
2450 }while( result->NextRow() );
2451 delete result;
2453 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2454 if(!data)
2456 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2457 SetSentErrorMessage(true);
2458 return false;
2461 target = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2462 if(!target)
2464 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2465 SetSentErrorMessage(true);
2466 return false;
2469 else
2471 lowguid = target->GetDBTableGUIDLow();
2474 else
2476 sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2478 // GUID provided
2479 // Warn if player also selected a creature
2480 // -> Creature selection is ignored <-
2481 if(target)
2483 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2485 lowguid = atoi((char*)guid_str);
2487 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2488 if(!data)
2490 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2491 SetSentErrorMessage(true);
2492 return false;
2495 target = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2496 if(!target || target->isPet())
2498 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2499 SetSentErrorMessage(true);
2500 return false;
2503 // lowguid -> GUID of the NPC
2504 // point -> number of the waypoint (if not 0)
2505 sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
2507 sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2509 Player* player = m_session->GetPlayer();
2510 WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
2512 // update movement type
2513 if(target)
2515 target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2516 target->GetMotionMaster()->Initialize();
2517 if(target->isAlive()) // dead creature will reset movement generator at respawn
2519 target->setDeathState(JUST_DIED);
2520 target->Respawn();
2522 target->SaveToDB();
2524 else
2525 WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
2527 PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
2529 return true;
2530 } // HandleWpAddCommand
2533 * .wp modify emote | spell | text | del | move | add
2535 * add -> add a WP after the selected visual waypoint
2536 * User must select a visual waypoint and then issue ".wp modify add"
2538 * emote <emoteID>
2539 * User has selected a visual waypoint before.
2540 * <emoteID> is added to this waypoint. Everytime the
2541 * NPC comes to this waypoint, the emote is called.
2543 * emote <GUID> <WPNUM> <emoteID>
2544 * User has not selected visual waypoint before.
2545 * For the waypoint <WPNUM> for the NPC with <GUID>
2546 * an emote <emoteID> is added.
2547 * Everytime the NPC comes to this waypoint, the emote is called.
2550 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2552 bool ChatHandler::HandleWpModifyCommand(const char* args)
2554 sLog.outDebug("DEBUG: HandleWpModifyCommand");
2556 if(!*args)
2557 return false;
2559 // first arg: add del text emote spell waittime move
2560 char* show_str = strtok((char*)args, " ");
2561 if (!show_str)
2563 return false;
2566 std::string show = show_str;
2567 // Check
2568 // Remember: "show" must also be the name of a column!
2569 if( (show != "emote") && (show != "spell") && (show != "textid1") && (show != "textid2")
2570 && (show != "textid3") && (show != "textid4") && (show != "textid5")
2571 && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
2572 && (show != "model1") && (show != "model2") && (show != "orientation"))
2574 return false;
2577 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2579 // Did user provide a GUID
2580 // or did the user select a creature?
2581 // -> variable lowguid is filled with the GUID of the NPC
2582 uint32 lowguid = 0;
2583 uint32 point = 0;
2584 uint32 wpGuid = 0;
2585 Creature* target = getSelectedCreature();
2587 if(target)
2589 sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2591 // Did the user select a visual spawnpoint?
2592 if (target->GetEntry() != VISUAL_WAYPOINT )
2594 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2595 SetSentErrorMessage(true);
2596 return false;
2599 wpGuid = target->GetGUIDLow();
2601 // The visual waypoint
2602 QueryResult *result =
2603 WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2604 target->GetGUIDLow() );
2605 if(!result)
2607 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
2608 SetSentErrorMessage(true);
2609 return false;
2611 sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2613 Field *fields = result->Fetch();
2614 lowguid = fields[0].GetUInt32();
2615 point = fields[1].GetUInt32();
2617 // Cleanup memory
2618 sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2619 delete result;
2621 else
2623 // User did provide <GUID> <WPNUM>
2625 char* guid_str = strtok((char*)NULL, " ");
2626 if( !guid_str )
2628 SendSysMessage(LANG_WAYPOINT_NOGUID);
2629 return false;
2631 lowguid = atoi((char*)guid_str);
2633 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2634 if(!data)
2636 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2637 SetSentErrorMessage(true);
2638 return false;
2641 PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2643 char* point_str = strtok((char*)NULL, " ");
2644 if( !point_str )
2646 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2647 return false;
2649 point = atoi((char*)point_str);
2651 PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2653 // Now we need the GUID of the visual waypoint
2654 // -> "del", "move", "add" command
2656 QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
2657 if (!result)
2659 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2660 SetSentErrorMessage(true);
2661 return false;
2664 Field *fields = result->Fetch();
2665 wpGuid = fields[0].GetUInt32();
2667 // Free memory
2668 delete result;
2671 char* arg_str = NULL;
2672 // Check for argument
2673 if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
2675 // Text is enclosed in "<>", all other arguments not
2676 if( show.find("text") != std::string::npos )
2677 arg_str = strtok((char*)NULL, "<>");
2678 else
2679 arg_str = strtok((char*)NULL, " ");
2681 if( !arg_str)
2683 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2684 return false;
2688 sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2690 // wpGuid -> GUID of the waypoint creature
2691 // lowguid -> GUID of the NPC
2692 // point -> waypoint number
2694 // Special functions:
2695 // add - move - del -> no args commands
2696 // Add a waypoint after the selected visual
2697 if(show == "add" && target)
2699 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2701 // Get the creature for which we read the waypoint
2702 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2703 if(!data)
2705 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2706 SetSentErrorMessage(true);
2707 return false;
2710 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2712 if( !npcCreature )
2714 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2715 SetSentErrorMessage(true);
2716 return false;
2719 sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2721 // What to do:
2722 // Add the visual spawnpoint (DB only)
2723 // Adjust the waypoints
2724 // Respawn the owner of the waypoints
2725 sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
2727 Player* chr = m_session->GetPlayer();
2728 Map *map = chr->GetMap();
2730 if(npcCreature)
2732 npcCreature->GetMotionMaster()->Initialize();
2733 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2735 npcCreature->setDeathState(JUST_DIED);
2736 npcCreature->Respawn();
2740 // create the waypoint creature
2741 wpGuid = 0;
2742 Creature* wpCreature = new Creature;
2743 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT,0))
2745 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2746 delete wpCreature;
2748 else
2750 wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2752 if(!wpCreature->IsPositionValid())
2754 sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
2755 delete wpCreature;
2757 else
2759 wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
2760 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2761 wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
2762 map->Add(wpCreature);
2763 wpGuid = wpCreature->GetGUIDLow();
2767 WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
2769 if(!wpGuid)
2770 return false;
2772 PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2773 return true;
2774 } // add
2776 if(show == "del" && target)
2778 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2780 // Get the creature for which we read the waypoint
2781 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2782 if(!data)
2784 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2785 SetSentErrorMessage(true);
2786 return false;
2789 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2791 // wpCreature
2792 Creature* wpCreature = NULL;
2793 if( wpGuid != 0 )
2795 wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2796 wpCreature->DeleteFromDB();
2797 wpCreature->CleanupsBeforeDelete();
2798 wpCreature->AddObjectToRemoveList();
2801 // What to do:
2802 // Remove the visual spawnpoint
2803 // Adjust the waypoints
2804 // Respawn the owner of the waypoints
2806 WaypointMgr.DeleteNode(lowguid, point);
2808 if(npcCreature)
2810 // Any waypoints left?
2811 QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
2812 if(!result2)
2814 npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2816 else
2818 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2819 delete result2;
2821 npcCreature->GetMotionMaster()->Initialize();
2822 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2824 npcCreature->setDeathState(JUST_DIED);
2825 npcCreature->Respawn();
2827 npcCreature->SaveToDB();
2830 PSendSysMessage(LANG_WAYPOINT_REMOVED);
2831 return true;
2832 } // del
2834 if(show == "move" && target)
2836 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2838 Player *chr = m_session->GetPlayer();
2839 Map *map = chr->GetMap();
2841 // Get the creature for which we read the waypoint
2842 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2843 if(!data)
2845 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2846 SetSentErrorMessage(true);
2847 return false;
2850 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2852 // wpCreature
2853 Creature* wpCreature = NULL;
2854 // What to do:
2855 // Move the visual spawnpoint
2856 // Respawn the owner of the waypoints
2857 if( wpGuid != 0 )
2859 wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2860 wpCreature->DeleteFromDB();
2861 wpCreature->CleanupsBeforeDelete();
2862 wpCreature->AddObjectToRemoveList();
2863 // re-create
2864 Creature* wpCreature2 = new Creature;
2865 if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))
2867 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2868 delete wpCreature2;
2869 return false;
2872 wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2874 if(!wpCreature2->IsPositionValid())
2876 sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());
2877 delete wpCreature2;
2878 return false;
2881 wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
2882 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2883 wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
2884 map->Add(wpCreature2);
2885 //npcCreature->GetMap()->Add(wpCreature2);
2888 WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
2890 if(npcCreature)
2892 npcCreature->GetMotionMaster()->Initialize();
2893 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2895 npcCreature->setDeathState(JUST_DIED);
2896 npcCreature->Respawn();
2899 PSendSysMessage(LANG_WAYPOINT_CHANGED);
2901 return true;
2902 } // move
2904 // Create creature - npc that has the waypoint
2905 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2906 if(!data)
2908 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2909 SetSentErrorMessage(true);
2910 return false;
2913 // set in game textids not supported
2914 if( show == "textid1" || show == "textid2" || show == "textid3" ||
2915 show == "textid4" || show == "textid5" )
2917 return false;
2920 WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
2922 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2923 if(npcCreature)
2925 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2926 npcCreature->GetMotionMaster()->Initialize();
2927 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2929 npcCreature->setDeathState(JUST_DIED);
2930 npcCreature->Respawn();
2933 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2935 return true;
2939 * .wp show info | on | off
2941 * info -> User has selected a visual waypoint before
2943 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2944 * provided the GUID of the NPC and the number of
2945 * the waypoint.
2947 * on -> User has selected an NPC; all visual waypoints for this
2948 * NPC are added to the world
2950 * on <GUID> -> User did not select an NPC - instead the GUID of the
2951 * NPC is provided. All visual waypoints for this NPC
2952 * are added from the world.
2954 * off -> User has selected an NPC; all visual waypoints for this
2955 * NPC are removed from the world.
2957 * on <GUID> -> User did not select an NPC - instead the GUID of the
2958 * NPC is provided. All visual waypoints for this NPC
2959 * are removed from the world.
2963 bool ChatHandler::HandleWpShowCommand(const char* args)
2965 sLog.outDebug("DEBUG: HandleWpShowCommand");
2967 if(!*args)
2968 return false;
2970 // first arg: on, off, first, last
2971 char* show_str = strtok((char*)args, " ");
2972 if (!show_str)
2974 return false;
2976 // second arg: GUID (optional, if a creature is selected)
2977 char* guid_str = strtok((char*)NULL, " ");
2978 sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2979 //if (!guid_str) {
2980 // return false;
2983 // Did user provide a GUID
2984 // or did the user select a creature?
2985 // -> variable lowguid is filled with the GUID
2986 Creature* target = getSelectedCreature();
2987 // Did player provide a GUID?
2988 if (!guid_str)
2990 sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2991 // No GUID provided
2992 // -> Player must have selected a creature
2994 if(!target)
2996 SendSysMessage(LANG_SELECT_CREATURE);
2997 SetSentErrorMessage(true);
2998 return false;
3001 else
3003 sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
3004 // GUID provided
3005 // Warn if player also selected a creature
3006 // -> Creature selection is ignored <-
3007 if(target)
3009 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
3012 uint32 lowguid = atoi((char*)guid_str);
3014 CreatureData const* data = objmgr.GetCreatureData(lowguid);
3015 if(!data)
3017 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
3018 SetSentErrorMessage(true);
3019 return false;
3022 target = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
3024 if(!target)
3026 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
3027 SetSentErrorMessage(true);
3028 return false;
3032 uint32 lowguid = target->GetDBTableGUIDLow();
3034 std::string show = show_str;
3035 uint32 Maxpoint;
3037 sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid, show_str);
3039 // Show info for the selected waypoint
3040 if(show == "info")
3042 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
3044 // Check if the user did specify a visual waypoint
3045 if( target->GetEntry() != VISUAL_WAYPOINT )
3047 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
3048 SetSentErrorMessage(true);
3049 return false;
3052 //PSendSysMessage("wp on, GUID: %u", lowguid);
3054 //pCreature->GetPositionX();
3056 QueryResult *result =
3057 WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
3058 target->GetGUIDLow() );
3059 if(!result)
3061 // Since we compare float values, we have to deal with
3062 // some difficulties.
3063 // Here we search for all waypoints that only differ in one from 1 thousand
3064 // (0.001) - There is no other way to compare C++ floats with mySQL floats
3065 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
3066 const char* maxDIFF = "0.01";
3067 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
3069 result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
3070 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
3071 if(!result)
3073 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
3074 SetSentErrorMessage(true);
3075 return false;
3080 Field *fields = result->Fetch();
3081 uint32 creGUID = fields[0].GetUInt32();
3082 uint32 point = fields[1].GetUInt32();
3083 int waittime = fields[2].GetUInt32();
3084 uint32 emote = fields[3].GetUInt32();
3085 uint32 spell = fields[4].GetUInt32();
3086 uint32 textid[MAX_WAYPOINT_TEXT];
3087 for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
3088 textid[i] = fields[5+i].GetUInt32();
3089 uint32 model1 = fields[10].GetUInt32();
3090 uint32 model2 = fields[11].GetUInt32();
3092 // Get the creature for which we read the waypoint
3093 Creature* wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3095 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
3096 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
3097 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
3098 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
3099 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
3100 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
3101 for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
3102 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, i+1, textid[i], (textid[i] ? GetMangosString(textid[i]) : ""));
3104 }while( result->NextRow() );
3105 // Cleanup memory
3106 delete result;
3107 return true;
3110 if(show == "on")
3112 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
3114 QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
3115 if(!result)
3117 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3118 SetSentErrorMessage(true);
3119 return false;
3121 // Delete all visuals for this NPC
3122 QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
3123 if(result2)
3125 bool hasError = false;
3128 Field *fields = result2->Fetch();
3129 uint32 wpguid = fields[0].GetUInt32();
3130 Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3132 if(!pCreature)
3134 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
3135 hasError = true;
3136 WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
3138 else
3140 pCreature->DeleteFromDB();
3141 pCreature->CleanupsBeforeDelete();
3142 pCreature->AddObjectToRemoveList();
3145 }while( result2->NextRow() );
3146 delete result2;
3147 if( hasError )
3149 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3150 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3151 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3157 Field *fields = result->Fetch();
3158 uint32 point = fields[0].GetUInt32();
3159 float x = fields[1].GetFloat();
3160 float y = fields[2].GetFloat();
3161 float z = fields[3].GetFloat();
3163 uint32 id = VISUAL_WAYPOINT;
3165 Player *chr = m_session->GetPlayer();
3166 Map *map = chr->GetMap();
3167 float o = chr->GetOrientation();
3169 Creature* wpCreature = new Creature;
3170 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
3172 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3173 delete wpCreature;
3174 delete result;
3175 return false;
3178 wpCreature->Relocate(x, y, z, o);
3180 if(!wpCreature->IsPositionValid())
3182 sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
3183 delete wpCreature;
3184 delete result;
3185 return false;
3188 wpCreature->SetVisibility(VISIBILITY_OFF);
3189 sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3190 // set "wpguid" column to the visual waypoint
3191 WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
3193 wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3194 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3195 wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
3196 map->Add(wpCreature);
3197 //wpCreature->GetMap()->Add(wpCreature);
3198 }while( result->NextRow() );
3200 // Cleanup memory
3201 delete result;
3202 return true;
3205 if(show == "first")
3207 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3209 QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3210 if(!result)
3212 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3213 SetSentErrorMessage(true);
3214 return false;
3217 Field *fields = result->Fetch();
3218 float x = fields[0].GetFloat();
3219 float y = fields[1].GetFloat();
3220 float z = fields[2].GetFloat();
3221 uint32 id = VISUAL_WAYPOINT;
3223 Player *chr = m_session->GetPlayer();
3224 float o = chr->GetOrientation();
3225 Map *map = chr->GetMap();
3227 Creature* pCreature = new Creature;
3228 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))
3230 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3231 delete pCreature;
3232 delete result;
3233 return false;
3236 pCreature->Relocate(x, y, z, o);
3238 if(!pCreature->IsPositionValid())
3240 sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3241 delete pCreature;
3242 delete result;
3243 return false;
3246 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3247 pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3248 map->Add(pCreature);
3249 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3251 // Cleanup memory
3252 delete result;
3253 return true;
3256 if(show == "last")
3258 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3260 QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3261 if( result )
3263 Maxpoint = (*result)[0].GetUInt32();
3265 delete result;
3267 else
3268 Maxpoint = 0;
3270 result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3271 if(!result)
3273 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3274 SetSentErrorMessage(true);
3275 return false;
3277 Field *fields = result->Fetch();
3278 float x = fields[0].GetFloat();
3279 float y = fields[1].GetFloat();
3280 float z = fields[2].GetFloat();
3281 uint32 id = VISUAL_WAYPOINT;
3283 Player *chr = m_session->GetPlayer();
3284 float o = chr->GetOrientation();
3285 Map *map = chr->GetMap();
3287 Creature* pCreature = new Creature;
3288 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
3290 PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3291 delete pCreature;
3292 delete result;
3293 return false;
3296 pCreature->Relocate(x, y, z, o);
3298 if(!pCreature->IsPositionValid())
3300 sLog.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3301 delete pCreature;
3302 delete result;
3303 return false;
3306 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3307 pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3308 map->Add(pCreature);
3309 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3310 // Cleanup memory
3311 delete result;
3312 return true;
3315 if(show == "off")
3317 QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3318 if(!result)
3320 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3321 SetSentErrorMessage(true);
3322 return false;
3324 bool hasError = false;
3327 Field *fields = result->Fetch();
3328 uint32 guid = fields[0].GetUInt32();
3329 Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3330 if(!pCreature)
3332 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3333 hasError = true;
3334 WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3336 else
3338 pCreature->DeleteFromDB();
3339 pCreature->CleanupsBeforeDelete();
3340 pCreature->AddObjectToRemoveList();
3342 }while(result->NextRow());
3343 // set "wpguid" column to "empty" - no visual waypoint spawned
3344 WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3346 if( hasError )
3348 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3349 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3350 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3353 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3354 // Cleanup memory
3355 delete result;
3357 return true;
3360 PSendSysMessage("DEBUG: wpshow - no valid command found");
3362 return true;
3363 } // HandleWpShowCommand
3365 bool ChatHandler::HandleWpExportCommand(const char *args)
3367 if(!*args)
3368 return false;
3370 // Next arg is: <GUID> <ARGUMENT>
3372 // Did user provide a GUID
3373 // or did the user select a creature?
3374 // -> variable lowguid is filled with the GUID of the NPC
3375 uint32 lowguid = 0;
3376 Creature* target = getSelectedCreature();
3377 char* arg_str = NULL;
3378 if (target)
3380 if (target->GetEntry() != VISUAL_WAYPOINT)
3381 lowguid = target->GetGUIDLow();
3382 else
3384 QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3385 if (!result)
3387 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3388 return true;
3390 Field *fields = result->Fetch();
3391 lowguid = fields[0].GetUInt32();;
3392 delete result;
3395 arg_str = strtok((char*)args, " ");
3397 else
3399 // user provided <GUID>
3400 char* guid_str = strtok((char*)args, " ");
3401 if( !guid_str )
3403 SendSysMessage(LANG_WAYPOINT_NOGUID);
3404 return false;
3406 lowguid = atoi((char*)guid_str);
3408 arg_str = strtok((char*)NULL, " ");
3411 if( !arg_str)
3413 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3414 return false;
3417 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3419 QueryResult *result = WorldDatabase.PQuery(
3420 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3421 "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
3423 if (!result)
3425 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3426 SetSentErrorMessage(true);
3427 return false;
3430 std::ofstream outfile;
3431 outfile.open (arg_str);
3435 Field *fields = result->Fetch();
3437 outfile << "INSERT INTO creature_movement ";
3438 outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3440 outfile << "( ";
3441 outfile << fields[15].GetUInt32(); // id
3442 outfile << ", ";
3443 outfile << fields[0].GetUInt32(); // point
3444 outfile << ", ";
3445 outfile << fields[1].GetFloat(); // position_x
3446 outfile << ", ";
3447 outfile << fields[2].GetFloat(); // position_y
3448 outfile << ", ";
3449 outfile << fields[3].GetUInt32(); // position_z
3450 outfile << ", ";
3451 outfile << fields[4].GetUInt32(); // orientation
3452 outfile << ", ";
3453 outfile << fields[5].GetUInt32(); // model1
3454 outfile << ", ";
3455 outfile << fields[6].GetUInt32(); // model2
3456 outfile << ", ";
3457 outfile << fields[7].GetUInt16(); // waittime
3458 outfile << ", ";
3459 outfile << fields[8].GetUInt32(); // emote
3460 outfile << ", ";
3461 outfile << fields[9].GetUInt32(); // spell
3462 outfile << ", ";
3463 outfile << fields[10].GetUInt32(); // textid1
3464 outfile << ", ";
3465 outfile << fields[11].GetUInt32(); // textid2
3466 outfile << ", ";
3467 outfile << fields[12].GetUInt32(); // textid3
3468 outfile << ", ";
3469 outfile << fields[13].GetUInt32(); // textid4
3470 outfile << ", ";
3471 outfile << fields[14].GetUInt32(); // textid5
3472 outfile << ");\n ";
3474 } while( result->NextRow() );
3475 delete result;
3477 PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3478 outfile.close();
3480 return true;
3483 bool ChatHandler::HandleWpImportCommand(const char *args)
3485 if(!*args)
3486 return false;
3488 char* arg_str = strtok((char*)args, " ");
3489 if (!arg_str)
3490 return false;
3492 std::string line;
3493 std::ifstream infile (arg_str);
3494 if (infile.is_open())
3496 while (! infile.eof() )
3498 getline (infile,line);
3499 //cout << line << endl;
3500 QueryResult *result = WorldDatabase.Query(line.c_str());
3501 delete result;
3503 infile.close();
3505 PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3507 return true;
3510 //rename characters
3511 bool ChatHandler::HandleCharacterRenameCommand(const char* args)
3513 Player* target;
3514 uint64 target_guid;
3515 std::string target_name;
3516 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
3517 return false;
3519 if(target)
3521 // check online security
3522 if (HasLowerSecurity(target, 0))
3523 return false;
3525 PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());
3526 target->SetAtLoginFlag(AT_LOGIN_RENAME);
3527 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3529 else
3531 // check offline security
3532 if (HasLowerSecurity(NULL, target_guid))
3533 return false;
3535 std::string oldNameLink = playerLink(target_name);
3537 PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
3538 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid));
3541 return true;
3544 // customize characters
3545 bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
3547 Player* target;
3548 uint64 target_guid;
3549 std::string target_name;
3550 if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
3551 return false;
3553 if(target)
3555 PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
3556 target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
3557 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
3559 else
3561 std::string oldNameLink = playerLink(target_name);
3563 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
3564 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid));
3567 return true;
3570 bool ChatHandler::HandleCharacterReputationCommand(const char* args)
3572 Player* target;
3573 if(!extractPlayerTarget((char*)args,&target))
3574 return false;
3576 LocaleConstant loc = GetSessionDbcLocale();
3578 FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
3579 for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
3581 FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
3582 char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#";
3583 ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
3584 std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
3585 std::ostringstream ss;
3586 if (m_session)
3587 ss << itr->second.ID << " - |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << " " << localeNames[loc] << "]|h|r";
3588 else
3589 ss << itr->second.ID << " - " << factionName << " " << localeNames[loc];
3591 ss << " " << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ")";
3593 if(itr->second.Flags & FACTION_FLAG_VISIBLE)
3594 ss << GetMangosString(LANG_FACTION_VISIBLE);
3595 if(itr->second.Flags & FACTION_FLAG_AT_WAR)
3596 ss << GetMangosString(LANG_FACTION_ATWAR);
3597 if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
3598 ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
3599 if(itr->second.Flags & FACTION_FLAG_HIDDEN)
3600 ss << GetMangosString(LANG_FACTION_HIDDEN);
3601 if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
3602 ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
3603 if(itr->second.Flags & FACTION_FLAG_INACTIVE)
3604 ss << GetMangosString(LANG_FACTION_INACTIVE);
3606 SendSysMessage(ss.str().c_str());
3608 return true;
3611 //change standstate
3612 bool ChatHandler::HandleModifyStandStateCommand(const char* args)
3614 if (!*args)
3615 return false;
3617 uint32 anim_id = atoi((char*)args);
3618 m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3620 return true;
3623 bool ChatHandler::HandleHonorAddCommand(const char* args)
3625 if (!*args)
3626 return false;
3628 Player *target = getSelectedPlayer();
3629 if(!target)
3631 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3632 SetSentErrorMessage(true);
3633 return false;
3636 // check online security
3637 if (HasLowerSecurity(target, 0))
3638 return false;
3640 uint32 amount = (uint32)atoi(args);
3641 target->RewardHonor(NULL, 1, amount);
3642 return true;
3645 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3647 Unit *target = getSelectedUnit();
3648 if(!target)
3650 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3651 SetSentErrorMessage(true);
3652 return false;
3655 // check online security
3656 if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
3657 return false;
3659 m_session->GetPlayer()->RewardHonor(target, 1);
3660 return true;
3663 bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
3665 Player *target = getSelectedPlayer();
3666 if(!target)
3668 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3669 SetSentErrorMessage(true);
3670 return false;
3673 // check online security
3674 if (HasLowerSecurity(target, 0))
3675 return false;
3677 target->UpdateHonorFields();
3678 return true;
3681 bool ChatHandler::HandleLookupEventCommand(const char* args)
3683 if(!*args)
3684 return false;
3686 std::string namepart = args;
3687 std::wstring wnamepart;
3689 // converting string that we try to find to lower case
3690 if(!Utf8toWStr(namepart,wnamepart))
3691 return false;
3693 wstrToLower(wnamepart);
3695 uint32 counter = 0;
3697 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3698 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3700 for(uint32 id = 0; id < events.size(); ++id )
3702 GameEventData const& eventData = events[id];
3704 std::string descr = eventData.description;
3705 if(descr.empty())
3706 continue;
3708 if (Utf8FitTo(descr, wnamepart))
3710 char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : "";
3712 if(m_session)
3713 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
3714 else
3715 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
3717 ++counter;
3721 if (counter==0)
3722 SendSysMessage(LANG_NOEVENTFOUND);
3724 return true;
3727 bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
3729 uint32 counter = 0;
3731 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3732 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3734 char const* active = GetMangosString(LANG_ACTIVE);
3736 for(GameEventMgr::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3738 uint32 event_id = *itr;
3739 GameEventData const& eventData = events[event_id];
3741 if(m_session)
3742 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
3743 else
3744 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
3746 ++counter;
3749 if (counter==0)
3750 SendSysMessage(LANG_NOEVENTFOUND);
3752 return true;
3755 bool ChatHandler::HandleEventInfoCommand(const char* args)
3757 if(!*args)
3758 return false;
3760 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3761 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3762 if(!cId)
3763 return false;
3765 uint32 event_id = atoi(cId);
3767 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3769 if(event_id >=events.size())
3771 SendSysMessage(LANG_EVENT_NOT_EXIST);
3772 SetSentErrorMessage(true);
3773 return false;
3776 GameEventData const& eventData = events[event_id];
3777 if(!eventData.isValid())
3779 SendSysMessage(LANG_EVENT_NOT_EXIST);
3780 SetSentErrorMessage(true);
3781 return false;
3784 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3785 bool active = activeEvents.find(event_id) != activeEvents.end();
3786 char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : "";
3788 std::string startTimeStr = TimeToTimestampStr(eventData.start);
3789 std::string endTimeStr = TimeToTimestampStr(eventData.end);
3791 uint32 delay = gameeventmgr.NextCheck(event_id);
3792 time_t nextTime = time(NULL)+delay;
3793 std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3795 std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3796 std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3798 PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3799 startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3800 nextStr.c_str());
3801 return true;
3804 bool ChatHandler::HandleEventStartCommand(const char* args)
3806 if(!*args)
3807 return false;
3809 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3810 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3811 if(!cId)
3812 return false;
3814 int32 event_id = atoi(cId);
3816 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3818 if(event_id < 1 || event_id >=events.size())
3820 SendSysMessage(LANG_EVENT_NOT_EXIST);
3821 SetSentErrorMessage(true);
3822 return false;
3825 GameEventData const& eventData = events[event_id];
3826 if(!eventData.isValid())
3828 SendSysMessage(LANG_EVENT_NOT_EXIST);
3829 SetSentErrorMessage(true);
3830 return false;
3833 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3834 if(activeEvents.find(event_id) != activeEvents.end())
3836 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
3837 SetSentErrorMessage(true);
3838 return false;
3841 gameeventmgr.StartEvent(event_id,true);
3842 return true;
3845 bool ChatHandler::HandleEventStopCommand(const char* args)
3847 if(!*args)
3848 return false;
3850 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3851 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3852 if(!cId)
3853 return false;
3855 int32 event_id = atoi(cId);
3857 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3859 if(event_id < 1 || event_id >=events.size())
3861 SendSysMessage(LANG_EVENT_NOT_EXIST);
3862 SetSentErrorMessage(true);
3863 return false;
3866 GameEventData const& eventData = events[event_id];
3867 if(!eventData.isValid())
3869 SendSysMessage(LANG_EVENT_NOT_EXIST);
3870 SetSentErrorMessage(true);
3871 return false;
3874 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3876 if(activeEvents.find(event_id) == activeEvents.end())
3878 PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
3879 SetSentErrorMessage(true);
3880 return false;
3883 gameeventmgr.StopEvent(event_id,true);
3884 return true;
3887 bool ChatHandler::HandleCombatStopCommand(const char* args)
3889 Player* target;
3890 if(!extractPlayerTarget((char*)args,&target))
3891 return false;
3893 // check online security
3894 if (HasLowerSecurity(target, 0))
3895 return false;
3897 target->CombatStop();
3898 target->getHostilRefManager().deleteReferences();
3899 return true;
3902 void ChatHandler::HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id)
3904 uint32 classmask = player->getClassMask();
3906 for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3908 SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3909 if (!skillLine)
3910 continue;
3912 // wrong skill
3913 if( skillLine->skillId != skill_id)
3914 continue;
3916 // not high rank
3917 if(skillLine->forward_spellid )
3918 continue;
3920 // skip racial skills
3921 if (skillLine->racemask != 0)
3922 continue;
3924 // skip wrong class skills
3925 if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3926 continue;
3928 SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3929 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false))
3930 continue;
3932 player->learnSpell(skillLine->spellId,false);
3936 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3938 uint32 classmask = m_session->GetPlayer()->getClassMask();
3940 for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3942 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3943 if( !skillInfo )
3944 continue;
3946 if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) &&
3947 skillInfo->canLink) // only prof. with recipes have
3949 HandleLearnSkillRecipesHelper(m_session->GetPlayer(),skillInfo->id);
3953 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
3954 return true;
3957 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
3959 // Learns all recipes of specified profession and sets skill to max
3960 // Example: .learn all_recipes enchanting
3962 Player* target = getSelectedPlayer();
3963 if( !target )
3965 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3966 return false;
3969 if(!*args)
3970 return false;
3972 std::wstring wnamepart;
3974 if(!Utf8toWStr(args,wnamepart))
3975 return false;
3977 // converting string that we try to find to lower case
3978 wstrToLower( wnamepart );
3980 uint32 classmask = m_session->GetPlayer()->getClassMask();
3982 std::string name;
3984 SkillLineEntry const *targetSkillInfo = NULL;
3985 for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i)
3987 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3988 if (!skillInfo)
3989 continue;
3991 if ((skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
3992 skillInfo->categoryId != SKILL_CATEGORY_SECONDARY) ||
3993 !skillInfo->canLink) // only prof with recipes have set
3994 continue;
3996 int loc = GetSessionDbcLocale();
3997 name = skillInfo->name[loc];
3998 if(name.empty())
3999 continue;
4001 if (!Utf8FitTo(name, wnamepart))
4003 loc = 0;
4004 for(; loc < MAX_LOCALE; ++loc)
4006 if(loc==GetSessionDbcLocale())
4007 continue;
4009 name = skillInfo->name[loc];
4010 if(name.empty())
4011 continue;
4013 if (Utf8FitTo(name, wnamepart))
4014 break;
4018 if(loc < MAX_LOCALE)
4020 targetSkillInfo = skillInfo;
4021 break;
4025 if(!targetSkillInfo)
4026 return false;
4028 HandleLearnSkillRecipesHelper(target,targetSkillInfo->id);
4030 uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->id);
4031 target->SetSkill(targetSkillInfo->id, maxLevel, maxLevel);
4032 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
4033 return true;
4036 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
4039 if (!*args)
4040 return false;
4042 std::string ip = strtok ((char*)args, " ");
4043 char* limit_str = strtok (NULL, " ");
4044 int32 limit = limit_str ? atoi (limit_str) : -1;
4046 loginDatabase.escape_string (ip);
4048 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
4050 return LookupPlayerSearchCommand (result,limit);
4053 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
4055 if (!*args)
4056 return false;
4058 std::string account = strtok ((char*)args, " ");
4059 char* limit_str = strtok (NULL, " ");
4060 int32 limit = limit_str ? atoi (limit_str) : -1;
4062 if (!AccountMgr::normilizeString (account))
4063 return false;
4065 loginDatabase.escape_string (account);
4067 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
4069 return LookupPlayerSearchCommand (result,limit);
4072 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
4075 if (!*args)
4076 return false;
4078 std::string email = strtok ((char*)args, " ");
4079 char* limit_str = strtok (NULL, " ");
4080 int32 limit = limit_str ? atoi (limit_str) : -1;
4082 loginDatabase.escape_string (email);
4084 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
4086 return LookupPlayerSearchCommand (result,limit);
4089 bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
4091 if(!result)
4093 PSendSysMessage(LANG_NO_PLAYERS_FOUND);
4094 SetSentErrorMessage(true);
4095 return false;
4098 int i =0;
4101 Field* fields = result->Fetch();
4102 uint32 acc_id = fields[0].GetUInt32();
4103 std::string acc_name = fields[1].GetCppString();
4105 QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
4106 if(chars)
4108 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
4110 uint64 guid = 0;
4111 std::string name;
4115 Field* charfields = chars->Fetch();
4116 guid = charfields[0].GetUInt64();
4117 name = charfields[1].GetCppString();
4119 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
4120 ++i;
4122 } while( chars->NextRow() && ( limit == -1 || i < limit ) );
4124 delete chars;
4126 } while(result->NextRow());
4128 delete result;
4130 if(i==0) // empty accounts only
4132 PSendSysMessage(LANG_NO_PLAYERS_FOUND);
4133 SetSentErrorMessage(true);
4134 return false;
4137 return true;
4140 /// Triggering corpses expire check in world
4141 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4143 CorpsesErase();
4144 return true;
4147 bool ChatHandler::HandleRepairitemsCommand(const char* args)
4149 Player* target;
4150 if(!extractPlayerTarget((char*)args,&target))
4151 return false;
4153 // check online security
4154 if (HasLowerSecurity(target, 0))
4155 return false;
4157 // Repair items
4158 target->DurabilityRepairAll(false, 0, false);
4160 PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());
4161 if(needReportToTarget(target))
4162 ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());
4163 return true;
4166 bool ChatHandler::HandleWaterwalkCommand(const char* args)
4168 if(!*args)
4169 return false;
4171 Player *player = getSelectedPlayer();
4173 if(!player)
4175 PSendSysMessage(LANG_NO_CHAR_SELECTED);
4176 SetSentErrorMessage(true);
4177 return false;
4180 // check online security
4181 if (HasLowerSecurity(player, 0))
4182 return false;
4184 if (strncmp(args, "on", 3) == 0)
4185 player->SetMovement(MOVE_WATER_WALK); // ON
4186 else if (strncmp(args, "off", 4) == 0)
4187 player->SetMovement(MOVE_LAND_WALK); // OFF
4188 else
4190 SendSysMessage(LANG_USE_BOL);
4191 return false;
4194 PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str());
4195 if(needReportToTarget(player))
4196 ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());
4197 return true;