[7690] Move GetCreature/GetGameobject to class Map.
[AHbot.git] / src / game / Level2.cpp
blob79cd2c5da980b407c8b25cff9e224a91ddb491ef
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 if (!*args)
56 return false;
58 std::string name = extractPlayerNameFromLink((char*)args);
59 if(name.empty())
61 SendSysMessage(LANG_PLAYER_NOT_FOUND);
62 SetSentErrorMessage(true);
63 return false;
66 char *timetonotspeak = strtok(NULL, " ");
67 if(!timetonotspeak)
68 return false;
70 uint32 notspeaktime = (uint32) atoi(timetonotspeak);
72 uint64 guid = objmgr.GetPlayerGUIDByName(name);
73 if(!guid)
75 SendSysMessage(LANG_PLAYER_NOT_FOUND);
76 SetSentErrorMessage(true);
77 return false;
80 Player *chr = objmgr.GetPlayer(guid);
82 // must have strong lesser security level
83 if(HasLowerSecurity (chr,guid,true))
84 return false;
86 uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
88 time_t mutetime = time(NULL) + notspeaktime*60;
90 if (chr)
91 chr->GetSession()->m_muteTime = mutetime;
93 loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
95 if(chr)
96 ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
98 std::string nameLink = playerLink(name);
100 PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);
102 return true;
105 //unmute player
106 bool ChatHandler::HandleUnmuteCommand(const char* args)
108 if (!*args)
109 return false;
111 std::string name = extractPlayerNameFromLink((char*)args);
112 if(name.empty())
114 SendSysMessage(LANG_PLAYER_NOT_FOUND);
115 SetSentErrorMessage(true);
116 return false;
119 uint64 guid = objmgr.GetPlayerGUIDByName(name);
120 if(!guid)
122 SendSysMessage(LANG_PLAYER_NOT_FOUND);
123 SetSentErrorMessage(true);
124 return false;
127 Player *chr = objmgr.GetPlayer(guid);
129 // must have strong lesser security level
130 if(HasLowerSecurity (chr,guid,true))
131 return false;
133 uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
135 if (chr)
137 if(chr->CanSpeak())
139 SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
140 SetSentErrorMessage(true);
141 return false;
144 chr->GetSession()->m_muteTime = 0;
147 loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
149 if(chr)
150 ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
152 std::string nameLink = playerLink(name);
154 PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());
155 return true;
158 bool ChatHandler::HandleGoTriggerCommand(const char* args)
160 Player* _player = m_session->GetPlayer();
162 if (!*args)
163 return false;
165 char *atId = strtok((char*)args, " ");
166 if (!atId)
167 return false;
169 int32 i_atId = atoi(atId);
171 if(!i_atId)
172 return false;
174 AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
175 if (!at)
177 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
178 SetSentErrorMessage(true);
179 return false;
182 if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
184 PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
185 SetSentErrorMessage(true);
186 return false;
189 // stop flight if need
190 if(_player->isInFlight())
192 _player->GetMotionMaster()->MovementExpired();
193 _player->m_taxi.ClearTaxiDestinations();
195 // save only in non-flight case
196 else
197 _player->SaveRecallPosition();
199 _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
200 return true;
203 bool ChatHandler::HandleGoGraveyardCommand(const char* args)
205 Player* _player = m_session->GetPlayer();
207 if (!*args)
208 return false;
210 char *gyId = strtok((char*)args, " ");
211 if (!gyId)
212 return false;
214 int32 i_gyId = atoi(gyId);
216 if(!i_gyId)
217 return false;
219 WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
220 if (!gy)
222 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
223 SetSentErrorMessage(true);
224 return false;
227 if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
229 PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
230 SetSentErrorMessage(true);
231 return false;
234 // stop flight if need
235 if(_player->isInFlight())
237 _player->GetMotionMaster()->MovementExpired();
238 _player->m_taxi.ClearTaxiDestinations();
240 // save only in non-flight case
241 else
242 _player->SaveRecallPosition();
244 _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
245 return true;
248 /** \brief Teleport the GM to the specified creature
250 * .gocreature <GUID> --> TP using creature.guid
251 * .gocreature azuregos --> TP player to the mob with this name
252 * Warning: If there is more than one mob with this name
253 * you will be teleported to the first one that is found.
254 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
255 * Warning: If there is more than one mob with this "id"
256 * you will be teleported to the first one that is found.
258 //teleport to creature
259 bool ChatHandler::HandleGoCreatureCommand(const char* args)
261 if(!*args)
262 return false;
263 Player* _player = m_session->GetPlayer();
265 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
266 char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
267 if (!pParam1)
268 return false;
270 std::ostringstream whereClause;
272 // User wants to teleport to the NPC's template entry
273 if( strcmp(pParam1, "id") == 0 )
275 //sLog.outError("DEBUG: ID found");
277 // Get the "creature_template.entry"
278 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
279 char* tail = strtok(NULL,"");
280 if(!tail)
281 return false;
282 char* cId = extractKeyFromLink(tail,"Hcreature_entry");
283 if(!cId)
284 return false;
286 int32 tEntry = atoi(cId);
287 //sLog.outError("DEBUG: ID value: %d", tEntry);
288 if(!tEntry)
289 return false;
291 whereClause << "WHERE id = '" << tEntry << "'";
293 else
295 //sLog.outError("DEBUG: ID *not found*");
297 int32 guid = atoi(pParam1);
299 // Number is invalid - maybe the user specified the mob's name
300 if(!guid)
302 std::string name = pParam1;
303 WorldDatabase.escape_string(name);
304 whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
306 else
308 whereClause << "WHERE guid = '" << guid << "'";
311 //sLog.outError("DEBUG: %s", whereClause.c_str());
313 QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
314 if (!result)
316 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
317 SetSentErrorMessage(true);
318 return false;
320 if( result->GetRowCount() > 1 )
322 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
325 Field *fields = result->Fetch();
326 float x = fields[0].GetFloat();
327 float y = fields[1].GetFloat();
328 float z = fields[2].GetFloat();
329 float ort = fields[3].GetFloat();
330 int mapid = fields[4].GetUInt16();
332 delete result;
334 if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
336 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
337 SetSentErrorMessage(true);
338 return false;
341 // stop flight if need
342 if(_player->isInFlight())
344 _player->GetMotionMaster()->MovementExpired();
345 _player->m_taxi.ClearTaxiDestinations();
347 // save only in non-flight case
348 else
349 _player->SaveRecallPosition();
351 _player->TeleportTo(mapid, x, y, z, ort);
352 return true;
355 //teleport to gameobject
356 bool ChatHandler::HandleGoObjectCommand(const char* args)
358 if(!*args)
359 return false;
361 Player* _player = m_session->GetPlayer();
363 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
364 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
365 if(!cId)
366 return false;
368 int32 guid = atoi(cId);
369 if(!guid)
370 return false;
372 float x, y, z, ort;
373 int mapid;
375 // by DB guid
376 if (GameObjectData const* go_data = objmgr.GetGOData(guid))
378 x = go_data->posX;
379 y = go_data->posY;
380 z = go_data->posZ;
381 ort = go_data->orientation;
382 mapid = go_data->mapid;
384 else
386 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
387 SetSentErrorMessage(true);
388 return false;
391 if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
393 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
394 SetSentErrorMessage(true);
395 return false;
398 // stop flight if need
399 if(_player->isInFlight())
401 _player->GetMotionMaster()->MovementExpired();
402 _player->m_taxi.ClearTaxiDestinations();
404 // save only in non-flight case
405 else
406 _player->SaveRecallPosition();
408 _player->TeleportTo(mapid, x, y, z, ort);
409 return true;
412 bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
414 Player* pl = m_session->GetPlayer();
415 QueryResult *result;
416 GameEventMgr::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
417 if(*args)
419 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
420 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
421 if(!cId)
422 return false;
424 uint32 id = atol(cId);
426 if(id)
427 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",
428 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
429 else
431 std::string name = cId;
432 WorldDatabase.escape_string(name);
433 result = WorldDatabase.PQuery(
434 "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_ "
435 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
436 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
439 else
441 std::ostringstream eventFilter;
442 eventFilter << " AND (event IS NULL ";
443 bool initString = true;
445 for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
447 if (initString)
449 eventFilter << "OR event IN (" <<*itr;
450 initString =false;
452 else
453 eventFilter << "," << *itr;
456 if (!initString)
457 eventFilter << "))";
458 else
459 eventFilter << ")";
461 result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
462 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
463 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
464 m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
467 if (!result)
469 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
470 return true;
473 bool found = false;
474 float x, y, z, o;
475 uint32 lowguid, id;
476 uint16 mapid, pool_id;
480 Field *fields = result->Fetch();
481 lowguid = fields[0].GetUInt32();
482 id = fields[1].GetUInt32();
483 x = fields[2].GetFloat();
484 y = fields[3].GetFloat();
485 z = fields[4].GetFloat();
486 o = fields[5].GetFloat();
487 mapid = fields[6].GetUInt16();
488 pool_id = poolhandler.IsPartOfAPool(lowguid, TYPEID_GAMEOBJECT);
489 if (!pool_id || (pool_id && poolhandler.IsSpawnedObject(pool_id, lowguid, TYPEID_GAMEOBJECT)))
490 found = true;
491 } while( result->NextRow() && (!found) );
493 delete result;
495 if (!found)
497 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
498 return false;
501 GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
503 if (!goI)
505 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
506 return false;
509 GameObject* target = m_session->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
511 PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
513 if(target)
515 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
516 if(curRespawnDelay < 0)
517 curRespawnDelay = 0;
519 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
520 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
522 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
524 return true;
527 //delete object by selection or guid
528 bool ChatHandler::HandleGameObjectDeleteCommand(const char* args)
530 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
531 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
532 if(!cId)
533 return false;
535 uint32 lowguid = atoi(cId);
536 if(!lowguid)
537 return false;
539 GameObject* obj = NULL;
541 // by DB guid
542 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
543 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
545 if(!obj)
547 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
548 SetSentErrorMessage(true);
549 return false;
552 uint64 owner_guid = obj->GetOwnerGUID();
553 if(owner_guid)
555 Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
556 if(!owner && !IS_PLAYER_GUID(owner_guid))
558 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
559 SetSentErrorMessage(true);
560 return false;
563 owner->RemoveGameObject(obj,false);
566 obj->SetRespawnTime(0); // not save respawn time
567 obj->Delete();
568 obj->DeleteFromDB();
570 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
572 return true;
575 //turn selected object
576 bool ChatHandler::HandleGameObjectTurnCommand(const char* args)
578 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
579 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
580 if(!cId)
581 return false;
583 uint32 lowguid = atoi(cId);
584 if(!lowguid)
585 return false;
587 GameObject* obj = NULL;
589 // by DB guid
590 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
591 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
593 if(!obj)
595 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
596 SetSentErrorMessage(true);
597 return false;
600 char* po = strtok(NULL, " ");
601 float o;
603 if (po)
605 o = (float)atof(po);
607 else
609 Player *chr = m_session->GetPlayer();
610 o = chr->GetOrientation();
613 Map* map = obj->GetMap();
614 map->Remove(obj,false);
616 obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
617 obj->UpdateRotationFields();
619 map->Add(obj);
621 obj->SaveToDB();
622 obj->Refresh();
624 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow(), o);
626 return true;
629 //move selected object
630 bool ChatHandler::HandleGameObjectMoveCommand(const char* args)
632 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
633 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
634 if(!cId)
635 return false;
637 uint32 lowguid = atoi(cId);
638 if(!lowguid)
639 return false;
641 GameObject* obj = NULL;
643 // by DB guid
644 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
645 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
647 if(!obj)
649 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
650 SetSentErrorMessage(true);
651 return false;
654 char* px = strtok(NULL, " ");
655 char* py = strtok(NULL, " ");
656 char* pz = strtok(NULL, " ");
658 if (!px)
660 Player *chr = m_session->GetPlayer();
662 Map* map = obj->GetMap();
663 map->Remove(obj,false);
665 obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
666 obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
667 obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
668 obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
670 map->Add(obj);
672 else
674 if(!py || !pz)
675 return false;
677 float x = (float)atof(px);
678 float y = (float)atof(py);
679 float z = (float)atof(pz);
681 if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
683 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
684 SetSentErrorMessage(true);
685 return false;
688 Map* map = obj->GetMap();
689 map->Remove(obj,false);
691 obj->Relocate(x, y, z, obj->GetOrientation());
692 obj->SetFloatValue(GAMEOBJECT_POS_X, x);
693 obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
694 obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
696 map->Add(obj);
699 obj->SaveToDB();
700 obj->Refresh();
702 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow(), obj->GetGOInfo()->name, obj->GetGUIDLow());
704 return true;
707 //spawn go
708 bool ChatHandler::HandleGameObjectAddCommand(const char* args)
710 if (!*args)
711 return false;
713 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
714 char* cId = extractKeyFromLink((char*)args,"Hgameobject_entry");
715 if(!cId)
716 return false;
718 uint32 id = atol(cId);
719 if(!id)
720 return false;
722 char* spawntimeSecs = strtok(NULL, " ");
724 const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
726 if (!goI)
728 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
729 SetSentErrorMessage(true);
730 return false;
733 Player *chr = m_session->GetPlayer();
734 float x = float(chr->GetPositionX());
735 float y = float(chr->GetPositionY());
736 float z = float(chr->GetPositionZ());
737 float o = float(chr->GetOrientation());
738 Map *map = chr->GetMap();
740 GameObject* pGameObj = new GameObject;
741 uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
743 if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, 1))
745 delete pGameObj;
746 return false;
749 if( spawntimeSecs )
751 uint32 value = atoi((char*)spawntimeSecs);
752 pGameObj->SetRespawnTime(value);
753 //sLog.outDebug("*** spawntimeSecs: %d", value);
756 // fill the gameobject data and save to the db
757 pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()),chr->GetPhaseMaskForSpawn());
759 // this will generate a new guid if the object is in an instance
760 if(!pGameObj->LoadFromDB(db_lowGUID, map))
762 delete pGameObj;
763 return false;
766 sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
768 map->Add(pGameObj);
770 // TODO: is it really necessary to add both the real and DB table guid here ?
771 objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
773 PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
774 return true;
777 //set pahsemask for selected object
778 bool ChatHandler::HandleGameObjectPhaseCommand(const char* args)
780 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
781 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
782 if(!cId)
783 return false;
785 uint32 lowguid = atoi(cId);
786 if(!lowguid)
787 return false;
789 GameObject* obj = NULL;
791 // by DB guid
792 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
793 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
795 if(!obj)
797 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
798 SetSentErrorMessage(true);
799 return false;
802 char* phaseStr = strtok (NULL, " ");
803 uint32 phasemask = phaseStr? atoi(phaseStr) : 0;
804 if ( phasemask == 0 )
806 SendSysMessage(LANG_BAD_VALUE);
807 SetSentErrorMessage(true);
808 return false;
811 obj->SetPhaseMask(phasemask,true);
812 obj->SaveToDB();
813 return true;
816 bool ChatHandler::HandleGameObjectNearCommand(const char* args)
818 float distance = (!*args) ? 10 : atol(args);
819 uint32 count = 0;
821 Player* pl = m_session->GetPlayer();
822 QueryResult *result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
823 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
824 "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_",
825 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),
826 pl->GetMapId(),pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(),distance*distance);
828 if (result)
832 Field *fields = result->Fetch();
833 uint32 guid = fields[0].GetUInt32();
834 uint32 entry = fields[1].GetUInt32();
835 float x = fields[2].GetFloat();
836 float y = fields[3].GetFloat();
837 float z = fields[4].GetFloat();
838 int mapid = fields[5].GetUInt16();
840 GameObjectInfo const * gInfo = objmgr.GetGameObjectInfo(entry);
842 if(!gInfo)
843 continue;
845 PSendSysMessage(LANG_GO_LIST_CHAT, guid, guid, gInfo->name, x, y, z, mapid);
847 ++count;
848 } while (result->NextRow());
850 delete result;
853 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE,distance,count);
854 return true;
857 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
859 uint64 guid = m_session->GetPlayer()->GetSelection();
861 if (guid == 0)
863 SendSysMessage(LANG_NO_SELECTION);
864 SetSentErrorMessage(true);
865 return false;
868 PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
869 return true;
872 bool ChatHandler::HandleLookupFactionCommand(const char* args)
874 if (!*args)
875 return false;
877 // Can be NULL at console call
878 Player *target = getSelectedPlayer ();
880 std::string namepart = args;
881 std::wstring wnamepart;
883 if (!Utf8toWStr (namepart,wnamepart))
884 return false;
886 // converting string that we try to find to lower case
887 wstrToLower (wnamepart);
889 uint32 counter = 0; // Counter for figure out that we found smth.
891 for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
893 FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
894 if (factionEntry)
896 FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
898 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
899 std::string name = factionEntry->name[loc];
900 if(name.empty())
901 continue;
903 if (!Utf8FitTo(name, wnamepart))
905 loc = 0;
906 for(; loc < MAX_LOCALE; ++loc)
908 if(m_session && loc==m_session->GetSessionDbcLocale())
909 continue;
911 name = factionEntry->name[loc];
912 if(name.empty())
913 continue;
915 if (Utf8FitTo(name, wnamepart))
916 break;
920 if(loc < MAX_LOCALE)
922 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
923 // or "id - [faction] [no reputation]" format
924 std::ostringstream ss;
925 if (m_session)
926 ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
927 else
928 ss << id << " - " << name << " " << localeNames[loc];
930 if (repState) // and then target!=NULL also
932 ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
933 std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
935 ss << " " << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ")";
937 if(repState->Flags & FACTION_FLAG_VISIBLE)
938 ss << GetMangosString(LANG_FACTION_VISIBLE);
939 if(repState->Flags & FACTION_FLAG_AT_WAR)
940 ss << GetMangosString(LANG_FACTION_ATWAR);
941 if(repState->Flags & FACTION_FLAG_PEACE_FORCED)
942 ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
943 if(repState->Flags & FACTION_FLAG_HIDDEN)
944 ss << GetMangosString(LANG_FACTION_HIDDEN);
945 if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
946 ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
947 if(repState->Flags & FACTION_FLAG_INACTIVE)
948 ss << GetMangosString(LANG_FACTION_INACTIVE);
950 else
951 ss << GetMangosString(LANG_FACTION_NOREPUTATION);
953 SendSysMessage(ss.str().c_str());
954 counter++;
959 if (counter == 0) // if counter == 0 then we found nth
960 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
961 return true;
964 bool ChatHandler::HandleModifyRepCommand(const char * args)
966 if (!*args) return false;
968 Player* target = NULL;
969 target = getSelectedPlayer();
971 if(!target)
973 SendSysMessage(LANG_PLAYER_NOT_FOUND);
974 SetSentErrorMessage(true);
975 return false;
978 // check online security
979 if (HasLowerSecurity(target, 0))
980 return false;
982 char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
983 if(!factionTxt)
984 return false;
986 uint32 factionId = atoi(factionTxt);
988 int32 amount = 0;
989 char *rankTxt = strtok(NULL, " ");
990 if (!factionTxt || !rankTxt)
991 return false;
993 amount = atoi(rankTxt);
994 if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
996 std::string rankStr = rankTxt;
997 std::wstring wrankStr;
998 if(!Utf8toWStr(rankStr,wrankStr))
999 return false;
1000 wstrToLower( wrankStr );
1002 int r = 0;
1003 amount = -42000;
1004 for (; r < MAX_REPUTATION_RANK; ++r)
1006 std::string rank = GetMangosString(ReputationRankStrIndex[r]);
1007 if(rank.empty())
1008 continue;
1010 std::wstring wrank;
1011 if(!Utf8toWStr(rank,wrank))
1012 continue;
1014 wstrToLower(wrank);
1016 if(wrank.substr(0,wrankStr.size())==wrankStr)
1018 char *deltaTxt = strtok(NULL, " ");
1019 if (deltaTxt)
1021 int32 delta = atoi(deltaTxt);
1022 if ((delta < 0) || (delta > ReputationMgr::PointsInRank[r] -1))
1024 PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (ReputationMgr::PointsInRank[r]-1));
1025 SetSentErrorMessage(true);
1026 return false;
1028 amount += delta;
1030 break;
1032 amount += ReputationMgr::PointsInRank[r];
1034 if (r >= MAX_REPUTATION_RANK)
1036 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
1037 SetSentErrorMessage(true);
1038 return false;
1042 FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
1044 if (!factionEntry)
1046 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
1047 SetSentErrorMessage(true);
1048 return false;
1051 if (factionEntry->reputationListID < 0)
1053 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
1054 SetSentErrorMessage(true);
1055 return false;
1058 target->GetReputationMgr().SetReputation(factionEntry,amount);
1059 PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId,
1060 GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry));
1061 return true;
1064 //-----------------------Npc Commands-----------------------
1065 //add spawn of creature
1066 bool ChatHandler::HandleNpcAddCommand(const char* args)
1068 if(!*args)
1069 return false;
1070 char* charID = extractKeyFromLink((char*)args,"Hcreature_entry");
1071 if(!charID)
1072 return false;
1074 char* team = strtok(NULL, " ");
1075 int32 teamval = 0;
1076 if (team) { teamval = atoi(team); }
1077 if (teamval < 0) { teamval = 0; }
1079 uint32 id = atoi(charID);
1081 Player *chr = m_session->GetPlayer();
1082 float x = chr->GetPositionX();
1083 float y = chr->GetPositionY();
1084 float z = chr->GetPositionZ();
1085 float o = chr->GetOrientation();
1086 Map *map = chr->GetMap();
1088 Creature* pCreature = new Creature;
1089 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval))
1091 delete pCreature;
1092 return false;
1095 pCreature->Relocate(x,y,z,o);
1097 if(!pCreature->IsPositionValid())
1099 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());
1100 delete pCreature;
1101 return false;
1104 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
1106 uint32 db_guid = pCreature->GetDBTableGUIDLow();
1108 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
1109 pCreature->LoadFromDB(db_guid, map);
1111 map->Add(pCreature);
1112 objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
1113 return true;
1116 //add item in vendorlist
1117 bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args)
1119 if (!*args)
1120 return false;
1122 char* pitem = extractKeyFromLink((char*)args,"Hitem");
1123 if (!pitem)
1125 SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1126 SetSentErrorMessage(true);
1127 return false;
1130 uint32 itemId = atol(pitem);
1132 char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
1133 uint32 maxcount = 0;
1134 if (fmaxcount)
1135 maxcount = atol(fmaxcount);
1137 char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
1138 uint32 incrtime = 0;
1139 if (fincrtime)
1140 incrtime = atol(fincrtime);
1142 char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
1143 uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
1145 Creature* vendor = getSelectedCreature();
1147 uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
1149 if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
1151 SetSentErrorMessage(true);
1152 return false;
1155 objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
1157 ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1159 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
1160 return true;
1163 //del item from vendor list
1164 bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args)
1166 if (!*args)
1167 return false;
1169 Creature* vendor = getSelectedCreature();
1170 if (!vendor || !vendor->isVendor())
1172 SendSysMessage(LANG_COMMAND_VENDORSELECTION);
1173 SetSentErrorMessage(true);
1174 return false;
1177 char* pitem = extractKeyFromLink((char*)args,"Hitem");
1178 if (!pitem)
1180 SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1181 SetSentErrorMessage(true);
1182 return false;
1184 uint32 itemId = atol(pitem);
1186 if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
1188 PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
1189 SetSentErrorMessage(true);
1190 return false;
1193 ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1195 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
1196 return true;
1199 //add move for creature
1200 bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
1202 if(!*args)
1203 return false;
1205 char* guid_str = strtok((char*)args, " ");
1206 char* wait_str = strtok((char*)NULL, " ");
1208 uint32 lowguid = atoi((char*)guid_str);
1210 Creature* pCreature = NULL;
1212 /* FIXME: impossible without entry
1213 if(lowguid)
1214 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1217 // attempt check creature existence by DB data
1218 if(!pCreature)
1220 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1221 if(!data)
1223 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1224 SetSentErrorMessage(true);
1225 return false;
1228 else
1230 // obtain real GUID for DB operations
1231 lowguid = pCreature->GetDBTableGUIDLow();
1234 int wait = wait_str ? atoi(wait_str) : 0;
1236 if(wait < 0)
1237 wait = 0;
1239 Player* player = m_session->GetPlayer();
1241 WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
1243 // update movement type
1244 WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1245 if(pCreature)
1247 pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1248 pCreature->GetMotionMaster()->Initialize();
1249 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1251 pCreature->setDeathState(JUST_DIED);
1252 pCreature->Respawn();
1254 pCreature->SaveToDB();
1257 SendSysMessage(LANG_WAYPOINT_ADDED);
1259 return true;
1262 //change level of creature or pet
1263 bool ChatHandler::HandleNpcChangeLevelCommand(const char* args)
1265 if (!*args)
1266 return false;
1268 uint8 lvl = (uint8) atoi((char*)args);
1269 if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1271 SendSysMessage(LANG_BAD_VALUE);
1272 SetSentErrorMessage(true);
1273 return false;
1276 Creature* pCreature = getSelectedCreature();
1277 if(!pCreature)
1279 SendSysMessage(LANG_SELECT_CREATURE);
1280 SetSentErrorMessage(true);
1281 return false;
1284 if(pCreature->isPet())
1286 ((Pet*)pCreature)->GivePetLevel(lvl);
1288 else
1290 pCreature->SetMaxHealth( 100 + 30*lvl);
1291 pCreature->SetHealth( 100 + 30*lvl);
1292 pCreature->SetLevel( lvl);
1293 pCreature->SaveToDB();
1296 return true;
1299 //set npcflag of creature
1300 bool ChatHandler::HandleNpcFlagCommand(const char* args)
1302 if (!*args)
1303 return false;
1305 uint32 npcFlags = (uint32) atoi((char*)args);
1307 Creature* pCreature = getSelectedCreature();
1309 if(!pCreature)
1311 SendSysMessage(LANG_SELECT_CREATURE);
1312 SetSentErrorMessage(true);
1313 return false;
1316 pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1318 WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
1320 SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1322 return true;
1325 bool ChatHandler::HandleNpcDeleteCommand(const char* args)
1327 Creature* unit = NULL;
1329 if(*args)
1331 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1332 char* cId = extractKeyFromLink((char*)args,"Hcreature");
1333 if(!cId)
1334 return false;
1336 uint32 lowguid = atoi(cId);
1337 if(!lowguid)
1338 return false;
1340 if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
1341 unit = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
1343 else
1344 unit = getSelectedCreature();
1346 if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())
1348 SendSysMessage(LANG_SELECT_CREATURE);
1349 SetSentErrorMessage(true);
1350 return false;
1353 // Delete the creature
1354 unit->CombatStop();
1355 unit->DeleteFromDB();
1356 unit->CleanupsBeforeDelete();
1357 unit->AddObjectToRemoveList();
1359 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
1361 return true;
1364 //move selected creature
1365 bool ChatHandler::HandleNpcMoveCommand(const char* args)
1367 uint32 lowguid = 0;
1369 Creature* pCreature = getSelectedCreature();
1371 if(!pCreature)
1373 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1374 char* cId = extractKeyFromLink((char*)args,"Hcreature");
1375 if(!cId)
1376 return false;
1378 uint32 lowguid = atoi(cId);
1380 /* FIXME: impossibel without entry
1381 if(lowguid)
1382 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1385 // Attempting creature load from DB data
1386 if(!pCreature)
1388 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1389 if(!data)
1391 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1392 SetSentErrorMessage(true);
1393 return false;
1396 uint32 map_id = data->mapid;
1398 if(m_session->GetPlayer()->GetMapId()!=map_id)
1400 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
1401 SetSentErrorMessage(true);
1402 return false;
1405 else
1407 lowguid = pCreature->GetDBTableGUIDLow();
1410 else
1412 lowguid = pCreature->GetDBTableGUIDLow();
1415 float x = m_session->GetPlayer()->GetPositionX();
1416 float y = m_session->GetPlayer()->GetPositionY();
1417 float z = m_session->GetPlayer()->GetPositionZ();
1418 float o = m_session->GetPlayer()->GetOrientation();
1420 if (pCreature)
1422 if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
1424 const_cast<CreatureData*>(data)->posX = x;
1425 const_cast<CreatureData*>(data)->posY = y;
1426 const_cast<CreatureData*>(data)->posZ = z;
1427 const_cast<CreatureData*>(data)->orientation = o;
1429 pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o);
1430 pCreature->GetMotionMaster()->Initialize();
1431 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1433 pCreature->setDeathState(JUST_DIED);
1434 pCreature->Respawn();
1438 WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
1439 PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
1440 return true;
1443 /**HandleNpcSetMoveTypeCommand
1444 * Set the movement type for an NPC.<br/>
1445 * <br/>
1446 * Valid movement types are:
1447 * <ul>
1448 * <li> stay - NPC wont move </li>
1449 * <li> random - NPC will move randomly according to the spawndist </li>
1450 * <li> way - NPC will move with given waypoints set </li>
1451 * </ul>
1452 * additional parameter: NODEL - so no waypoints are deleted, if you
1453 * change the movement type
1455 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
1457 if(!*args)
1458 return false;
1460 // 3 arguments:
1461 // GUID (optional - you can also select the creature)
1462 // stay|random|way (determines the kind of movement)
1463 // NODEL (optional - tells the system NOT to delete any waypoints)
1464 // this is very handy if you want to do waypoints, that are
1465 // later switched on/off according to special events (like escort
1466 // quests, etc)
1467 char* guid_str = strtok((char*)args, " ");
1468 char* type_str = strtok((char*)NULL, " ");
1469 char* dontdel_str = strtok((char*)NULL, " ");
1471 bool doNotDelete = false;
1473 if(!guid_str)
1474 return false;
1476 uint32 lowguid = 0;
1477 Creature* pCreature = NULL;
1479 if( dontdel_str )
1481 //sLog.outError("DEBUG: All 3 params are set");
1483 // All 3 params are set
1484 // GUID
1485 // type
1486 // doNotDEL
1487 if( stricmp( dontdel_str, "NODEL" ) == 0 )
1489 //sLog.outError("DEBUG: doNotDelete = true;");
1490 doNotDelete = true;
1493 else
1495 // Only 2 params - but maybe NODEL is set
1496 if( type_str )
1498 sLog.outError("DEBUG: Only 2 params ");
1499 if( stricmp( type_str, "NODEL" ) == 0 )
1501 //sLog.outError("DEBUG: type_str, NODEL ");
1502 doNotDelete = true;
1503 type_str = NULL;
1508 if(!type_str) // case .setmovetype $move_type (with selected creature)
1510 type_str = guid_str;
1511 pCreature = getSelectedCreature();
1512 if(!pCreature || pCreature->isPet())
1513 return false;
1514 lowguid = pCreature->GetDBTableGUIDLow();
1516 else // case .setmovetype #creature_guid $move_type (with selected creature)
1518 lowguid = atoi((char*)guid_str);
1520 /* impossible without entry
1521 if(lowguid)
1522 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1525 // attempt check creature existence by DB data
1526 if(!pCreature)
1528 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1529 if(!data)
1531 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1532 SetSentErrorMessage(true);
1533 return false;
1536 else
1538 lowguid = pCreature->GetDBTableGUIDLow();
1542 // now lowguid is low guid really existed creature
1543 // and pCreature point (maybe) to this creature or NULL
1545 MovementGeneratorType move_type;
1547 std::string type = type_str;
1549 if(type == "stay")
1550 move_type = IDLE_MOTION_TYPE;
1551 else if(type == "random")
1552 move_type = RANDOM_MOTION_TYPE;
1553 else if(type == "way")
1554 move_type = WAYPOINT_MOTION_TYPE;
1555 else
1556 return false;
1558 // update movement type
1559 if(doNotDelete == false)
1560 WaypointMgr.DeletePath(lowguid);
1562 if(pCreature)
1564 pCreature->SetDefaultMovementType(move_type);
1565 pCreature->GetMotionMaster()->Initialize();
1566 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1568 pCreature->setDeathState(JUST_DIED);
1569 pCreature->Respawn();
1571 pCreature->SaveToDB();
1573 if( doNotDelete == false )
1575 PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1577 else
1579 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1582 return true;
1585 //set model of creature
1586 bool ChatHandler::HandleNpcSetModelCommand(const char* args)
1588 if (!*args)
1589 return false;
1591 uint32 displayId = (uint32) atoi((char*)args);
1593 Creature *pCreature = getSelectedCreature();
1595 if(!pCreature || pCreature->isPet())
1597 SendSysMessage(LANG_SELECT_CREATURE);
1598 SetSentErrorMessage(true);
1599 return false;
1602 pCreature->SetDisplayId(displayId);
1603 pCreature->SetNativeDisplayId(displayId);
1605 pCreature->SaveToDB();
1607 return true;
1609 //set faction of creature
1610 bool ChatHandler::HandleNpcFactionIdCommand(const char* args)
1612 if (!*args)
1613 return false;
1615 uint32 factionId = (uint32) atoi((char*)args);
1617 if (!sFactionTemplateStore.LookupEntry(factionId))
1619 PSendSysMessage(LANG_WRONG_FACTION, factionId);
1620 SetSentErrorMessage(true);
1621 return false;
1624 Creature* pCreature = getSelectedCreature();
1626 if(!pCreature)
1628 SendSysMessage(LANG_SELECT_CREATURE);
1629 SetSentErrorMessage(true);
1630 return false;
1633 pCreature->setFaction(factionId);
1635 // faction is set in creature_template - not inside creature
1637 // update in memory
1638 if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
1640 const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
1641 const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
1644 // and DB
1645 WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
1647 return true;
1649 //set spawn dist of creature
1650 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
1652 if(!*args)
1653 return false;
1655 float option = atof((char*)args);
1656 if (option < 0.0f)
1658 SendSysMessage(LANG_BAD_VALUE);
1659 return false;
1662 MovementGeneratorType mtype = IDLE_MOTION_TYPE;
1663 if (option >0.0f)
1664 mtype = RANDOM_MOTION_TYPE;
1666 Creature *pCreature = getSelectedCreature();
1667 uint32 u_guidlow = 0;
1669 if (pCreature)
1670 u_guidlow = pCreature->GetDBTableGUIDLow();
1671 else
1672 return false;
1674 pCreature->SetRespawnRadius((float)option);
1675 pCreature->SetDefaultMovementType(mtype);
1676 pCreature->GetMotionMaster()->Initialize();
1677 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1679 pCreature->setDeathState(JUST_DIED);
1680 pCreature->Respawn();
1683 WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
1684 PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
1685 return true;
1687 //spawn time handling
1688 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
1690 if(!*args)
1691 return false;
1693 char* stime = strtok((char*)args, " ");
1695 if (!stime)
1696 return false;
1698 int i_stime = atoi((char*)stime);
1700 if (i_stime < 0)
1702 SendSysMessage(LANG_BAD_VALUE);
1703 SetSentErrorMessage(true);
1704 return false;
1707 Creature *pCreature = getSelectedCreature();
1708 uint32 u_guidlow = 0;
1710 if (pCreature)
1711 u_guidlow = pCreature->GetDBTableGUIDLow();
1712 else
1713 return false;
1715 WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
1716 pCreature->SetRespawnDelay((uint32)i_stime);
1717 PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
1719 return true;
1721 //npc follow handling
1722 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
1724 Player *player = m_session->GetPlayer();
1725 Creature *creature = getSelectedCreature();
1727 if(!creature)
1729 PSendSysMessage(LANG_SELECT_CREATURE);
1730 SetSentErrorMessage(true);
1731 return false;
1734 // Follow player - Using pet's default dist and angle
1735 creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
1737 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName());
1738 return true;
1740 //npc unfollow handling
1741 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
1743 Player *player = m_session->GetPlayer();
1744 Creature *creature = getSelectedCreature();
1746 if(!creature)
1748 PSendSysMessage(LANG_SELECT_CREATURE);
1749 SetSentErrorMessage(true);
1750 return false;
1753 if (creature->GetMotionMaster()->empty() ||
1754 creature->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE)
1756 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
1757 SetSentErrorMessage(true);
1758 return false;
1761 TargetedMovementGenerator<Creature> const* mgen
1762 = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
1764 if(mgen->GetTarget()!=player)
1766 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU);
1767 SetSentErrorMessage(true);
1768 return false;
1771 // reset movement
1772 creature->GetMotionMaster()->MovementExpired(true);
1774 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName());
1775 return true;
1777 //npc tame handling
1778 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
1780 Creature *creatureTarget = getSelectedCreature ();
1781 if (!creatureTarget || creatureTarget->isPet ())
1783 PSendSysMessage (LANG_SELECT_CREATURE);
1784 SetSentErrorMessage (true);
1785 return false;
1788 Player *player = m_session->GetPlayer ();
1790 if(player->GetPetGUID ())
1792 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET);
1793 SetSentErrorMessage (true);
1794 return false;
1797 CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo();
1799 if (!cInfo->isTameable ())
1801 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
1802 SetSentErrorMessage (true);
1803 return false;
1806 // Everything looks OK, create new pet
1807 Pet* pet = player->CreateTamedPetFrom (creatureTarget);
1808 if (!pet)
1810 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
1811 SetSentErrorMessage (true);
1812 return false;
1815 // place pet before player
1816 float x,y,z;
1817 player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE);
1818 pet->Relocate (x,y,z,M_PI-player->GetOrientation ());
1820 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
1821 pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
1823 // calculate proper level
1824 uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel();
1826 // prepare visual effect for levelup
1827 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
1829 // add to world
1830 pet->GetMap()->Add((Creature*)pet);
1832 // visual effect for levelup
1833 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
1835 // caster have pet now
1836 player->SetPet(pet);
1838 pet->SavePetToDB(PET_SAVE_AS_CURRENT);
1839 player->PetSpellInitialize();
1841 return true;
1843 //npc phasemask handling
1844 //change phasemask of creature or pet
1845 bool ChatHandler::HandleNpcSetPhaseCommand(const char* args)
1847 if (!*args)
1848 return false;
1850 uint32 phasemask = (uint32) atoi((char*)args);
1851 if ( phasemask == 0 )
1853 SendSysMessage(LANG_BAD_VALUE);
1854 SetSentErrorMessage(true);
1855 return false;
1858 Creature* pCreature = getSelectedCreature();
1859 if(!pCreature)
1861 SendSysMessage(LANG_SELECT_CREATURE);
1862 SetSentErrorMessage(true);
1863 return false;
1866 pCreature->SetPhaseMask(phasemask,true);
1868 if(!pCreature->isPet())
1869 pCreature->SaveToDB();
1871 return true;
1873 //npc deathstate handling
1874 bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args)
1876 if (!*args)
1877 return false;
1879 Creature* pCreature = getSelectedCreature();
1880 if(!pCreature || pCreature->isPet())
1882 SendSysMessage(LANG_SELECT_CREATURE);
1883 SetSentErrorMessage(true);
1884 return false;
1887 if (strncmp(args, "on", 3) == 0)
1888 pCreature->SetDeadByDefault(true);
1889 else if (strncmp(args, "off", 4) == 0)
1890 pCreature->SetDeadByDefault(false);
1891 else
1893 SendSysMessage(LANG_USE_BOL);
1894 SetSentErrorMessage(true);
1895 return false;
1898 pCreature->SaveToDB();
1899 pCreature->Respawn();
1901 return true;
1904 //TODO: NpcCommands that need to be fixed :
1906 bool ChatHandler::HandleNpcNameCommand(const char* /*args*/)
1908 /* Temp. disabled
1909 if(!*args)
1910 return false;
1912 if(strlen((char*)args)>75)
1914 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
1915 return true;
1918 for (uint8 i = 0; i < strlen(args); i++)
1920 if(!isalpha(args[i]) && args[i]!=' ')
1922 SendSysMessage(LANG_CHARS_ONLY);
1923 return false;
1927 uint64 guid;
1928 guid = m_session->GetPlayer()->GetSelection();
1929 if (guid == 0)
1931 SendSysMessage(LANG_NO_SELECTION);
1932 return true;
1935 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1937 if(!pCreature)
1939 SendSysMessage(LANG_SELECT_CREATURE);
1940 return true;
1943 pCreature->SetName(args);
1944 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
1945 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1947 pCreature->SaveToDB();
1950 return true;
1953 bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
1955 /* Temp. disabled
1957 if(!*args)
1958 args = "";
1960 if(strlen((char*)args)>75)
1963 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
1964 return true;
1967 for (uint8 i = 0; i < strlen(args); i++)
1969 if(!isalpha(args[i]) && args[i]!=' ')
1971 SendSysMessage(LANG_CHARS_ONLY);
1972 return false;
1975 uint64 guid;
1976 guid = m_session->GetPlayer()->GetSelection();
1977 if (guid == 0)
1979 SendSysMessage(LANG_NO_SELECTION);
1980 return true;
1983 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1985 if(!pCreature)
1987 SendSysMessage(LANG_SELECT_CREATURE);
1988 return true;
1991 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
1992 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1994 pCreature->SaveToDB();
1996 return true;
1999 //move item to other slot
2000 bool ChatHandler::HandleItemMoveCommand(const char* args)
2002 if(!*args)
2003 return false;
2004 uint8 srcslot, dstslot;
2006 char* pParam1 = strtok((char*)args, " ");
2007 if (!pParam1)
2008 return false;
2010 char* pParam2 = strtok(NULL, " ");
2011 if (!pParam2)
2012 return false;
2014 srcslot = (uint8)atoi(pParam1);
2015 dstslot = (uint8)atoi(pParam2);
2017 if(srcslot==dstslot)
2018 return true;
2020 if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
2021 return false;
2023 if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
2024 return false;
2026 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
2027 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
2029 m_session->GetPlayer()->SwapItem( src, dst );
2031 return true;
2034 //demorph player or unit
2035 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
2037 Unit *target = getSelectedUnit();
2038 if(!target)
2039 target = m_session->GetPlayer();
2042 // check online security
2043 else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
2044 return false;
2046 target->DeMorph();
2048 return true;
2051 //morph creature or player
2052 bool ChatHandler::HandleModifyMorphCommand(const char* args)
2054 if (!*args)
2055 return false;
2057 uint16 display_id = (uint16)atoi((char*)args);
2059 Unit *target = getSelectedUnit();
2060 if(!target)
2061 target = m_session->GetPlayer();
2063 // check online security
2064 else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
2065 return false;
2067 target->SetDisplayId(display_id);
2069 return true;
2072 //kick player
2073 bool ChatHandler::HandleKickPlayerCommand(const char *args)
2075 if (!*args)
2077 Player* player = getSelectedPlayer();
2079 if(!player)
2081 SendSysMessage(LANG_NO_CHAR_SELECTED);
2082 SetSentErrorMessage(true);
2083 return false;
2086 if(player==m_session->GetPlayer())
2088 SendSysMessage(LANG_COMMAND_KICKSELF);
2089 SetSentErrorMessage(true);
2090 return false;
2093 // check online security
2094 if (HasLowerSecurity(player, 0))
2095 return false;
2097 player->GetSession()->KickPlayer();
2099 else
2101 std::string name = extractPlayerNameFromLink((char*)args);
2102 if(name.empty())
2104 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2105 SetSentErrorMessage(true);
2106 return false;
2109 if(m_session && name==m_session->GetPlayer()->GetName())
2111 SendSysMessage(LANG_COMMAND_KICKSELF);
2112 SetSentErrorMessage(true);
2113 return false;
2116 // check online security
2117 Player* player = ObjectAccessor::Instance().FindPlayerByName(name.c_str());
2118 if (player && HasLowerSecurity(player, 0))
2119 return false;
2121 std::string nameLink = playerLink(name);
2123 if(sWorld.KickPlayer(name))
2125 PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());
2127 else
2128 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());
2131 return true;
2134 //set temporary phase mask for player
2135 bool ChatHandler::HandleModifyPhaseCommand(const char* args)
2137 if (!*args)
2138 return false;
2140 uint32 phasemask = (uint32)atoi((char*)args);
2142 Unit *target = getSelectedUnit();
2143 if(!target)
2144 target = m_session->GetPlayer();
2146 // check online security
2147 else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
2148 return false;
2150 target->SetPhaseMask(phasemask,true);
2152 return true;
2155 //show info of player
2156 bool ChatHandler::HandlePInfoCommand(const char* args)
2158 Player* target = NULL;
2159 uint64 targetGUID = 0;
2161 char* px = strtok((char*)args, " ");
2162 char* py = NULL;
2164 std::string name;
2166 if (px)
2168 name = extractPlayerNameFromLink(px);
2169 if(name.empty())
2171 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2172 SetSentErrorMessage(true);
2173 return false;
2176 target = objmgr.GetPlayer(name.c_str());
2177 if (target)
2178 py = strtok(NULL, " ");
2179 else
2181 targetGUID = objmgr.GetPlayerGUIDByName(name);
2182 if(targetGUID)
2183 py = strtok(NULL, " ");
2184 else
2185 py = px;
2189 if(!target && !targetGUID)
2191 target = getSelectedPlayer();
2194 if(!target && !targetGUID)
2196 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2197 SetSentErrorMessage(true);
2198 return false;
2201 uint32 accId = 0;
2202 uint32 money = 0;
2203 uint32 total_player_time = 0;
2204 uint32 level = 0;
2205 uint32 latency = 0;
2207 // get additional information from Player object
2208 if(target)
2210 // check online security
2211 if (HasLowerSecurity(target, 0))
2212 return false;
2214 targetGUID = target->GetGUID();
2215 name = target->GetName(); // re-read for case getSelectedPlayer() target
2216 accId = target->GetSession()->GetAccountId();
2217 money = target->GetMoney();
2218 total_player_time = target->GetTotalPlayedTime();
2219 level = target->getLevel();
2220 latency = target->GetSession()->GetLatency();
2222 // get additional information from DB
2223 else
2225 // check offline security
2226 if (HasLowerSecurity(NULL, targetGUID))
2227 return false;
2229 // 0
2230 QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));
2231 if (!result)
2233 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2234 SetSentErrorMessage(true);
2235 return false;
2237 Field *fields = result->Fetch();
2238 total_player_time = fields[0].GetUInt32();
2239 delete result;
2241 Tokens data;
2242 if (!Player::LoadValuesArrayFromDB(data,targetGUID))
2244 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2245 SetSentErrorMessage(true);
2246 return false;
2249 money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
2250 level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
2252 accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
2255 std::string username = GetMangosString(LANG_ERROR);
2256 std::string last_ip = GetMangosString(LANG_ERROR);
2257 uint32 security = 0;
2258 std::string last_login = GetMangosString(LANG_ERROR);
2260 QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
2261 if(result)
2263 Field* fields = result->Fetch();
2264 username = fields[0].GetCppString();
2265 security = fields[1].GetUInt32();
2267 if(!m_session || m_session->GetSecurity() >= security)
2269 last_ip = fields[2].GetCppString();
2270 last_login = fields[3].GetCppString();
2272 else
2274 last_ip = "-";
2275 last_login = "-";
2278 delete result;
2281 std::string nameLink = playerLink(name);
2283 PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
2285 std::string timeStr = secsToTimeString(total_player_time,true,true);
2286 uint32 gold = money /GOLD;
2287 uint32 silv = (money % GOLD) / SILVER;
2288 uint32 copp = (money % GOLD) % SILVER;
2289 PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
2291 if ( py && strncmp(py, "rep", 3) == 0 )
2293 if(!target)
2295 // rep option not implemented for offline case
2296 SendSysMessage(LANG_PINFO_NO_REP);
2297 SetSentErrorMessage(true);
2298 return false;
2301 FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
2302 for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
2304 FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
2305 char const* factionName = factionEntry ? factionEntry->name[m_session->GetSessionDbcLocale()] : "#Not found#";
2306 ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
2307 std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
2308 std::ostringstream ss;
2309 ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << "]|h|r " << rankName << "|h|r ("
2310 << target->GetReputationMgr().GetReputation(factionEntry) << ")";
2312 if(itr->second.Flags & FACTION_FLAG_VISIBLE)
2313 ss << GetMangosString(LANG_FACTION_VISIBLE);
2314 if(itr->second.Flags & FACTION_FLAG_AT_WAR)
2315 ss << GetMangosString(LANG_FACTION_ATWAR);
2316 if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
2317 ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
2318 if(itr->second.Flags & FACTION_FLAG_HIDDEN)
2319 ss << GetMangosString(LANG_FACTION_HIDDEN);
2320 if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
2321 ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
2322 if(itr->second.Flags & FACTION_FLAG_INACTIVE)
2323 ss << GetMangosString(LANG_FACTION_INACTIVE);
2325 SendSysMessage(ss.str().c_str());
2328 return true;
2331 //show tickets
2332 void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
2334 std::string name;
2335 if(!objmgr.GetPlayerNameByGUID(guid,name))
2336 name = GetMangosString(LANG_UNKNOWN);
2338 std::string nameLink = playerLink(name);
2340 PSendSysMessage(LANG_COMMAND_TICKETVIEW, nameLink.c_str(),time,text);
2343 //ticket commands
2344 bool ChatHandler::HandleTicketCommand(const char* args)
2346 char* px = strtok((char*)args, " ");
2348 // ticket<end>
2349 if (!px)
2351 if(!m_session)
2353 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2354 SetSentErrorMessage(true);
2355 return false;
2358 size_t count = ticketmgr.GetTicketCount();
2360 bool accept = m_session->GetPlayer()->isAcceptTickets();
2362 PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ? GetMangosString(LANG_ON) : GetMangosString(LANG_OFF));
2363 return true;
2366 // ticket on
2367 if(strncmp(px,"on",3) == 0)
2369 if(!m_session)
2371 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2372 SetSentErrorMessage(true);
2373 return false;
2376 m_session->GetPlayer()->SetAcceptTicket(true);
2377 SendSysMessage(LANG_COMMAND_TICKETON);
2378 return true;
2381 // ticket off
2382 if(strncmp(px,"off",4) == 0)
2384 if(!m_session)
2386 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2387 SetSentErrorMessage(true);
2388 return false;
2391 m_session->GetPlayer()->SetAcceptTicket(false);
2392 SendSysMessage(LANG_COMMAND_TICKETOFF);
2393 return true;
2396 // ticket #num
2397 int num = atoi(px);
2398 if(num > 0)
2400 QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
2402 if(!result)
2404 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2405 SetSentErrorMessage(true);
2406 return false;
2409 Field* fields = result->Fetch();
2411 uint32 guid = fields[0].GetUInt32();
2412 char const* text = fields[1].GetString();
2413 char const* time = fields[2].GetString();
2415 ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
2416 delete result;
2417 return true;
2420 std::string name = extractPlayerNameFromLink(px);
2421 if(name.empty())
2423 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2424 SetSentErrorMessage(true);
2425 return false;
2428 uint64 guid = objmgr.GetPlayerGUIDByName(name);
2430 if(!guid)
2431 return false;
2433 // ticket $char_name
2434 GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid));
2435 if(!ticket)
2436 return false;
2438 std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
2440 ShowTicket(guid, ticket->GetText(), time.c_str());
2442 return true;
2445 //dell all tickets
2446 bool ChatHandler::HandleDelTicketCommand(const char *args)
2448 char* px = strtok((char*)args, " ");
2449 if (!px)
2450 return false;
2452 // delticket all
2453 if(strncmp(px,"all",4) == 0)
2455 ticketmgr.DeleteAll();
2456 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
2457 return true;
2460 int num = (uint32)atoi(px);
2462 // delticket #num
2463 if(num > 0)
2465 QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
2466 if(!result)
2468 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2469 SetSentErrorMessage(true);
2470 return false;
2472 Field* fields = result->Fetch();
2473 uint32 guid = fields[0].GetUInt32();
2474 delete result;
2476 ticketmgr.Delete(guid);
2478 //notify player
2479 if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
2481 pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2482 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, GetNameLink(pl).c_str());
2484 else
2485 PSendSysMessage(LANG_COMMAND_TICKETDEL);
2487 return true;
2490 std::string name = extractPlayerNameFromLink(px);
2491 if(name.empty())
2493 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2494 SetSentErrorMessage(true);
2495 return false;
2498 uint64 guid = objmgr.GetPlayerGUIDByName(name);
2500 if(!guid)
2501 return false;
2503 // delticket $char_name
2504 ticketmgr.Delete(GUID_LOPART(guid));
2506 // notify players about ticket deleting
2507 if(Player* sender = objmgr.GetPlayer(guid))
2508 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2510 std::string nameLink = playerLink(name);
2512 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());
2513 return true;
2517 * Add a waypoint to a creature.
2519 * The user can either select an npc or provide its GUID.
2521 * The user can even select a visual waypoint - then the new waypoint
2522 * is placed *after* the selected one - this makes insertion of new
2523 * waypoints possible.
2525 * eg:
2526 * .wp add 12345
2527 * -> adds a waypoint to the npc with the GUID 12345
2529 * .wp add
2530 * -> adds a waypoint to the currently selected creature
2533 * @param args if the user did not provide a GUID, it is NULL
2535 * @return true - command did succeed, false - something went wrong
2537 bool ChatHandler::HandleWpAddCommand(const char* args)
2539 sLog.outDebug("DEBUG: HandleWpAddCommand");
2541 // optional
2542 char* guid_str = NULL;
2544 if(*args)
2546 guid_str = strtok((char*)args, " ");
2549 uint32 lowguid = 0;
2550 uint32 point = 0;
2551 Creature* target = getSelectedCreature();
2552 // Did player provide a GUID?
2553 if (!guid_str)
2555 sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2557 // No GUID provided
2558 // -> Player must have selected a creature
2560 if(!target || target->isPet())
2562 SendSysMessage(LANG_SELECT_CREATURE);
2563 SetSentErrorMessage(true);
2564 return false;
2566 if (target->GetEntry() == VISUAL_WAYPOINT )
2568 sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2570 QueryResult *result =
2571 WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2572 target->GetGUIDLow() );
2573 if(!result)
2575 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
2576 // User selected a visual spawnpoint -> get the NPC
2577 // Select NPC GUID
2578 // Since we compare float values, we have to deal with
2579 // some difficulties.
2580 // Here we search for all waypoints that only differ in one from 1 thousand
2581 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2582 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2583 const char* maxDIFF = "0.01";
2584 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 )",
2585 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2586 if(!result)
2588 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
2589 SetSentErrorMessage(true);
2590 return false;
2595 Field *fields = result->Fetch();
2596 lowguid = fields[0].GetUInt32();
2597 point = fields[1].GetUInt32();
2598 }while( result->NextRow() );
2599 delete result;
2601 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2602 if(!data)
2604 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2605 SetSentErrorMessage(true);
2606 return false;
2609 target = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2610 if(!target)
2612 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2613 SetSentErrorMessage(true);
2614 return false;
2617 else
2619 lowguid = target->GetDBTableGUIDLow();
2622 else
2624 sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2626 // GUID provided
2627 // Warn if player also selected a creature
2628 // -> Creature selection is ignored <-
2629 if(target)
2631 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2633 lowguid = atoi((char*)guid_str);
2635 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2636 if(!data)
2638 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2639 SetSentErrorMessage(true);
2640 return false;
2643 target = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2644 if(!target || target->isPet())
2646 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2647 SetSentErrorMessage(true);
2648 return false;
2651 // lowguid -> GUID of the NPC
2652 // point -> number of the waypoint (if not 0)
2653 sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
2655 sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2657 Player* player = m_session->GetPlayer();
2658 WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
2660 // update movement type
2661 if(target)
2663 target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2664 target->GetMotionMaster()->Initialize();
2665 if(target->isAlive()) // dead creature will reset movement generator at respawn
2667 target->setDeathState(JUST_DIED);
2668 target->Respawn();
2670 target->SaveToDB();
2672 else
2673 WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
2675 PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
2677 return true;
2678 } // HandleWpAddCommand
2681 * .wp modify emote | spell | text | del | move | add
2683 * add -> add a WP after the selected visual waypoint
2684 * User must select a visual waypoint and then issue ".wp modify add"
2686 * emote <emoteID>
2687 * User has selected a visual waypoint before.
2688 * <emoteID> is added to this waypoint. Everytime the
2689 * NPC comes to this waypoint, the emote is called.
2691 * emote <GUID> <WPNUM> <emoteID>
2692 * User has not selected visual waypoint before.
2693 * For the waypoint <WPNUM> for the NPC with <GUID>
2694 * an emote <emoteID> is added.
2695 * Everytime the NPC comes to this waypoint, the emote is called.
2698 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2700 bool ChatHandler::HandleWpModifyCommand(const char* args)
2702 sLog.outDebug("DEBUG: HandleWpModifyCommand");
2704 if(!*args)
2705 return false;
2707 // first arg: add del text emote spell waittime move
2708 char* show_str = strtok((char*)args, " ");
2709 if (!show_str)
2711 return false;
2714 std::string show = show_str;
2715 // Check
2716 // Remember: "show" must also be the name of a column!
2717 if( (show != "emote") && (show != "spell") && (show != "textid1") && (show != "textid2")
2718 && (show != "textid3") && (show != "textid4") && (show != "textid5")
2719 && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
2720 && (show != "model1") && (show != "model2") && (show != "orientation"))
2722 return false;
2725 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2727 // Did user provide a GUID
2728 // or did the user select a creature?
2729 // -> variable lowguid is filled with the GUID of the NPC
2730 uint32 lowguid = 0;
2731 uint32 point = 0;
2732 uint32 wpGuid = 0;
2733 Creature* target = getSelectedCreature();
2735 if(target)
2737 sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2739 // Did the user select a visual spawnpoint?
2740 if (target->GetEntry() != VISUAL_WAYPOINT )
2742 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2743 SetSentErrorMessage(true);
2744 return false;
2747 wpGuid = target->GetGUIDLow();
2749 // The visual waypoint
2750 QueryResult *result =
2751 WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2752 target->GetGUIDLow() );
2753 if(!result)
2755 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
2756 SetSentErrorMessage(true);
2757 return false;
2759 sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2761 Field *fields = result->Fetch();
2762 lowguid = fields[0].GetUInt32();
2763 point = fields[1].GetUInt32();
2765 // Cleanup memory
2766 sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2767 delete result;
2769 else
2771 // User did provide <GUID> <WPNUM>
2773 char* guid_str = strtok((char*)NULL, " ");
2774 if( !guid_str )
2776 SendSysMessage(LANG_WAYPOINT_NOGUID);
2777 return false;
2779 lowguid = atoi((char*)guid_str);
2781 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2782 if(!data)
2784 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2785 SetSentErrorMessage(true);
2786 return false;
2789 PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2791 char* point_str = strtok((char*)NULL, " ");
2792 if( !point_str )
2794 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2795 return false;
2797 point = atoi((char*)point_str);
2799 PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2801 // Now we need the GUID of the visual waypoint
2802 // -> "del", "move", "add" command
2804 QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
2805 if (!result)
2807 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2808 SetSentErrorMessage(true);
2809 return false;
2812 Field *fields = result->Fetch();
2813 wpGuid = fields[0].GetUInt32();
2815 // Free memory
2816 delete result;
2819 char* arg_str = NULL;
2820 // Check for argument
2821 if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
2823 // Text is enclosed in "<>", all other arguments not
2824 if( show.find("text") != std::string::npos )
2825 arg_str = strtok((char*)NULL, "<>");
2826 else
2827 arg_str = strtok((char*)NULL, " ");
2829 if( !arg_str)
2831 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2832 return false;
2836 sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2838 // wpGuid -> GUID of the waypoint creature
2839 // lowguid -> GUID of the NPC
2840 // point -> waypoint number
2842 // Special functions:
2843 // add - move - del -> no args commands
2844 // Add a waypoint after the selected visual
2845 if(show == "add" && target)
2847 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2849 // Get the creature for which we read the waypoint
2850 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2851 if(!data)
2853 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2854 SetSentErrorMessage(true);
2855 return false;
2858 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2860 if( !npcCreature )
2862 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2863 SetSentErrorMessage(true);
2864 return false;
2867 sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2869 // What to do:
2870 // Add the visual spawnpoint (DB only)
2871 // Adjust the waypoints
2872 // Respawn the owner of the waypoints
2873 sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
2875 Player* chr = m_session->GetPlayer();
2876 Map *map = chr->GetMap();
2878 if(npcCreature)
2880 npcCreature->GetMotionMaster()->Initialize();
2881 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2883 npcCreature->setDeathState(JUST_DIED);
2884 npcCreature->Respawn();
2888 // create the waypoint creature
2889 wpGuid = 0;
2890 Creature* wpCreature = new Creature;
2891 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT,0))
2893 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2894 delete wpCreature;
2896 else
2898 wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2900 if(!wpCreature->IsPositionValid())
2902 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());
2903 delete wpCreature;
2905 else
2907 wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
2908 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2909 wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
2910 map->Add(wpCreature);
2911 wpGuid = wpCreature->GetGUIDLow();
2915 WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
2917 if(!wpGuid)
2918 return false;
2920 PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2921 return true;
2922 } // add
2924 if(show == "del" && target)
2926 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2928 // Get the creature for which we read the waypoint
2929 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2930 if(!data)
2932 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2933 SetSentErrorMessage(true);
2934 return false;
2937 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2939 // wpCreature
2940 Creature* wpCreature = NULL;
2941 if( wpGuid != 0 )
2943 wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2944 wpCreature->DeleteFromDB();
2945 wpCreature->CleanupsBeforeDelete();
2946 wpCreature->AddObjectToRemoveList();
2949 // What to do:
2950 // Remove the visual spawnpoint
2951 // Adjust the waypoints
2952 // Respawn the owner of the waypoints
2954 WaypointMgr.DeleteNode(lowguid, point);
2956 if(npcCreature)
2958 // Any waypoints left?
2959 QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
2960 if(!result2)
2962 npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2964 else
2966 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2967 delete result2;
2969 npcCreature->GetMotionMaster()->Initialize();
2970 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2972 npcCreature->setDeathState(JUST_DIED);
2973 npcCreature->Respawn();
2975 npcCreature->SaveToDB();
2978 PSendSysMessage(LANG_WAYPOINT_REMOVED);
2979 return true;
2980 } // del
2982 if(show == "move" && target)
2984 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2986 Player *chr = m_session->GetPlayer();
2987 Map *map = chr->GetMap();
2989 // Get the creature for which we read the waypoint
2990 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2991 if(!data)
2993 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2994 SetSentErrorMessage(true);
2995 return false;
2998 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
3000 // wpCreature
3001 Creature* wpCreature = NULL;
3002 // What to do:
3003 // Move the visual spawnpoint
3004 // Respawn the owner of the waypoints
3005 if( wpGuid != 0 )
3007 wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
3008 wpCreature->DeleteFromDB();
3009 wpCreature->CleanupsBeforeDelete();
3010 wpCreature->AddObjectToRemoveList();
3011 // re-create
3012 Creature* wpCreature2 = new Creature;
3013 if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))
3015 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
3016 delete wpCreature2;
3017 return false;
3020 wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
3022 if(!wpCreature2->IsPositionValid())
3024 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());
3025 delete wpCreature2;
3026 return false;
3029 wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3030 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3031 wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
3032 map->Add(wpCreature2);
3033 //npcCreature->GetMap()->Add(wpCreature2);
3036 WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
3038 if(npcCreature)
3040 npcCreature->GetMotionMaster()->Initialize();
3041 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
3043 npcCreature->setDeathState(JUST_DIED);
3044 npcCreature->Respawn();
3047 PSendSysMessage(LANG_WAYPOINT_CHANGED);
3049 return true;
3050 } // move
3052 // Create creature - npc that has the waypoint
3053 CreatureData const* data = objmgr.GetCreatureData(lowguid);
3054 if(!data)
3056 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
3057 SetSentErrorMessage(true);
3058 return false;
3061 // set in game textids not supported
3062 if( show == "textid1" || show == "textid2" || show == "textid3" ||
3063 show == "textid4" || show == "textid5" )
3065 return false;
3068 WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
3070 Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
3071 if(npcCreature)
3073 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
3074 npcCreature->GetMotionMaster()->Initialize();
3075 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
3077 npcCreature->setDeathState(JUST_DIED);
3078 npcCreature->Respawn();
3081 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
3083 return true;
3087 * .wp show info | on | off
3089 * info -> User has selected a visual waypoint before
3091 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
3092 * provided the GUID of the NPC and the number of
3093 * the waypoint.
3095 * on -> User has selected an NPC; all visual waypoints for this
3096 * NPC are added to the world
3098 * on <GUID> -> User did not select an NPC - instead the GUID of the
3099 * NPC is provided. All visual waypoints for this NPC
3100 * are added from the world.
3102 * off -> User has selected an NPC; all visual waypoints for this
3103 * NPC are removed from the world.
3105 * on <GUID> -> User did not select an NPC - instead the GUID of the
3106 * NPC is provided. All visual waypoints for this NPC
3107 * are removed from the world.
3111 bool ChatHandler::HandleWpShowCommand(const char* args)
3113 sLog.outDebug("DEBUG: HandleWpShowCommand");
3115 if(!*args)
3116 return false;
3118 // first arg: on, off, first, last
3119 char* show_str = strtok((char*)args, " ");
3120 if (!show_str)
3122 return false;
3124 // second arg: GUID (optional, if a creature is selected)
3125 char* guid_str = strtok((char*)NULL, " ");
3126 sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
3127 //if (!guid_str) {
3128 // return false;
3131 // Did user provide a GUID
3132 // or did the user select a creature?
3133 // -> variable lowguid is filled with the GUID
3134 Creature* target = getSelectedCreature();
3135 // Did player provide a GUID?
3136 if (!guid_str)
3138 sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
3139 // No GUID provided
3140 // -> Player must have selected a creature
3142 if(!target)
3144 SendSysMessage(LANG_SELECT_CREATURE);
3145 SetSentErrorMessage(true);
3146 return false;
3149 else
3151 sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
3152 // GUID provided
3153 // Warn if player also selected a creature
3154 // -> Creature selection is ignored <-
3155 if(target)
3157 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
3160 uint32 lowguid = atoi((char*)guid_str);
3162 CreatureData const* data = objmgr.GetCreatureData(lowguid);
3163 if(!data)
3165 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
3166 SetSentErrorMessage(true);
3167 return false;
3170 target = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
3172 if(!target)
3174 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
3175 SetSentErrorMessage(true);
3176 return false;
3180 uint32 lowguid = target->GetDBTableGUIDLow();
3182 std::string show = show_str;
3183 uint32 Maxpoint;
3185 sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid, show_str);
3187 // Show info for the selected waypoint
3188 if(show == "info")
3190 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
3192 // Check if the user did specify a visual waypoint
3193 if( target->GetEntry() != VISUAL_WAYPOINT )
3195 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
3196 SetSentErrorMessage(true);
3197 return false;
3200 //PSendSysMessage("wp on, GUID: %u", lowguid);
3202 //pCreature->GetPositionX();
3204 QueryResult *result =
3205 WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
3206 target->GetGUIDLow() );
3207 if(!result)
3209 // Since we compare float values, we have to deal with
3210 // some difficulties.
3211 // Here we search for all waypoints that only differ in one from 1 thousand
3212 // (0.001) - There is no other way to compare C++ floats with mySQL floats
3213 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
3214 const char* maxDIFF = "0.01";
3215 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
3217 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 )",
3218 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
3219 if(!result)
3221 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
3222 SetSentErrorMessage(true);
3223 return false;
3228 Field *fields = result->Fetch();
3229 uint32 creGUID = fields[0].GetUInt32();
3230 uint32 point = fields[1].GetUInt32();
3231 int waittime = fields[2].GetUInt32();
3232 uint32 emote = fields[3].GetUInt32();
3233 uint32 spell = fields[4].GetUInt32();
3234 uint32 textid[MAX_WAYPOINT_TEXT];
3235 for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
3236 textid[i] = fields[5+i].GetUInt32();
3237 uint32 model1 = fields[10].GetUInt32();
3238 uint32 model2 = fields[11].GetUInt32();
3240 // Get the creature for which we read the waypoint
3241 Creature* wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3243 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
3244 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
3245 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
3246 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
3247 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
3248 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
3249 for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
3250 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, i+1, textid[i], (textid[i] ? GetMangosString(textid[i]) : ""));
3252 }while( result->NextRow() );
3253 // Cleanup memory
3254 delete result;
3255 return true;
3258 if(show == "on")
3260 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
3262 QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
3263 if(!result)
3265 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3266 SetSentErrorMessage(true);
3267 return false;
3269 // Delete all visuals for this NPC
3270 QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
3271 if(result2)
3273 bool hasError = false;
3276 Field *fields = result2->Fetch();
3277 uint32 wpguid = fields[0].GetUInt32();
3278 Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3280 if(!pCreature)
3282 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
3283 hasError = true;
3284 WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
3286 else
3288 pCreature->DeleteFromDB();
3289 pCreature->CleanupsBeforeDelete();
3290 pCreature->AddObjectToRemoveList();
3293 }while( result2->NextRow() );
3294 delete result2;
3295 if( hasError )
3297 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3298 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3299 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3305 Field *fields = result->Fetch();
3306 uint32 point = fields[0].GetUInt32();
3307 float x = fields[1].GetFloat();
3308 float y = fields[2].GetFloat();
3309 float z = fields[3].GetFloat();
3311 uint32 id = VISUAL_WAYPOINT;
3313 Player *chr = m_session->GetPlayer();
3314 Map *map = chr->GetMap();
3315 float o = chr->GetOrientation();
3317 Creature* wpCreature = new Creature;
3318 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
3320 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3321 delete wpCreature;
3322 delete result;
3323 return false;
3326 wpCreature->Relocate(x, y, z, o);
3328 if(!wpCreature->IsPositionValid())
3330 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());
3331 delete wpCreature;
3332 delete result;
3333 return false;
3336 wpCreature->SetVisibility(VISIBILITY_OFF);
3337 sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3338 // set "wpguid" column to the visual waypoint
3339 WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
3341 wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3342 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3343 wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
3344 map->Add(wpCreature);
3345 //wpCreature->GetMap()->Add(wpCreature);
3346 }while( result->NextRow() );
3348 // Cleanup memory
3349 delete result;
3350 return true;
3353 if(show == "first")
3355 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3357 QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3358 if(!result)
3360 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3361 SetSentErrorMessage(true);
3362 return false;
3365 Field *fields = result->Fetch();
3366 float x = fields[0].GetFloat();
3367 float y = fields[1].GetFloat();
3368 float z = fields[2].GetFloat();
3369 uint32 id = VISUAL_WAYPOINT;
3371 Player *chr = m_session->GetPlayer();
3372 float o = chr->GetOrientation();
3373 Map *map = chr->GetMap();
3375 Creature* pCreature = new Creature;
3376 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))
3378 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3379 delete pCreature;
3380 delete result;
3381 return false;
3384 pCreature->Relocate(x, y, z, o);
3386 if(!pCreature->IsPositionValid())
3388 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());
3389 delete pCreature;
3390 delete result;
3391 return false;
3394 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3395 pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3396 map->Add(pCreature);
3397 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3399 // Cleanup memory
3400 delete result;
3401 return true;
3404 if(show == "last")
3406 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3408 QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3409 if( result )
3411 Maxpoint = (*result)[0].GetUInt32();
3413 delete result;
3415 else
3416 Maxpoint = 0;
3418 result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3419 if(!result)
3421 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3422 SetSentErrorMessage(true);
3423 return false;
3425 Field *fields = result->Fetch();
3426 float x = fields[0].GetFloat();
3427 float y = fields[1].GetFloat();
3428 float z = fields[2].GetFloat();
3429 uint32 id = VISUAL_WAYPOINT;
3431 Player *chr = m_session->GetPlayer();
3432 float o = chr->GetOrientation();
3433 Map *map = chr->GetMap();
3435 Creature* pCreature = new Creature;
3436 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
3438 PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3439 delete pCreature;
3440 delete result;
3441 return false;
3444 pCreature->Relocate(x, y, z, o);
3446 if(!pCreature->IsPositionValid())
3448 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());
3449 delete pCreature;
3450 delete result;
3451 return false;
3454 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
3455 pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3456 map->Add(pCreature);
3457 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3458 // Cleanup memory
3459 delete result;
3460 return true;
3463 if(show == "off")
3465 QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3466 if(!result)
3468 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3469 SetSentErrorMessage(true);
3470 return false;
3472 bool hasError = false;
3475 Field *fields = result->Fetch();
3476 uint32 guid = fields[0].GetUInt32();
3477 Creature* pCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3478 if(!pCreature)
3480 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3481 hasError = true;
3482 WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3484 else
3486 pCreature->DeleteFromDB();
3487 pCreature->CleanupsBeforeDelete();
3488 pCreature->AddObjectToRemoveList();
3490 }while(result->NextRow());
3491 // set "wpguid" column to "empty" - no visual waypoint spawned
3492 WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3494 if( hasError )
3496 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3497 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3498 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3501 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3502 // Cleanup memory
3503 delete result;
3505 return true;
3508 PSendSysMessage("DEBUG: wpshow - no valid command found");
3510 return true;
3511 } // HandleWpShowCommand
3513 bool ChatHandler::HandleWpExportCommand(const char *args)
3515 if(!*args)
3516 return false;
3518 // Next arg is: <GUID> <ARGUMENT>
3520 // Did user provide a GUID
3521 // or did the user select a creature?
3522 // -> variable lowguid is filled with the GUID of the NPC
3523 uint32 lowguid = 0;
3524 Creature* target = getSelectedCreature();
3525 char* arg_str = NULL;
3526 if (target)
3528 if (target->GetEntry() != VISUAL_WAYPOINT)
3529 lowguid = target->GetGUIDLow();
3530 else
3532 QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3533 if (!result)
3535 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3536 return true;
3538 Field *fields = result->Fetch();
3539 lowguid = fields[0].GetUInt32();;
3540 delete result;
3543 arg_str = strtok((char*)args, " ");
3545 else
3547 // user provided <GUID>
3548 char* guid_str = strtok((char*)args, " ");
3549 if( !guid_str )
3551 SendSysMessage(LANG_WAYPOINT_NOGUID);
3552 return false;
3554 lowguid = atoi((char*)guid_str);
3556 arg_str = strtok((char*)NULL, " ");
3559 if( !arg_str)
3561 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3562 return false;
3565 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3567 QueryResult *result = WorldDatabase.PQuery(
3568 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3569 "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 );
3571 if (!result)
3573 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3574 SetSentErrorMessage(true);
3575 return false;
3578 std::ofstream outfile;
3579 outfile.open (arg_str);
3583 Field *fields = result->Fetch();
3585 outfile << "INSERT INTO creature_movement ";
3586 outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3588 outfile << "( ";
3589 outfile << fields[15].GetUInt32(); // id
3590 outfile << ", ";
3591 outfile << fields[0].GetUInt32(); // point
3592 outfile << ", ";
3593 outfile << fields[1].GetFloat(); // position_x
3594 outfile << ", ";
3595 outfile << fields[2].GetFloat(); // position_y
3596 outfile << ", ";
3597 outfile << fields[3].GetUInt32(); // position_z
3598 outfile << ", ";
3599 outfile << fields[4].GetUInt32(); // orientation
3600 outfile << ", ";
3601 outfile << fields[5].GetUInt32(); // model1
3602 outfile << ", ";
3603 outfile << fields[6].GetUInt32(); // model2
3604 outfile << ", ";
3605 outfile << fields[7].GetUInt16(); // waittime
3606 outfile << ", ";
3607 outfile << fields[8].GetUInt32(); // emote
3608 outfile << ", ";
3609 outfile << fields[9].GetUInt32(); // spell
3610 outfile << ", ";
3611 outfile << fields[10].GetUInt32(); // textid1
3612 outfile << ", ";
3613 outfile << fields[11].GetUInt32(); // textid2
3614 outfile << ", ";
3615 outfile << fields[12].GetUInt32(); // textid3
3616 outfile << ", ";
3617 outfile << fields[13].GetUInt32(); // textid4
3618 outfile << ", ";
3619 outfile << fields[14].GetUInt32(); // textid5
3620 outfile << ");\n ";
3622 } while( result->NextRow() );
3623 delete result;
3625 PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3626 outfile.close();
3628 return true;
3631 bool ChatHandler::HandleWpImportCommand(const char *args)
3633 if(!*args)
3634 return false;
3636 char* arg_str = strtok((char*)args, " ");
3637 if (!arg_str)
3638 return false;
3640 std::string line;
3641 std::ifstream infile (arg_str);
3642 if (infile.is_open())
3644 while (! infile.eof() )
3646 getline (infile,line);
3647 //cout << line << endl;
3648 QueryResult *result = WorldDatabase.Query(line.c_str());
3649 delete result;
3651 infile.close();
3653 PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3655 return true;
3658 //rename characters
3659 bool ChatHandler::HandleRenameCommand(const char* args)
3661 Player* target = NULL;
3662 uint64 targetGUID = 0;
3663 std::string oldname;
3665 char* px = strtok((char*)args, " ");
3667 if(px)
3669 oldname = extractPlayerNameFromLink(px);
3670 if(oldname.empty())
3672 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3673 SetSentErrorMessage(true);
3674 return false;
3677 target = objmgr.GetPlayer(oldname.c_str());
3679 if (!target)
3680 targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3683 if(!target && !targetGUID)
3685 target = getSelectedPlayer();
3688 if(!target && !targetGUID)
3690 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3691 SetSentErrorMessage(true);
3692 return false;
3695 if(target)
3697 // check online security
3698 if (HasLowerSecurity(target, 0))
3699 return false;
3701 PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());
3702 target->SetAtLoginFlag(AT_LOGIN_RENAME);
3703 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3705 else
3707 // check offline security
3708 if (HasLowerSecurity(NULL, targetGUID))
3709 return false;
3711 std::string oldNameLink = playerLink(oldname);
3713 PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));
3714 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3717 return true;
3720 // customize characters
3721 bool ChatHandler::HandleCustomizeCommand(const char* args)
3723 Player* target = NULL;
3724 uint64 targetGUID = 0;
3725 std::string oldname;
3727 char* px = strtok((char*)args, " ");
3729 if(px)
3731 oldname = extractPlayerNameFromLink(px);
3732 if(oldname.empty())
3734 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3735 SetSentErrorMessage(true);
3736 return false;
3739 target = objmgr.GetPlayer(oldname.c_str());
3741 if (!target)
3742 targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3745 if(!target && !targetGUID)
3747 target = getSelectedPlayer();
3750 if(!target && !targetGUID)
3752 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3753 SetSentErrorMessage(true);
3754 return false;
3757 if(target)
3759 PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
3760 target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
3761 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
3763 else
3765 std::string oldNameLink = playerLink(oldname);
3767 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID));
3768 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3771 return true;
3774 //change standstate
3775 bool ChatHandler::HandleModifyStandStateCommand(const char* args)
3777 if (!*args)
3778 return false;
3780 uint32 anim_id = atoi((char*)args);
3781 m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3783 return true;
3786 bool ChatHandler::HandleHonorAddCommand(const char* args)
3788 if (!*args)
3789 return false;
3791 Player *target = getSelectedPlayer();
3792 if(!target)
3794 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3795 SetSentErrorMessage(true);
3796 return false;
3799 // check online security
3800 if (HasLowerSecurity(target, 0))
3801 return false;
3803 uint32 amount = (uint32)atoi(args);
3804 target->RewardHonor(NULL, 1, amount);
3805 return true;
3808 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3810 Unit *target = getSelectedUnit();
3811 if(!target)
3813 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3814 SetSentErrorMessage(true);
3815 return false;
3818 // check online security
3819 if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0))
3820 return false;
3822 m_session->GetPlayer()->RewardHonor(target, 1);
3823 return true;
3826 bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
3828 Player *target = getSelectedPlayer();
3829 if(!target)
3831 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3832 SetSentErrorMessage(true);
3833 return false;
3836 // check online security
3837 if (HasLowerSecurity(target, 0))
3838 return false;
3840 target->UpdateHonorFields();
3841 return true;
3844 bool ChatHandler::HandleLookupEventCommand(const char* args)
3846 if(!*args)
3847 return false;
3849 std::string namepart = args;
3850 std::wstring wnamepart;
3852 // converting string that we try to find to lower case
3853 if(!Utf8toWStr(namepart,wnamepart))
3854 return false;
3856 wstrToLower(wnamepart);
3858 uint32 counter = 0;
3860 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3861 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3863 for(uint32 id = 0; id < events.size(); ++id )
3865 GameEventData const& eventData = events[id];
3867 std::string descr = eventData.description;
3868 if(descr.empty())
3869 continue;
3871 if (Utf8FitTo(descr, wnamepart))
3873 char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : "";
3875 if(m_session)
3876 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
3877 else
3878 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
3880 ++counter;
3884 if (counter==0)
3885 SendSysMessage(LANG_NOEVENTFOUND);
3887 return true;
3890 bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
3892 uint32 counter = 0;
3894 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3895 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3897 char const* active = GetMangosString(LANG_ACTIVE);
3899 for(GameEventMgr::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3901 uint32 event_id = *itr;
3902 GameEventData const& eventData = events[event_id];
3904 if(m_session)
3905 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
3906 else
3907 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
3909 ++counter;
3912 if (counter==0)
3913 SendSysMessage(LANG_NOEVENTFOUND);
3915 return true;
3918 bool ChatHandler::HandleEventInfoCommand(const char* args)
3920 if(!*args)
3921 return false;
3923 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3924 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3925 if(!cId)
3926 return false;
3928 uint32 event_id = atoi(cId);
3930 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3932 if(event_id >=events.size())
3934 SendSysMessage(LANG_EVENT_NOT_EXIST);
3935 SetSentErrorMessage(true);
3936 return false;
3939 GameEventData const& eventData = events[event_id];
3940 if(!eventData.isValid())
3942 SendSysMessage(LANG_EVENT_NOT_EXIST);
3943 SetSentErrorMessage(true);
3944 return false;
3947 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3948 bool active = activeEvents.find(event_id) != activeEvents.end();
3949 char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : "";
3951 std::string startTimeStr = TimeToTimestampStr(eventData.start);
3952 std::string endTimeStr = TimeToTimestampStr(eventData.end);
3954 uint32 delay = gameeventmgr.NextCheck(event_id);
3955 time_t nextTime = time(NULL)+delay;
3956 std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3958 std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3959 std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3961 PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3962 startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3963 nextStr.c_str());
3964 return true;
3967 bool ChatHandler::HandleEventStartCommand(const char* args)
3969 if(!*args)
3970 return false;
3972 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3973 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3974 if(!cId)
3975 return false;
3977 int32 event_id = atoi(cId);
3979 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3981 if(event_id < 1 || event_id >=events.size())
3983 SendSysMessage(LANG_EVENT_NOT_EXIST);
3984 SetSentErrorMessage(true);
3985 return false;
3988 GameEventData const& eventData = events[event_id];
3989 if(!eventData.isValid())
3991 SendSysMessage(LANG_EVENT_NOT_EXIST);
3992 SetSentErrorMessage(true);
3993 return false;
3996 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3997 if(activeEvents.find(event_id) != activeEvents.end())
3999 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
4000 SetSentErrorMessage(true);
4001 return false;
4004 gameeventmgr.StartEvent(event_id,true);
4005 return true;
4008 bool ChatHandler::HandleEventStopCommand(const char* args)
4010 if(!*args)
4011 return false;
4013 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
4014 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
4015 if(!cId)
4016 return false;
4018 int32 event_id = atoi(cId);
4020 GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap();
4022 if(event_id < 1 || event_id >=events.size())
4024 SendSysMessage(LANG_EVENT_NOT_EXIST);
4025 SetSentErrorMessage(true);
4026 return false;
4029 GameEventData const& eventData = events[event_id];
4030 if(!eventData.isValid())
4032 SendSysMessage(LANG_EVENT_NOT_EXIST);
4033 SetSentErrorMessage(true);
4034 return false;
4037 GameEventMgr::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
4039 if(activeEvents.find(event_id) == activeEvents.end())
4041 PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
4042 SetSentErrorMessage(true);
4043 return false;
4046 gameeventmgr.StopEvent(event_id,true);
4047 return true;
4050 bool ChatHandler::HandleCombatStopCommand(const char* args)
4052 Player *player;
4054 if(*args)
4056 std::string playername = extractPlayerNameFromLink((char*)args);
4057 if(playername.empty())
4059 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4060 SetSentErrorMessage(true);
4061 return false;
4064 player = objmgr.GetPlayer(playername.c_str());
4066 if(!player)
4068 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4069 SetSentErrorMessage(true);
4070 return false;
4073 else
4075 player = getSelectedPlayer();
4077 if (!player)
4078 player = m_session->GetPlayer();
4081 // check online security
4082 if (HasLowerSecurity(player, 0))
4083 return false;
4085 player->CombatStop();
4086 player->getHostilRefManager().deleteReferences();
4087 return true;
4090 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
4092 uint32 classmask = m_session->GetPlayer()->getClassMask();
4094 for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
4096 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
4097 if( !skillInfo )
4098 continue;
4100 if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
4102 for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
4104 SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
4105 if( !skillLine )
4106 continue;
4108 // skip racial skills
4109 if( skillLine->racemask != 0 )
4110 continue;
4112 // skip wrong class skills
4113 if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
4114 continue;
4116 if( skillLine->skillId != i || skillLine->forward_spellid )
4117 continue;
4119 SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
4120 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
4121 continue;
4123 m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
4128 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
4129 return true;
4132 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
4134 // Learns all recipes of specified profession and sets skill to max
4135 // Example: .learn all_recipes enchanting
4137 Player* target = getSelectedPlayer();
4138 if( !target )
4140 SendSysMessage(LANG_PLAYER_NOT_FOUND);
4141 return false;
4144 if(!*args)
4145 return false;
4147 std::wstring wnamepart;
4149 if(!Utf8toWStr(args,wnamepart))
4150 return false;
4152 // converting string that we try to find to lower case
4153 wstrToLower( wnamepart );
4155 uint32 classmask = m_session->GetPlayer()->getClassMask();
4157 for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
4159 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
4160 if( !skillInfo )
4161 continue;
4163 if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
4164 skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
4165 continue;
4167 int loc = m_session->GetSessionDbcLocale();
4168 std::string name = skillInfo->name[loc];
4170 if(Utf8FitTo(name, wnamepart))
4172 for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
4174 SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
4175 if( !skillLine )
4176 continue;
4178 if( skillLine->skillId != i || skillLine->forward_spellid )
4179 continue;
4181 // skip racial skills
4182 if( skillLine->racemask != 0 )
4183 continue;
4185 // skip wrong class skills
4186 if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
4187 continue;
4189 SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
4190 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
4191 continue;
4193 if( !target->HasSpell(spellInfo->Id) )
4194 m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
4197 uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
4198 target->SetSkill(skillInfo->id, maxLevel, maxLevel);
4199 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
4200 return true;
4204 return false;
4207 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
4210 if (!*args)
4211 return false;
4213 std::string ip = strtok ((char*)args, " ");
4214 char* limit_str = strtok (NULL, " ");
4215 int32 limit = limit_str ? atoi (limit_str) : -1;
4217 loginDatabase.escape_string (ip);
4219 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
4221 return LookupPlayerSearchCommand (result,limit);
4224 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
4226 if (!*args)
4227 return false;
4229 std::string account = strtok ((char*)args, " ");
4230 char* limit_str = strtok (NULL, " ");
4231 int32 limit = limit_str ? atoi (limit_str) : -1;
4233 if (!AccountMgr::normilizeString (account))
4234 return false;
4236 loginDatabase.escape_string (account);
4238 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
4240 return LookupPlayerSearchCommand (result,limit);
4243 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
4246 if (!*args)
4247 return false;
4249 std::string email = strtok ((char*)args, " ");
4250 char* limit_str = strtok (NULL, " ");
4251 int32 limit = limit_str ? atoi (limit_str) : -1;
4253 loginDatabase.escape_string (email);
4255 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
4257 return LookupPlayerSearchCommand (result,limit);
4260 bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
4262 if(!result)
4264 PSendSysMessage(LANG_NO_PLAYERS_FOUND);
4265 SetSentErrorMessage(true);
4266 return false;
4269 int i =0;
4272 Field* fields = result->Fetch();
4273 uint32 acc_id = fields[0].GetUInt32();
4274 std::string acc_name = fields[1].GetCppString();
4276 QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
4277 if(chars)
4279 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
4281 uint64 guid = 0;
4282 std::string name;
4286 Field* charfields = chars->Fetch();
4287 guid = charfields[0].GetUInt64();
4288 name = charfields[1].GetCppString();
4290 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
4291 ++i;
4293 } while( chars->NextRow() && ( limit == -1 || i < limit ) );
4295 delete chars;
4297 } while(result->NextRow());
4299 delete result;
4301 if(i==0) // empty accounts only
4303 PSendSysMessage(LANG_NO_PLAYERS_FOUND);
4304 SetSentErrorMessage(true);
4305 return false;
4308 return true;
4311 /// Triggering corpses expire check in world
4312 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4314 CorpsesErase();
4315 return true;
4318 bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
4320 Player *target = getSelectedPlayer();
4322 if(!target)
4324 PSendSysMessage(LANG_NO_CHAR_SELECTED);
4325 SetSentErrorMessage(true);
4326 return false;
4329 // check online security
4330 if (HasLowerSecurity(target, 0))
4331 return false;
4333 // Repair items
4334 target->DurabilityRepairAll(false, 0, false);
4336 PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str());
4337 if(needReportToTarget(target))
4338 ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str());
4339 return true;
4342 bool ChatHandler::HandleWaterwalkCommand(const char* args)
4344 if(!*args)
4345 return false;
4347 Player *player = getSelectedPlayer();
4349 if(!player)
4351 PSendSysMessage(LANG_NO_CHAR_SELECTED);
4352 SetSentErrorMessage(true);
4353 return false;
4356 // check online security
4357 if (HasLowerSecurity(player, 0))
4358 return false;
4360 if (strncmp(args, "on", 3) == 0)
4361 player->SetMovement(MOVE_WATER_WALK); // ON
4362 else if (strncmp(args, "off", 4) == 0)
4363 player->SetMovement(MOVE_LAND_WALK); // OFF
4364 else
4366 SendSysMessage(LANG_USE_BOL);
4367 return false;
4370 PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str());
4371 if(needReportToTarget(player))
4372 ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str());
4373 return true;