Finish review/fix commands appropriate for console. Allow call 'help' command without...
[auctionmangos.git] / src / game / Level2.cpp
blob8fa4b219c20b14ca6f05f62b50221950e737a4a3
1 /*
2 * Copyright (C) 2005-2008 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 "WorldPacket.h"
22 #include "WorldSession.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "Player.h"
26 #include "Item.h"
27 #include "GameObject.h"
28 #include "Opcodes.h"
29 #include "Chat.h"
30 #include "ObjectAccessor.h"
31 #include "MapManager.h"
32 #include "Language.h"
33 #include "World.h"
34 #include "GameEvent.h"
35 #include "SpellMgr.h"
36 #include "AccountMgr.h"
37 #include "WaypointManager.h"
38 #include "Util.h"
39 #include <cctype>
40 #include <iostream>
41 #include <fstream>
42 #include <map>
43 #include "GlobalEvents.h"
45 static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
47 LANG_REP_HATED, LANG_REP_HOSTILE, LANG_REP_UNFRIENDLY, LANG_REP_NEUTRAL,
48 LANG_REP_FRIENDLY, LANG_REP_HONORED, LANG_REP_REVERED, LANG_REP_EXALTED
51 //mute player for some times
52 bool ChatHandler::HandleMuteCommand(const char* args)
54 if (!*args)
55 return false;
57 char *charname = strtok((char*)args, " ");
58 if (!charname)
59 return false;
61 std::string cname = charname;
63 char *timetonotspeak = strtok(NULL, " ");
64 if(!timetonotspeak)
65 return false;
67 uint32 notspeaktime = (uint32) atoi(timetonotspeak);
69 if(!normalizePlayerName(cname))
71 SendSysMessage(LANG_PLAYER_NOT_FOUND);
72 SetSentErrorMessage(true);
73 return false;
76 uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
77 if(!guid)
79 SendSysMessage(LANG_PLAYER_NOT_FOUND);
80 SetSentErrorMessage(true);
81 return false;
84 Player *chr = objmgr.GetPlayer(guid);
86 // check security
87 uint32 account_id = 0;
88 uint32 security = 0;
90 if (chr)
92 account_id = chr->GetSession()->GetAccountId();
93 security = chr->GetSession()->GetSecurity();
95 else
97 account_id = objmgr.GetPlayerAccountIdByGUID(guid);
98 security = accmgr.GetSecurity(account_id);
101 if(m_session && security >= m_session->GetSecurity())
103 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
104 SetSentErrorMessage(true);
105 return false;
108 time_t mutetime = time(NULL) + notspeaktime*60;
110 if (chr)
111 chr->GetSession()->m_muteTime = mutetime;
113 loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
115 if(chr)
116 ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
118 PSendSysMessage(LANG_YOU_DISABLE_CHAT, cname.c_str(), notspeaktime);
120 return true;
123 //unmute player
124 bool ChatHandler::HandleUnmuteCommand(const char* args)
126 if (!*args)
127 return false;
129 char *charname = strtok((char*)args, " ");
130 if (!charname)
131 return false;
133 std::string cname = charname;
135 if(!normalizePlayerName(cname))
137 SendSysMessage(LANG_PLAYER_NOT_FOUND);
138 SetSentErrorMessage(true);
139 return false;
142 uint64 guid = objmgr.GetPlayerGUIDByName(cname.c_str());
143 if(!guid)
145 SendSysMessage(LANG_PLAYER_NOT_FOUND);
146 SetSentErrorMessage(true);
147 return false;
150 Player *chr = objmgr.GetPlayer(guid);
152 // check security
153 uint32 account_id = 0;
154 uint32 security = 0;
156 if (chr)
158 account_id = chr->GetSession()->GetAccountId();
159 security = chr->GetSession()->GetSecurity();
161 else
163 account_id = objmgr.GetPlayerAccountIdByGUID(guid);
164 security = accmgr.GetSecurity(account_id);
167 if(m_session && security >= m_session->GetSecurity())
169 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
170 SetSentErrorMessage(true);
171 return false;
174 if (chr)
176 if(chr->CanSpeak())
178 SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
179 SetSentErrorMessage(true);
180 return false;
183 chr->GetSession()->m_muteTime = 0;
186 loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
188 if(chr)
189 ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
191 PSendSysMessage(LANG_YOU_ENABLE_CHAT, cname.c_str());
192 return true;
195 bool ChatHandler::HandleTargetObjectCommand(const char* args)
197 Player* pl = m_session->GetPlayer();
198 QueryResult *result;
199 GameEvent::ActiveEvents const& activeEventsList = gameeventmgr.GetActiveEventList();
200 if(*args)
202 int32 id = atoi((char*)args);
203 if(id)
204 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",
205 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),id);
206 else
208 std::string name = args;
209 WorldDatabase.escape_string(name);
210 result = WorldDatabase.PQuery(
211 "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_ "
212 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
213 pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), pl->GetMapId(),name.c_str());
216 else
218 std::ostringstream eventFilter;
219 eventFilter << " AND (event IS NULL ";
220 bool initString = true;
222 for (GameEvent::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
224 if (initString)
226 eventFilter << "OR event IN (" <<*itr;
227 initString =false;
229 else
230 eventFilter << "," << *itr;
233 if (!initString)
234 eventFilter << "))";
235 else
236 eventFilter << ")";
238 result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
239 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
240 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
241 m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetMapId(),eventFilter.str().c_str());
244 if (!result)
246 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND);
247 return true;
250 Field *fields = result->Fetch();
251 uint32 lowguid = fields[0].GetUInt32();
252 uint32 id = fields[1].GetUInt32();
253 float x = fields[2].GetFloat();
254 float y = fields[3].GetFloat();
255 float z = fields[4].GetFloat();
256 float o = fields[5].GetFloat();
257 int mapid = fields[6].GetUInt16();
258 delete result;
260 GameObjectInfo const* goI = objmgr.GetGameObjectInfo(id);
262 if (!goI)
264 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
265 return false;
268 GameObject* target = ObjectAccessor::GetGameObject(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,id,HIGHGUID_GAMEOBJECT));
270 PSendSysMessage(LANG_GAMEOBJECT_DETAIL, lowguid, goI->name, lowguid, id, x, y, z, mapid, o);
272 if(target)
274 int32 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL);
275 if(curRespawnDelay < 0)
276 curRespawnDelay = 0;
278 std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay,true);
279 std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true);
281 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str());
283 return true;
286 //teleport to gameobject
287 bool ChatHandler::HandleGoObjectCommand(const char* args)
289 if(!*args)
290 return false;
292 Player* _player = m_session->GetPlayer();
294 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
295 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
296 if(!cId)
297 return false;
299 int32 guid = atoi(cId);
300 if(!guid)
301 return false;
303 float x, y, z, ort;
304 int mapid;
306 // by DB guid
307 if (GameObjectData const* go_data = objmgr.GetGOData(guid))
309 x = go_data->posX;
310 y = go_data->posY;
311 z = go_data->posZ;
312 ort = go_data->orientation;
313 mapid = go_data->mapid;
315 else
317 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
318 SetSentErrorMessage(true);
319 return false;
322 if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
324 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
325 SetSentErrorMessage(true);
326 return false;
329 // stop flight if need
330 if(_player->isInFlight())
332 _player->GetMotionMaster()->MovementExpired();
333 _player->m_taxi.ClearTaxiDestinations();
335 // save only in non-flight case
336 else
337 _player->SaveRecallPosition();
339 _player->TeleportTo(mapid, x, y, z, ort);
340 return true;
343 bool ChatHandler::HandleGoTriggerCommand(const char* args)
345 Player* _player = m_session->GetPlayer();
347 if (!*args)
348 return false;
350 char *atId = strtok((char*)args, " ");
351 if (!atId)
352 return false;
354 int32 i_atId = atoi(atId);
356 if(!i_atId)
357 return false;
359 AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(i_atId);
360 if (!at)
362 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND,i_atId);
363 SetSentErrorMessage(true);
364 return false;
367 if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
369 PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
370 SetSentErrorMessage(true);
371 return false;
374 // stop flight if need
375 if(_player->isInFlight())
377 _player->GetMotionMaster()->MovementExpired();
378 _player->m_taxi.ClearTaxiDestinations();
380 // save only in non-flight case
381 else
382 _player->SaveRecallPosition();
384 _player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
385 return true;
388 bool ChatHandler::HandleGoGraveyardCommand(const char* args)
390 Player* _player = m_session->GetPlayer();
392 if (!*args)
393 return false;
395 char *gyId = strtok((char*)args, " ");
396 if (!gyId)
397 return false;
399 int32 i_gyId = atoi(gyId);
401 if(!i_gyId)
402 return false;
404 WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(i_gyId);
405 if (!gy)
407 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST,i_gyId);
408 SetSentErrorMessage(true);
409 return false;
412 if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
414 PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
415 SetSentErrorMessage(true);
416 return false;
419 // stop flight if need
420 if(_player->isInFlight())
422 _player->GetMotionMaster()->MovementExpired();
423 _player->m_taxi.ClearTaxiDestinations();
425 // save only in non-flight case
426 else
427 _player->SaveRecallPosition();
429 _player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
430 return true;
433 /** \brief Teleport the GM to the specified creature
435 * .gocreature <GUID> --> TP using creature.guid
436 * .gocreature azuregos --> TP player to the mob with this name
437 * Warning: If there is more than one mob with this name
438 * you will be teleported to the first one that is found.
439 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
440 * Warning: If there is more than one mob with this "id"
441 * you will be teleported to the first one that is found.
443 //teleport to creature
444 bool ChatHandler::HandleGoCreatureCommand(const char* args)
446 if(!*args)
447 return false;
448 Player* _player = m_session->GetPlayer();
450 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
451 char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
452 if (!pParam1)
453 return false;
455 std::ostringstream whereClause;
457 // User wants to teleport to the NPC's template entry
458 if( strcmp(pParam1, "id") == 0 )
460 //sLog.outError("DEBUG: ID found");
462 // Get the "creature_template.entry"
463 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
464 char* tail = strtok(NULL,"");
465 if(!tail)
466 return false;
467 char* cId = extractKeyFromLink(tail,"Hcreature_entry");
468 if(!cId)
469 return false;
471 int32 tEntry = atoi(cId);
472 //sLog.outError("DEBUG: ID value: %d", tEntry);
473 if(!tEntry)
474 return false;
476 whereClause << "WHERE id = '" << tEntry << "'";
478 else
480 //sLog.outError("DEBUG: ID *not found*");
482 int32 guid = atoi(pParam1);
484 // Number is invalid - maybe the user specified the mob's name
485 if(!guid)
487 std::string name = pParam1;
488 WorldDatabase.escape_string(name);
489 whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
491 else
493 whereClause << "WHERE guid = '" << guid << "'";
496 //sLog.outError("DEBUG: %s", whereClause.c_str());
498 QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
499 if (!result)
501 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
502 SetSentErrorMessage(true);
503 return false;
505 if( result->GetRowCount() > 1 )
507 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
510 Field *fields = result->Fetch();
511 float x = fields[0].GetFloat();
512 float y = fields[1].GetFloat();
513 float z = fields[2].GetFloat();
514 float ort = fields[3].GetFloat();
515 int mapid = fields[4].GetUInt16();
517 delete result;
519 if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
521 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
522 SetSentErrorMessage(true);
523 return false;
526 // stop flight if need
527 if(_player->isInFlight())
529 _player->GetMotionMaster()->MovementExpired();
530 _player->m_taxi.ClearTaxiDestinations();
532 // save only in non-flight case
533 else
534 _player->SaveRecallPosition();
536 _player->TeleportTo(mapid, x, y, z, ort);
537 return true;
540 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
542 uint64 guid = m_session->GetPlayer()->GetSelection();
544 if (guid == 0)
546 SendSysMessage(LANG_NO_SELECTION);
547 SetSentErrorMessage(true);
548 return false;
551 PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid));
552 return true;
555 bool ChatHandler::HandleLookupFactionCommand(const char* args)
557 if (!*args)
558 return false;
560 // Can be NULL at console call
561 Player *target = getSelectedPlayer ();
563 std::string namepart = args;
564 std::wstring wnamepart;
566 if (!Utf8toWStr (namepart,wnamepart))
567 return false;
569 // converting string that we try to find to lower case
570 wstrToLower (wnamepart);
572 uint32 counter = 0; // Counter for figure out that we found smth.
574 for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
576 FactionEntry const *factionEntry = sFactionStore.LookupEntry (id);
577 if (factionEntry)
579 FactionState const* repState = NULL;
580 if(target)
582 FactionStateList::const_iterator repItr = target->m_factions.find (factionEntry->reputationListID);
583 if(repItr != target->m_factions.end())
584 repState = &repItr->second;
588 int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale();
589 std::string name = factionEntry->name[loc];
590 if(name.empty())
591 continue;
593 if (!Utf8FitTo(name, wnamepart))
595 loc = 0;
596 for(; loc < MAX_LOCALE; ++loc)
598 if(m_session && loc==m_session->GetSessionDbcLocale())
599 continue;
601 name = factionEntry->name[loc];
602 if(name.empty())
603 continue;
605 if (Utf8FitTo(name, wnamepart))
606 break;
610 if(loc < MAX_LOCALE)
612 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
613 // or "id - [faction] [no reputation]" format
614 std::ostringstream ss;
615 if (m_session)
616 ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << " " << localeNames[loc] << "]|h|r";
617 else
618 ss << id << " - " << name << " " << localeNames[loc];
620 if (repState) // and then target!=NULL also
622 ReputationRank rank = target->GetReputationRank(factionEntry);
623 std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
625 ss << " " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
627 if(repState->Flags & FACTION_FLAG_VISIBLE)
628 ss << GetMangosString(LANG_FACTION_VISIBLE);
629 if(repState->Flags & FACTION_FLAG_AT_WAR)
630 ss << GetMangosString(LANG_FACTION_ATWAR);
631 if(repState->Flags & FACTION_FLAG_PEACE_FORCED)
632 ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
633 if(repState->Flags & FACTION_FLAG_HIDDEN)
634 ss << GetMangosString(LANG_FACTION_HIDDEN);
635 if(repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
636 ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
637 if(repState->Flags & FACTION_FLAG_INACTIVE)
638 ss << GetMangosString(LANG_FACTION_INACTIVE);
640 else
641 ss << GetMangosString(LANG_FACTION_NOREPUTATION);
643 SendSysMessage(ss.str().c_str());
644 counter++;
649 if (counter == 0) // if counter == 0 then we found nth
650 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
651 return true;
654 bool ChatHandler::HandleModifyRepCommand(const char * args)
656 if (!*args) return false;
658 Player* target = NULL;
659 target = getSelectedPlayer();
661 if(!target)
663 SendSysMessage(LANG_PLAYER_NOT_FOUND);
664 SetSentErrorMessage(true);
665 return false;
668 char* factionTxt = extractKeyFromLink((char*)args,"Hfaction");
669 if(!factionTxt)
670 return false;
672 uint32 factionId = atoi(factionTxt);
674 int32 amount = 0;
675 char *rankTxt = strtok(NULL, " ");
676 if (!factionTxt || !rankTxt)
677 return false;
679 amount = atoi(rankTxt);
680 if ((amount == 0) && (rankTxt[0] != '-') && !isdigit(rankTxt[0]))
682 std::string rankStr = rankTxt;
683 std::wstring wrankStr;
684 if(!Utf8toWStr(rankStr,wrankStr))
685 return false;
686 wstrToLower( wrankStr );
688 int r = 0;
689 amount = -42000;
690 for (; r < MAX_REPUTATION_RANK; ++r)
692 std::string rank = GetMangosString(ReputationRankStrIndex[r]);
693 if(rank.empty())
694 continue;
696 std::wstring wrank;
697 if(!Utf8toWStr(rank,wrank))
698 continue;
700 wstrToLower(wrank);
702 if(wrank.substr(0,wrankStr.size())==wrankStr)
704 char *deltaTxt = strtok(NULL, " ");
705 if (deltaTxt)
707 int32 delta = atoi(deltaTxt);
708 if ((delta < 0) || (delta > Player::ReputationRank_Length[r] -1))
710 PSendSysMessage(LANG_COMMAND_FACTION_DELTA, (Player::ReputationRank_Length[r]-1));
711 SetSentErrorMessage(true);
712 return false;
714 amount += delta;
716 break;
718 amount += Player::ReputationRank_Length[r];
720 if (r >= MAX_REPUTATION_RANK)
722 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM, rankTxt);
723 SetSentErrorMessage(true);
724 return false;
728 FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
730 if (!factionEntry)
732 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN, factionId);
733 SetSentErrorMessage(true);
734 return false;
737 if (factionEntry->reputationListID < 0)
739 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId);
740 SetSentErrorMessage(true);
741 return false;
744 target->SetFactionReputation(factionEntry,amount);
745 PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, target->GetName(), target->GetReputation(factionId));
746 return true;
749 bool ChatHandler::HandleNameCommand(const char* args)
751 /* Temp. disabled
752 if(!*args)
753 return false;
755 if(strlen((char*)args)>75)
757 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
758 return true;
761 for (uint8 i = 0; i < strlen(args); i++)
763 if(!isalpha(args[i]) && args[i]!=' ')
765 SendSysMessage(LANG_CHARS_ONLY);
766 return false;
770 uint64 guid;
771 guid = m_session->GetPlayer()->GetSelection();
772 if (guid == 0)
774 SendSysMessage(LANG_NO_SELECTION);
775 return true;
778 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
780 if(!pCreature)
782 SendSysMessage(LANG_SELECT_CREATURE);
783 return true;
786 pCreature->SetName(args);
787 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
788 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
790 pCreature->SaveToDB();
793 return true;
796 bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
798 /* Temp. disabled
800 if(!*args)
801 args = "";
803 if(strlen((char*)args)>75)
806 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
807 return true;
810 for (uint8 i = 0; i < strlen(args); i++)
812 if(!isalpha(args[i]) && args[i]!=' ')
814 SendSysMessage(LANG_CHARS_ONLY);
815 return false;
818 uint64 guid;
819 guid = m_session->GetPlayer()->GetSelection();
820 if (guid == 0)
822 SendSysMessage(LANG_NO_SELECTION);
823 return true;
826 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
828 if(!pCreature)
830 SendSysMessage(LANG_SELECT_CREATURE);
831 return true;
834 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
835 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
837 pCreature->SaveToDB();
839 return true;
842 //move item to other slot
843 bool ChatHandler::HandleItemMoveCommand(const char* args)
845 if(!*args)
846 return false;
847 uint8 srcslot, dstslot;
849 char* pParam1 = strtok((char*)args, " ");
850 if (!pParam1)
851 return false;
853 char* pParam2 = strtok(NULL, " ");
854 if (!pParam2)
855 return false;
857 srcslot = (uint8)atoi(pParam1);
858 dstslot = (uint8)atoi(pParam2);
860 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
861 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
863 if(srcslot==dstslot)
864 return true;
866 m_session->GetPlayer()->SwapItem( src, dst );
868 return true;
871 //add spawn of creature
872 bool ChatHandler::HandleAddSpwCommand(const char* args)
874 if(!*args)
875 return false;
876 char* charID = strtok((char*)args, " ");
877 if (!charID)
878 return false;
880 char* team = strtok(NULL, " ");
881 int32 teamval = 0;
882 if (team) { teamval = atoi(team); }
883 if (teamval < 0) { teamval = 0; }
885 uint32 id = atoi(charID);
887 Player *chr = m_session->GetPlayer();
888 float x = chr->GetPositionX();
889 float y = chr->GetPositionY();
890 float z = chr->GetPositionZ();
891 float o = chr->GetOrientation();
892 Map *map = chr->GetMap();
894 Creature* pCreature = new Creature;
895 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval))
897 delete pCreature;
898 return false;
901 pCreature->Relocate(x,y,z,o);
903 if(!pCreature->IsPositionValid())
905 sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
906 delete pCreature;
907 return false;
910 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
912 uint32 db_guid = pCreature->GetDBTableGUIDLow();
914 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
915 pCreature->LoadFromDB(db_guid, map);
917 map->Add(pCreature);
918 objmgr.AddCreatureToGrid(db_guid, objmgr.GetCreatureData(db_guid));
919 return true;
922 bool ChatHandler::HandleDelCreatureCommand(const char* args)
924 Creature* unit = NULL;
926 if(*args)
928 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
929 char* cId = extractKeyFromLink((char*)args,"Hcreature");
930 if(!cId)
931 return false;
933 uint32 lowguid = atoi(cId);
934 if(!lowguid)
935 return false;
937 if (CreatureData const* cr_data = objmgr.GetCreatureData(lowguid))
938 unit = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT));
940 else
941 unit = getSelectedCreature();
943 if(!unit || unit->isPet() || unit->isTotem())
945 SendSysMessage(LANG_SELECT_CREATURE);
946 SetSentErrorMessage(true);
947 return false;
950 // Delete the creature
951 unit->CombatStop();
952 unit->DeleteFromDB();
953 unit->CleanupsBeforeDelete();
954 unit->AddObjectToRemoveList();
956 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE);
958 return true;
961 //delete object by selection or guid
962 bool ChatHandler::HandleDelObjectCommand(const char* args)
964 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
965 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
966 if(!cId)
967 return false;
969 uint32 lowguid = atoi(cId);
970 if(!lowguid)
971 return false;
973 GameObject* obj = NULL;
975 // by DB guid
976 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
977 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
979 if(!obj)
981 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
982 SetSentErrorMessage(true);
983 return false;
986 uint64 owner_guid = obj->GetOwnerGUID();
987 if(owner_guid)
989 Unit* owner = ObjectAccessor::GetUnit(*m_session->GetPlayer(),owner_guid);
990 if(!owner && !IS_PLAYER_GUID(owner_guid))
992 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE, GUID_LOPART(owner_guid), obj->GetGUIDLow());
993 SetSentErrorMessage(true);
994 return false;
997 owner->RemoveGameObject(obj,false);
1000 obj->SetRespawnTime(0); // not save respawn time
1001 obj->Delete();
1002 obj->DeleteFromDB();
1004 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE, obj->GetGUIDLow());
1006 return true;
1009 //turn selected object
1010 bool ChatHandler::HandleTurnObjectCommand(const char* args)
1012 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
1013 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
1014 if(!cId)
1015 return false;
1017 uint32 lowguid = atoi(cId);
1018 if(!lowguid)
1019 return false;
1021 GameObject* obj = NULL;
1023 // by DB guid
1024 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
1025 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
1027 if(!obj)
1029 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
1030 SetSentErrorMessage(true);
1031 return false;
1034 char* po = strtok(NULL, " ");
1035 float o;
1037 if (po)
1039 o = (float)atof(po);
1041 else
1043 Player *chr = m_session->GetPlayer();
1044 o = chr->GetOrientation();
1047 float rot2 = sin(o/2);
1048 float rot3 = cos(o/2);
1050 Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1051 map->Remove(obj,false);
1053 obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
1055 obj->SetFloatValue(GAMEOBJECT_FACING, o);
1056 obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
1057 obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
1059 map->Add(obj);
1061 obj->SaveToDB();
1062 obj->Refresh();
1064 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, obj->GetGUIDLow(), o);
1066 return true;
1069 //move selected creature
1070 bool ChatHandler::HandleMoveCreatureCommand(const char* args)
1072 uint32 lowguid = 0;
1074 Creature* pCreature = getSelectedCreature();
1076 if(!pCreature)
1078 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1079 char* cId = extractKeyFromLink((char*)args,"Hcreature");
1080 if(!cId)
1081 return false;
1083 uint32 lowguid = atoi(cId);
1085 /* FIXME: impossibel without entry
1086 if(lowguid)
1087 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1090 // Attempting creature load from DB data
1091 if(!pCreature)
1093 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1094 if(!data)
1096 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1097 SetSentErrorMessage(true);
1098 return false;
1101 uint32 map_id = data->mapid;
1103 if(m_session->GetPlayer()->GetMapId()!=map_id)
1105 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid);
1106 SetSentErrorMessage(true);
1107 return false;
1110 else
1112 lowguid = pCreature->GetDBTableGUIDLow();
1115 else
1117 lowguid = pCreature->GetDBTableGUIDLow();
1120 float x = m_session->GetPlayer()->GetPositionX();
1121 float y = m_session->GetPlayer()->GetPositionY();
1122 float z = m_session->GetPlayer()->GetPositionZ();
1123 float o = m_session->GetPlayer()->GetOrientation();
1125 if (pCreature)
1127 if(CreatureData const* data = objmgr.GetCreatureData(pCreature->GetDBTableGUIDLow()))
1129 const_cast<CreatureData*>(data)->posX = x;
1130 const_cast<CreatureData*>(data)->posY = y;
1131 const_cast<CreatureData*>(data)->posZ = z;
1132 const_cast<CreatureData*>(data)->orientation = o;
1134 MapManager::Instance().GetMap(pCreature->GetMapId(),pCreature)->CreatureRelocation(pCreature,x, y, z,o);
1135 pCreature->GetMotionMaster()->Initialize();
1136 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1138 pCreature->setDeathState(JUST_DIED);
1139 pCreature->Respawn();
1143 WorldDatabase.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid);
1144 PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
1145 return true;
1148 //move selected object
1149 bool ChatHandler::HandleMoveObjectCommand(const char* args)
1151 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1152 char* cId = extractKeyFromLink((char*)args,"Hgameobject");
1153 if(!cId)
1154 return false;
1156 uint32 lowguid = atoi(cId);
1157 if(!lowguid)
1158 return false;
1160 GameObject* obj = NULL;
1162 // by DB guid
1163 if (GameObjectData const* go_data = objmgr.GetGOData(lowguid))
1164 obj = GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid,go_data->id);
1166 if(!obj)
1168 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, lowguid);
1169 SetSentErrorMessage(true);
1170 return false;
1173 char* px = strtok(NULL, " ");
1174 char* py = strtok(NULL, " ");
1175 char* pz = strtok(NULL, " ");
1177 if (!px)
1179 Player *chr = m_session->GetPlayer();
1181 Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1182 map->Remove(obj,false);
1184 obj->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), obj->GetOrientation());
1185 obj->SetFloatValue(GAMEOBJECT_POS_X, chr->GetPositionX());
1186 obj->SetFloatValue(GAMEOBJECT_POS_Y, chr->GetPositionY());
1187 obj->SetFloatValue(GAMEOBJECT_POS_Z, chr->GetPositionZ());
1189 map->Add(obj);
1191 else
1193 if(!py || !pz)
1194 return false;
1196 float x = (float)atof(px);
1197 float y = (float)atof(py);
1198 float z = (float)atof(pz);
1200 if(!MapManager::IsValidMapCoord(obj->GetMapId(),x,y,z))
1202 PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,obj->GetMapId());
1203 SetSentErrorMessage(true);
1204 return false;
1207 Map* map = MapManager::Instance().GetMap(obj->GetMapId(),obj);
1208 map->Remove(obj,false);
1210 obj->Relocate(x, y, z, obj->GetOrientation());
1211 obj->SetFloatValue(GAMEOBJECT_POS_X, x);
1212 obj->SetFloatValue(GAMEOBJECT_POS_Y, y);
1213 obj->SetFloatValue(GAMEOBJECT_POS_Z, z);
1215 map->Add(obj);
1218 obj->SaveToDB();
1219 obj->Refresh();
1221 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, obj->GetGUIDLow());
1223 return true;
1226 //demorph player or unit
1227 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1229 Unit *target = getSelectedUnit();
1230 if(!target)
1231 target = m_session->GetPlayer();
1233 target->DeMorph();
1235 return true;
1238 //add item in vendorlist
1239 bool ChatHandler::HandleAddVendorItemCommand(const char* args)
1241 if (!*args)
1242 return false;
1244 char* pitem = extractKeyFromLink((char*)args,"Hitem");
1245 if (!pitem)
1247 SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1248 SetSentErrorMessage(true);
1249 return false;
1252 uint32 itemId = atol(pitem);
1254 char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
1255 uint32 maxcount = 0;
1256 if (fmaxcount)
1257 maxcount = atol(fmaxcount);
1259 char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
1260 uint32 incrtime = 0;
1261 if (fincrtime)
1262 incrtime = atol(fincrtime);
1264 char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
1265 uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
1267 Creature* vendor = getSelectedCreature();
1269 uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
1271 if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
1273 SetSentErrorMessage(true);
1274 return false;
1277 objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
1279 ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1281 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
1282 return true;
1285 //del item from vendor list
1286 bool ChatHandler::HandleDelVendorItemCommand(const char* args)
1288 if (!*args)
1289 return false;
1291 Creature* vendor = getSelectedCreature();
1292 if (!vendor || !vendor->isVendor())
1294 SendSysMessage(LANG_COMMAND_VENDORSELECTION);
1295 SetSentErrorMessage(true);
1296 return false;
1299 char* pitem = extractKeyFromLink((char*)args,"Hitem");
1300 if (!pitem)
1302 SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
1303 SetSentErrorMessage(true);
1304 return false;
1306 uint32 itemId = atol(pitem);
1308 if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
1310 PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
1311 SetSentErrorMessage(true);
1312 return false;
1315 ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
1317 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
1318 return true;
1321 //add move for creature
1322 bool ChatHandler::HandleAddMoveCommand(const char* args)
1324 if(!*args)
1325 return false;
1327 char* guid_str = strtok((char*)args, " ");
1328 char* wait_str = strtok((char*)NULL, " ");
1330 uint32 lowguid = atoi((char*)guid_str);
1332 Creature* pCreature = NULL;
1334 /* FIXME: impossible without entry
1335 if(lowguid)
1336 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1339 // attempt check creature existence by DB data
1340 if(!pCreature)
1342 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1343 if(!data)
1345 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1346 SetSentErrorMessage(true);
1347 return false;
1350 else
1352 // obtain real GUID for DB operations
1353 lowguid = pCreature->GetDBTableGUIDLow();
1356 int wait = wait_str ? atoi(wait_str) : 0;
1358 if(wait < 0)
1359 wait = 0;
1361 Player* player = m_session->GetPlayer();
1363 WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
1365 // update movement type
1366 WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
1367 if(pCreature)
1369 pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
1370 pCreature->GetMotionMaster()->Initialize();
1371 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1373 pCreature->setDeathState(JUST_DIED);
1374 pCreature->Respawn();
1376 pCreature->SaveToDB();
1379 SendSysMessage(LANG_WAYPOINT_ADDED);
1381 return true;
1385 * Set the movement type for an NPC.<br/>
1386 * <br/>
1387 * Valid movement types are:
1388 * <ul>
1389 * <li> stay - NPC wont move </li>
1390 * <li> random - NPC will move randomly according to the spawndist </li>
1391 * <li> way - NPC will move with given waypoints set </li>
1392 * </ul>
1393 * additional parameter: NODEL - so no waypoints are deleted, if you
1394 * change the movement type
1396 bool ChatHandler::HandleSetMoveTypeCommand(const char* args)
1398 if(!*args)
1399 return false;
1401 // 3 arguments:
1402 // GUID (optional - you can also select the creature)
1403 // stay|random|way (determines the kind of movement)
1404 // NODEL (optional - tells the system NOT to delete any waypoints)
1405 // this is very handy if you want to do waypoints, that are
1406 // later switched on/off according to special events (like escort
1407 // quests, etc)
1408 char* guid_str = strtok((char*)args, " ");
1409 char* type_str = strtok((char*)NULL, " ");
1410 char* dontdel_str = strtok((char*)NULL, " ");
1412 bool doNotDelete = false;
1414 if(!guid_str)
1415 return false;
1417 uint32 lowguid = 0;
1418 Creature* pCreature = NULL;
1420 if( dontdel_str )
1422 //sLog.outError("DEBUG: All 3 params are set");
1424 // All 3 params are set
1425 // GUID
1426 // type
1427 // doNotDEL
1428 if( stricmp( dontdel_str, "NODEL" ) == 0 )
1430 //sLog.outError("DEBUG: doNotDelete = true;");
1431 doNotDelete = true;
1434 else
1436 // Only 2 params - but maybe NODEL is set
1437 if( type_str )
1439 sLog.outError("DEBUG: Only 2 params ");
1440 if( stricmp( type_str, "NODEL" ) == 0 )
1442 //sLog.outError("DEBUG: type_str, NODEL ");
1443 doNotDelete = true;
1444 type_str = NULL;
1449 if(!type_str) // case .setmovetype $move_type (with selected creature)
1451 type_str = guid_str;
1452 pCreature = getSelectedCreature();
1453 if(!pCreature || pCreature->isPet())
1454 return false;
1455 lowguid = pCreature->GetDBTableGUIDLow();
1457 else // case .setmovetype #creature_guid $move_type (with selected creature)
1459 lowguid = atoi((char*)guid_str);
1461 /* impossible without entry
1462 if(lowguid)
1463 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1466 // attempt check creature existence by DB data
1467 if(!pCreature)
1469 CreatureData const* data = objmgr.GetCreatureData(lowguid);
1470 if(!data)
1472 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid);
1473 SetSentErrorMessage(true);
1474 return false;
1477 else
1479 lowguid = pCreature->GetDBTableGUIDLow();
1483 // now lowguid is low guid really existed creature
1484 // and pCreature point (maybe) to this creature or NULL
1486 MovementGeneratorType move_type;
1488 std::string type = type_str;
1490 if(type == "stay")
1491 move_type = IDLE_MOTION_TYPE;
1492 else if(type == "random")
1493 move_type = RANDOM_MOTION_TYPE;
1494 else if(type == "way")
1495 move_type = WAYPOINT_MOTION_TYPE;
1496 else
1497 return false;
1499 // update movement type
1500 if(doNotDelete == false)
1501 WaypointMgr.DeletePath(lowguid);
1503 if(pCreature)
1505 pCreature->SetDefaultMovementType(move_type);
1506 pCreature->GetMotionMaster()->Initialize();
1507 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
1509 pCreature->setDeathState(JUST_DIED);
1510 pCreature->Respawn();
1512 pCreature->SaveToDB();
1514 if( doNotDelete == false )
1516 PSendSysMessage(LANG_MOVE_TYPE_SET,type_str);
1518 else
1520 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str);
1523 return true;
1524 } // HandleSetMoveTypeCommand
1526 //change level of creature or pet
1527 bool ChatHandler::HandleChangeLevelCommand(const char* args)
1529 if (!*args)
1530 return false;
1532 uint8 lvl = (uint8) atoi((char*)args);
1533 if ( lvl < 1 || lvl > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
1535 SendSysMessage(LANG_BAD_VALUE);
1536 SetSentErrorMessage(true);
1537 return false;
1540 Creature* pCreature = getSelectedCreature();
1541 if(!pCreature)
1543 SendSysMessage(LANG_SELECT_CREATURE);
1544 SetSentErrorMessage(true);
1545 return false;
1548 if(pCreature->isPet())
1550 ((Pet*)pCreature)->GivePetLevel(lvl);
1552 else
1554 pCreature->SetMaxHealth( 100 + 30*lvl);
1555 pCreature->SetHealth( 100 + 30*lvl);
1556 pCreature->SetLevel( lvl);
1557 pCreature->SaveToDB();
1560 return true;
1563 //set npcflag of creature
1564 bool ChatHandler::HandleNPCFlagCommand(const char* args)
1566 if (!*args)
1567 return false;
1569 uint32 npcFlags = (uint32) atoi((char*)args);
1571 Creature* pCreature = getSelectedCreature();
1573 if(!pCreature)
1575 SendSysMessage(LANG_SELECT_CREATURE);
1576 SetSentErrorMessage(true);
1577 return false;
1580 pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags);
1582 WorldDatabase.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry());
1584 SendSysMessage(LANG_VALUE_SAVED_REJOIN);
1586 return true;
1589 //set model of creature
1590 bool ChatHandler::HandleSetModelCommand(const char* args)
1592 if (!*args)
1593 return false;
1595 uint32 displayId = (uint32) atoi((char*)args);
1597 Creature *pCreature = getSelectedCreature();
1599 if(!pCreature || pCreature->isPet())
1601 SendSysMessage(LANG_SELECT_CREATURE);
1602 SetSentErrorMessage(true);
1603 return false;
1606 pCreature->SetDisplayId(displayId);
1607 pCreature->SetNativeDisplayId(displayId);
1609 pCreature->SaveToDB();
1611 return true;
1614 //morph creature or player
1615 bool ChatHandler::HandleMorphCommand(const char* args)
1617 if (!*args)
1618 return false;
1620 uint16 display_id = (uint16)atoi((char*)args);
1622 Unit *target = getSelectedUnit();
1623 if(!target)
1624 target = m_session->GetPlayer();
1626 target->SetDisplayId(display_id);
1628 return true;
1631 //set faction of creature or go
1632 bool ChatHandler::HandleFactionIdCommand(const char* args)
1634 if (!*args)
1635 return false;
1637 uint32 factionId = (uint32) atoi((char*)args);
1639 if (!sFactionTemplateStore.LookupEntry(factionId))
1641 PSendSysMessage(LANG_WRONG_FACTION, factionId);
1642 SetSentErrorMessage(true);
1643 return false;
1646 Creature* pCreature = getSelectedCreature();
1648 if(!pCreature)
1650 SendSysMessage(LANG_SELECT_CREATURE);
1651 SetSentErrorMessage(true);
1652 return false;
1655 pCreature->setFaction(factionId);
1657 // faction is set in creature_template - not inside creature
1659 // update in memory
1660 if(CreatureInfo const *cinfo = pCreature->GetCreatureInfo())
1662 const_cast<CreatureInfo*>(cinfo)->faction_A = factionId;
1663 const_cast<CreatureInfo*>(cinfo)->faction_H = factionId;
1666 // and DB
1667 WorldDatabase.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry());
1669 return true;
1672 //kick player
1673 bool ChatHandler::HandleKickPlayerCommand(const char *args)
1675 char* kickName = strtok((char*)args, " ");
1676 if (!kickName)
1678 Player* player = getSelectedPlayer();
1680 if(!player)
1682 SendSysMessage(LANG_NO_CHAR_SELECTED);
1683 SetSentErrorMessage(true);
1684 return false;
1687 if(player==m_session->GetPlayer())
1689 SendSysMessage(LANG_COMMAND_KICKSELF);
1690 SetSentErrorMessage(true);
1691 return false;
1694 player->GetSession()->KickPlayer();
1696 else
1698 std::string name = kickName;
1699 if(!normalizePlayerName(name))
1701 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1702 SetSentErrorMessage(true);
1703 return false;
1706 if(m_session && name==m_session->GetPlayer()->GetName())
1708 SendSysMessage(LANG_COMMAND_KICKSELF);
1709 SetSentErrorMessage(true);
1710 return false;
1713 if(sWorld.KickPlayer(name))
1715 PSendSysMessage(LANG_COMMAND_KICKMESSAGE,name.c_str());
1717 else
1718 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,name.c_str());
1721 return true;
1724 //show info of player
1725 bool ChatHandler::HandlePInfoCommand(const char* args)
1727 Player* target = NULL;
1728 uint64 targetGUID = 0;
1730 char* px = strtok((char*)args, " ");
1731 char* py = NULL;
1733 std::string name;
1735 if (px)
1737 name = px;
1739 if(name.empty())
1740 return false;
1742 if(!normalizePlayerName(name))
1744 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1745 SetSentErrorMessage(true);
1746 return false;
1749 target = objmgr.GetPlayer(name.c_str());
1750 if (target)
1751 py = strtok(NULL, " ");
1752 else
1754 targetGUID = objmgr.GetPlayerGUIDByName(name);
1755 if(targetGUID)
1756 py = strtok(NULL, " ");
1757 else
1758 py = px;
1762 if(!target && !targetGUID)
1764 target = getSelectedPlayer();
1767 if(!target && !targetGUID)
1769 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1770 SetSentErrorMessage(true);
1771 return false;
1774 uint32 accId = 0;
1775 uint32 money = 0;
1776 uint32 total_player_time = 0;
1777 uint32 level = 0;
1778 uint32 latency = 0;
1780 // get additional information from Player object
1781 if(target)
1783 targetGUID = target->GetGUID();
1784 name = target->GetName(); // re-read for case getSelectedPlayer() target
1785 accId = target->GetSession()->GetAccountId();
1786 money = target->GetMoney();
1787 total_player_time = target->GetTotalPlayedTime();
1788 level = target->getLevel();
1789 latency = target->GetSession()->GetLatency();
1791 // get additional information from DB
1792 else
1794 accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
1795 Player plr(m_session); // use current session for temporary load
1796 plr.MinimalLoadFromDB(NULL, targetGUID);
1797 money = plr.GetMoney();
1798 total_player_time = plr.GetTotalPlayedTime();
1799 level = plr.getLevel();
1802 std::string username = GetMangosString(LANG_ERROR);
1803 std::string last_ip = GetMangosString(LANG_ERROR);
1804 uint32 security = 0;
1805 std::string last_login = GetMangosString(LANG_ERROR);
1807 QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId);
1808 if(result)
1810 Field* fields = result->Fetch();
1811 username = fields[0].GetCppString();
1812 security = fields[1].GetUInt32();
1814 if(!m_session || m_session->GetSecurity() >= security)
1816 last_ip = fields[2].GetCppString();
1817 last_login = fields[3].GetCppString();
1819 else
1821 last_ip = "-";
1822 last_login = "-";
1825 delete result;
1828 PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), name.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
1830 std::string timeStr = secsToTimeString(total_player_time,true,true);
1831 uint32 gold = money /GOLD;
1832 uint32 silv = (money % GOLD) / SILVER;
1833 uint32 copp = (money % GOLD) % SILVER;
1834 PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
1836 if ( py && strncmp(py, "rep", 3) == 0 )
1838 if(!target)
1840 // rep option not implemented for offline case
1841 SendSysMessage(LANG_PINFO_NO_REP);
1842 SetSentErrorMessage(true);
1843 return false;
1846 char* FactionName;
1847 for(FactionStateList::const_iterator itr = target->m_factions.begin(); itr != target->m_factions.end(); ++itr)
1849 FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
1850 if (factionEntry)
1851 FactionName = factionEntry->name[m_session->GetSessionDbcLocale()];
1852 else
1853 FactionName = "#Not found#";
1854 ReputationRank rank = target->GetReputationRank(factionEntry);
1855 std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
1856 std::ostringstream ss;
1857 ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << FactionName << "]|h|r " << rankName << "|h|r (" << target->GetReputation(factionEntry) << ")";
1859 if(itr->second.Flags & FACTION_FLAG_VISIBLE)
1860 ss << GetMangosString(LANG_FACTION_VISIBLE);
1861 if(itr->second.Flags & FACTION_FLAG_AT_WAR)
1862 ss << GetMangosString(LANG_FACTION_ATWAR);
1863 if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
1864 ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
1865 if(itr->second.Flags & FACTION_FLAG_HIDDEN)
1866 ss << GetMangosString(LANG_FACTION_HIDDEN);
1867 if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
1868 ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
1869 if(itr->second.Flags & FACTION_FLAG_INACTIVE)
1870 ss << GetMangosString(LANG_FACTION_INACTIVE);
1872 SendSysMessage(ss.str().c_str());
1875 return true;
1878 //show tickets
1879 void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
1881 std::string name;
1882 if(!objmgr.GetPlayerNameByGUID(guid,name))
1883 name = GetMangosString(LANG_UNKNOWN);
1885 PSendSysMessage(LANG_COMMAND_TICKETVIEW, name.c_str(),time,text);
1888 //ticket commands
1889 bool ChatHandler::HandleTicketCommand(const char* args)
1891 char* px = strtok((char*)args, " ");
1893 // ticket<end>
1894 if (!px)
1896 if(!m_session)
1898 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1899 SetSentErrorMessage(true);
1900 return false;
1903 size_t count;
1904 QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket");
1905 if(result)
1907 count = (*result)[0].GetUInt32();
1908 delete result;
1910 else
1911 count = 0;
1913 bool accept = m_session->GetPlayer()->isAcceptTickets();
1915 PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, accept ? GetMangosString(LANG_ON) : GetMangosString(LANG_OFF));
1916 return true;
1919 // ticket on
1920 if(strncmp(px,"on",3) == 0)
1922 if(!m_session)
1924 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1925 SetSentErrorMessage(true);
1926 return false;
1929 m_session->GetPlayer()->SetAcceptTicket(true);
1930 SendSysMessage(LANG_COMMAND_TICKETON);
1931 return true;
1934 // ticket off
1935 if(strncmp(px,"off",4) == 0)
1937 if(!m_session)
1939 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1940 SetSentErrorMessage(true);
1941 return false;
1944 m_session->GetPlayer()->SetAcceptTicket(false);
1945 SendSysMessage(LANG_COMMAND_TICKETOFF);
1946 return true;
1949 // ticket #num
1950 int num = atoi(px);
1951 if(num > 0)
1953 QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC LIMIT %d,1",num-1);
1955 if(!result)
1957 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
1958 delete result;
1959 SetSentErrorMessage(true);
1960 return false;
1963 Field* fields = result->Fetch();
1965 uint64 guid = fields[0].GetUInt64();
1966 char const* text = fields[1].GetString();
1967 char const* time = fields[2].GetString();
1969 ShowTicket(guid,text,time);
1970 delete result;
1971 return true;
1974 std::string name = px;
1976 if(!normalizePlayerName(name))
1978 SendSysMessage(LANG_PLAYER_NOT_FOUND);
1979 SetSentErrorMessage(true);
1980 return false;
1983 uint64 guid = objmgr.GetPlayerGUIDByName(name);
1985 if(!guid)
1986 return false;
1988 // ticket $char_name
1989 QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid));
1991 if(!result)
1992 return false;
1994 Field* fields = result->Fetch();
1996 char const* text = fields[0].GetString();
1997 char const* time = fields[1].GetString();
1999 ShowTicket(guid,text,time);
2000 delete result;
2002 return true;
2005 uint32 ChatHandler::GetTicketIDByNum(uint32 num)
2007 QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket");
2009 if(!result || num > result->GetRowCount())
2011 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2012 delete result;
2013 return 0;
2016 for(uint32 i = 1; i < num; ++i)
2017 result->NextRow();
2019 Field* fields = result->Fetch();
2021 uint32 id = fields[0].GetUInt32();
2022 delete result;
2023 return id;
2026 //dell all tickets
2027 bool ChatHandler::HandleDelTicketCommand(const char *args)
2029 char* px = strtok((char*)args, " ");
2030 if (!px)
2031 return false;
2033 // delticket all
2034 if(strncmp(px,"all",4) == 0)
2036 QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket");
2038 if(!result)
2039 return true;
2041 // notify players about ticket deleting
2044 Field* fields = result->Fetch();
2046 uint64 guid = fields[0].GetUInt64();
2048 if(Player* sender = objmgr.GetPlayer(guid))
2049 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2051 }while(result->NextRow());
2053 delete result;
2055 CharacterDatabase.PExecute("DELETE FROM character_ticket");
2056 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
2057 return true;
2060 int num = (uint32)atoi(px);
2062 // delticket #num
2063 if(num > 0)
2065 QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket LIMIT %i",num);
2067 if(!result || uint64(num) > result->GetRowCount())
2069 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
2070 delete result;
2071 SetSentErrorMessage(true);
2072 return false;
2075 for(int i = 1; i < num; ++i)
2076 result->NextRow();
2078 Field* fields = result->Fetch();
2080 uint32 id = fields[0].GetUInt32();
2081 uint64 guid = fields[1].GetUInt64();
2082 delete result;
2084 CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id);
2086 // notify players about ticket deleting
2087 if(Player* sender = objmgr.GetPlayer(guid))
2089 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2090 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName());
2092 else
2093 SendSysMessage(LANG_COMMAND_TICKETDEL);
2095 return true;
2098 std::string name = px;
2100 if(!normalizePlayerName(name))
2102 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2103 SetSentErrorMessage(true);
2104 return false;
2107 uint64 guid = objmgr.GetPlayerGUIDByName(name);
2109 if(!guid)
2110 return false;
2112 // delticket $char_name
2113 CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid));
2115 // notify players about ticket deleting
2116 if(Player* sender = objmgr.GetPlayer(guid))
2117 sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
2119 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
2120 return true;
2123 //set spawn dist of creature
2124 bool ChatHandler::HandleSpawnDistCommand(const char* args)
2126 if(!*args)
2127 return false;
2129 float option = atof((char*)args);
2130 if (option < 0.0f)
2132 SendSysMessage(LANG_BAD_VALUE);
2133 return false;
2136 MovementGeneratorType mtype = IDLE_MOTION_TYPE;
2137 if (option >0.0f)
2138 mtype = RANDOM_MOTION_TYPE;
2140 Creature *pCreature = getSelectedCreature();
2141 uint32 u_guidlow = 0;
2143 if (pCreature)
2144 u_guidlow = pCreature->GetDBTableGUIDLow();
2145 else
2146 return false;
2148 pCreature->SetRespawnRadius((float)option);
2149 pCreature->SetDefaultMovementType(mtype);
2150 pCreature->GetMotionMaster()->Initialize();
2151 if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
2153 pCreature->setDeathState(JUST_DIED);
2154 pCreature->Respawn();
2157 WorldDatabase.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow);
2158 PSendSysMessage(LANG_COMMAND_SPAWNDIST,option);
2159 return true;
2162 bool ChatHandler::HandleSpawnTimeCommand(const char* args)
2164 if(!*args)
2165 return false;
2167 char* stime = strtok((char*)args, " ");
2169 if (!stime)
2170 return false;
2172 int i_stime = atoi((char*)stime);
2174 if (i_stime < 0)
2176 SendSysMessage(LANG_BAD_VALUE);
2177 SetSentErrorMessage(true);
2178 return false;
2181 Creature *pCreature = getSelectedCreature();
2182 uint32 u_guidlow = 0;
2184 if (pCreature)
2185 u_guidlow = pCreature->GetDBTableGUIDLow();
2186 else
2187 return false;
2189 WorldDatabase.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow);
2190 pCreature->SetRespawnDelay((uint32)i_stime);
2191 PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime);
2193 return true;
2197 * Add a waypoint to a creature.
2199 * The user can either select an npc or provide its GUID.
2201 * The user can even select a visual waypoint - then the new waypoint
2202 * is placed *after* the selected one - this makes insertion of new
2203 * waypoints possible.
2205 * eg:
2206 * .wp add 12345
2207 * -> adds a waypoint to the npc with the GUID 12345
2209 * .wp add
2210 * -> adds a waypoint to the currently selected creature
2213 * @param args if the user did not provide a GUID, it is NULL
2215 * @return true - command did succeed, false - something went wrong
2217 bool ChatHandler::HandleWpAddCommand(const char* args)
2219 sLog.outDebug("DEBUG: HandleWpAddCommand");
2221 // optional
2222 char* guid_str = NULL;
2224 if(*args)
2226 guid_str = strtok((char*)args, " ");
2229 uint32 lowguid = 0;
2230 uint32 point = 0;
2231 Creature* target = getSelectedCreature();
2232 // Did player provide a GUID?
2233 if (!guid_str)
2235 sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2237 // No GUID provided
2238 // -> Player must have selected a creature
2240 if(!target || target->isPet())
2242 SendSysMessage(LANG_SELECT_CREATURE);
2243 SetSentErrorMessage(true);
2244 return false;
2246 if (target->GetEntry() == VISUAL_WAYPOINT )
2248 sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2250 QueryResult *result =
2251 WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2252 target->GetGUIDLow() );
2253 if(!result)
2255 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
2256 // User selected a visual spawnpoint -> get the NPC
2257 // Select NPC GUID
2258 // Since we compare float values, we have to deal with
2259 // some difficulties.
2260 // Here we search for all waypoints that only differ in one from 1 thousand
2261 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2262 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2263 const char* maxDIFF = "0.01";
2264 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 )",
2265 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2266 if(!result)
2268 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
2269 SetSentErrorMessage(true);
2270 return false;
2275 Field *fields = result->Fetch();
2276 lowguid = fields[0].GetUInt32();
2277 point = fields[1].GetUInt32();
2278 }while( result->NextRow() );
2279 delete result;
2281 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2282 if(!data)
2284 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2285 SetSentErrorMessage(true);
2286 return false;
2289 target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2290 if(!target)
2292 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2293 SetSentErrorMessage(true);
2294 return false;
2297 else
2299 lowguid = target->GetDBTableGUIDLow();
2302 else
2304 sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2306 // GUID provided
2307 // Warn if player also selected a creature
2308 // -> Creature selection is ignored <-
2309 if(target)
2311 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2313 lowguid = atoi((char*)guid_str);
2315 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2316 if(!data)
2318 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2319 SetSentErrorMessage(true);
2320 return false;
2323 target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2324 if(!target || target->isPet())
2326 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2327 SetSentErrorMessage(true);
2328 return false;
2331 // lowguid -> GUID of the NPC
2332 // point -> number of the waypoint (if not 0)
2333 sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
2335 sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2337 Player* player = m_session->GetPlayer();
2338 WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
2340 // update movement type
2341 if(target)
2343 target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2344 target->GetMotionMaster()->Initialize();
2345 if(target->isAlive()) // dead creature will reset movement generator at respawn
2347 target->setDeathState(JUST_DIED);
2348 target->Respawn();
2350 target->SaveToDB();
2352 else
2353 WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
2355 PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
2357 return true;
2358 } // HandleWpAddCommand
2361 * .wp modify emote | spell | text | del | move | add
2363 * add -> add a WP after the selected visual waypoint
2364 * User must select a visual waypoint and then issue ".wp modify add"
2366 * emote <emoteID>
2367 * User has selected a visual waypoint before.
2368 * <emoteID> is added to this waypoint. Everytime the
2369 * NPC comes to this waypoint, the emote is called.
2371 * emote <GUID> <WPNUM> <emoteID>
2372 * User has not selected visual waypoint before.
2373 * For the waypoint <WPNUM> for the NPC with <GUID>
2374 * an emote <emoteID> is added.
2375 * Everytime the NPC comes to this waypoint, the emote is called.
2378 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2380 bool ChatHandler::HandleWpModifyCommand(const char* args)
2382 sLog.outDebug("DEBUG: HandleWpModifyCommand");
2384 if(!*args)
2385 return false;
2387 // first arg: add del text emote spell waittime move
2388 char* show_str = strtok((char*)args, " ");
2389 if (!show_str)
2391 return false;
2394 std::string show = show_str;
2395 // Check
2396 // Remember: "show" must also be the name of a column!
2397 if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2")
2398 && (show != "text3") && (show != "text4") && (show != "text5")
2399 && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
2400 && (show != "model1") && (show != "model2") && (show != "orientation"))
2402 return false;
2405 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2407 // Did user provide a GUID
2408 // or did the user select a creature?
2409 // -> variable lowguid is filled with the GUID of the NPC
2410 uint32 lowguid = 0;
2411 uint32 point = 0;
2412 uint32 wpGuid = 0;
2413 Creature* target = getSelectedCreature();
2415 if(target)
2417 sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2419 // Did the user select a visual spawnpoint?
2420 if (target->GetEntry() != VISUAL_WAYPOINT )
2422 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2423 SetSentErrorMessage(true);
2424 return false;
2427 wpGuid = target->GetGUIDLow();
2429 // The visual waypoint
2430 QueryResult *result =
2431 WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2432 target->GetGUIDLow() );
2433 if(!result)
2435 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
2436 SetSentErrorMessage(true);
2437 return false;
2439 sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2441 Field *fields = result->Fetch();
2442 lowguid = fields[0].GetUInt32();
2443 point = fields[1].GetUInt32();
2445 // Cleanup memory
2446 sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2447 delete result;
2449 else
2451 // User did provide <GUID> <WPNUM>
2453 char* guid_str = strtok((char*)NULL, " ");
2454 if( !guid_str )
2456 SendSysMessage(LANG_WAYPOINT_NOGUID);
2457 return false;
2459 lowguid = atoi((char*)guid_str);
2461 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2462 if(!data)
2464 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2465 SetSentErrorMessage(true);
2466 return false;
2469 PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
2471 char* point_str = strtok((char*)NULL, " ");
2472 if( !point_str )
2474 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
2475 return false;
2477 point = atoi((char*)point_str);
2479 PSendSysMessage("DEBUG: wpNumber provided: %d", point);
2481 // Now we need the GUID of the visual waypoint
2482 // -> "del", "move", "add" command
2484 QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
2485 if (!result)
2487 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
2488 SetSentErrorMessage(true);
2489 return false;
2492 Field *fields = result->Fetch();
2493 wpGuid = fields[0].GetUInt32();
2495 // Free memory
2496 delete result;
2499 char* arg_str = NULL;
2500 // Check for argument
2501 if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
2503 // Text is enclosed in "<>", all other arguments not
2504 if( show.find("text") != std::string::npos )
2505 arg_str = strtok((char*)NULL, "<>");
2506 else
2507 arg_str = strtok((char*)NULL, " ");
2509 if( !arg_str)
2511 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
2512 return false;
2516 sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2518 // wpGuid -> GUID of the waypoint creature
2519 // lowguid -> GUID of the NPC
2520 // point -> waypoint number
2522 // Special functions:
2523 // add - move - del -> no args commands
2524 // Add a waypoint after the selected visual
2525 if(show == "add" && target)
2527 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
2529 // Get the creature for which we read the waypoint
2530 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2531 if(!data)
2533 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2534 SetSentErrorMessage(true);
2535 return false;
2538 Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2540 if( !npcCreature )
2542 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
2543 SetSentErrorMessage(true);
2544 return false;
2547 sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2549 // What to do:
2550 // Add the visual spawnpoint (DB only)
2551 // Adjust the waypoints
2552 // Respawn the owner of the waypoints
2553 sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
2555 Player* chr = m_session->GetPlayer();
2556 Map *map = chr->GetMap();
2558 if(npcCreature)
2560 npcCreature->GetMotionMaster()->Initialize();
2561 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2563 npcCreature->setDeathState(JUST_DIED);
2564 npcCreature->Respawn();
2568 // create the waypoint creature
2569 wpGuid = 0;
2570 Creature* wpCreature = new Creature;
2571 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
2573 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2574 delete wpCreature;
2576 else
2578 wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2580 if(!wpCreature->IsPositionValid())
2582 sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
2583 delete wpCreature;
2585 else
2587 wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2588 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2589 wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
2590 map->Add(wpCreature);
2591 wpGuid = wpCreature->GetGUIDLow();
2595 WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
2597 if(!wpGuid)
2598 return false;
2600 PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
2601 return true;
2602 } // add
2604 if(show == "del" && target)
2606 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
2608 // Get the creature for which we read the waypoint
2609 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2610 if(!data)
2612 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2613 SetSentErrorMessage(true);
2614 return false;
2617 Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2619 // wpCreature
2620 Creature* wpCreature = NULL;
2621 if( wpGuid != 0 )
2623 wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2624 wpCreature->DeleteFromDB();
2625 wpCreature->CleanupsBeforeDelete();
2626 wpCreature->AddObjectToRemoveList();
2629 // What to do:
2630 // Remove the visual spawnpoint
2631 // Adjust the waypoints
2632 // Respawn the owner of the waypoints
2634 WaypointMgr.DeleteNode(lowguid, point);
2636 if(npcCreature)
2638 // Any waypoints left?
2639 QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
2640 if(!result2)
2642 npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
2644 else
2646 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2647 delete result2;
2649 npcCreature->GetMotionMaster()->Initialize();
2650 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2652 npcCreature->setDeathState(JUST_DIED);
2653 npcCreature->Respawn();
2655 npcCreature->SaveToDB();
2658 PSendSysMessage(LANG_WAYPOINT_REMOVED);
2659 return true;
2660 } // del
2662 if(show == "move" && target)
2664 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
2666 Player *chr = m_session->GetPlayer();
2667 Map *map = chr->GetMap();
2669 // Get the creature for which we read the waypoint
2670 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2671 if(!data)
2673 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2674 SetSentErrorMessage(true);
2675 return false;
2678 Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2680 // wpCreature
2681 Creature* wpCreature = NULL;
2682 // What to do:
2683 // Move the visual spawnpoint
2684 // Respawn the owner of the waypoints
2685 if( wpGuid != 0 )
2687 wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
2688 wpCreature->DeleteFromDB();
2689 wpCreature->CleanupsBeforeDelete();
2690 wpCreature->AddObjectToRemoveList();
2691 // re-create
2692 Creature* wpCreature2 = new Creature;
2693 if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0))
2695 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
2696 delete wpCreature2;
2697 return false;
2700 wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
2702 if(!wpCreature2->IsPositionValid())
2704 sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2->GetGUIDLow(),wpCreature2->GetEntry(),wpCreature2->GetPositionX(),wpCreature2->GetPositionY());
2705 delete wpCreature2;
2706 return false;
2709 wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
2710 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2711 wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
2712 map->Add(wpCreature2);
2713 //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2716 WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
2718 if(npcCreature)
2720 npcCreature->GetMotionMaster()->Initialize();
2721 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2723 npcCreature->setDeathState(JUST_DIED);
2724 npcCreature->Respawn();
2727 PSendSysMessage(LANG_WAYPOINT_CHANGED);
2729 return true;
2730 } // move
2732 // Create creature - npc that has the waypoint
2733 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2734 if(!data)
2736 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2737 SetSentErrorMessage(true);
2738 return false;
2741 WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
2743 Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
2744 if(npcCreature)
2746 npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
2747 npcCreature->GetMotionMaster()->Initialize();
2748 if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
2750 npcCreature->setDeathState(JUST_DIED);
2751 npcCreature->Respawn();
2754 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
2756 return true;
2760 * .wp show info | on | off
2762 * info -> User has selected a visual waypoint before
2764 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2765 * provided the GUID of the NPC and the number of
2766 * the waypoint.
2768 * on -> User has selected an NPC; all visual waypoints for this
2769 * NPC are added to the world
2771 * on <GUID> -> User did not select an NPC - instead the GUID of the
2772 * NPC is provided. All visual waypoints for this NPC
2773 * are added from the world.
2775 * off -> User has selected an NPC; all visual waypoints for this
2776 * NPC are removed from the world.
2778 * on <GUID> -> User did not select an NPC - instead the GUID of the
2779 * NPC is provided. All visual waypoints for this NPC
2780 * are removed from the world.
2784 bool ChatHandler::HandleWpShowCommand(const char* args)
2786 sLog.outDebug("DEBUG: HandleWpShowCommand");
2788 if(!*args)
2789 return false;
2791 // first arg: on, off, first, last
2792 char* show_str = strtok((char*)args, " ");
2793 if (!show_str)
2795 return false;
2797 // second arg: GUID (optional, if a creature is selected)
2798 char* guid_str = strtok((char*)NULL, " ");
2799 sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
2800 //if (!guid_str) {
2801 // return false;
2804 // Did user provide a GUID
2805 // or did the user select a creature?
2806 // -> variable lowguid is filled with the GUID
2807 Creature* target = getSelectedCreature();
2808 // Did player provide a GUID?
2809 if (!guid_str)
2811 sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2812 // No GUID provided
2813 // -> Player must have selected a creature
2815 if(!target)
2817 SendSysMessage(LANG_SELECT_CREATURE);
2818 SetSentErrorMessage(true);
2819 return false;
2822 else
2824 sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2825 // GUID provided
2826 // Warn if player also selected a creature
2827 // -> Creature selection is ignored <-
2828 if(target)
2830 SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
2833 uint32 lowguid = atoi((char*)guid_str);
2835 CreatureData const* data = objmgr.GetCreatureData(lowguid);
2836 if(!data)
2838 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2839 SetSentErrorMessage(true);
2840 return false;
2843 target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
2845 if(!target)
2847 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
2848 SetSentErrorMessage(true);
2849 return false;
2853 uint32 lowguid = target->GetDBTableGUIDLow();
2855 std::string show = show_str;
2856 uint32 Maxpoint;
2858 sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid);
2860 sLog.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", target );
2862 sLog.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str);
2863 //PSendSysMessage("wpshow - show: %s", show);
2865 // Show info for the selected waypoint
2866 if(show == "info")
2868 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
2870 // Check if the user did specify a visual waypoint
2871 if( target->GetEntry() != VISUAL_WAYPOINT )
2873 PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
2874 SetSentErrorMessage(true);
2875 return false;
2878 //PSendSysMessage("wp on, GUID: %u", lowguid);
2880 //pCreature->GetPositionX();
2882 QueryResult *result =
2883 WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2884 target->GetGUID() );
2885 if(!result)
2887 // Since we compare float values, we have to deal with
2888 // some difficulties.
2889 // Here we search for all waypoints that only differ in one from 1 thousand
2890 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2891 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2892 const char* maxDIFF = "0.01";
2893 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
2895 result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2896 target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
2897 if(!result)
2899 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
2900 SetSentErrorMessage(true);
2901 return false;
2906 Field *fields = result->Fetch();
2907 uint32 creGUID = fields[0].GetUInt32();
2908 uint32 point = fields[1].GetUInt32();
2909 int waittime = fields[2].GetUInt32();
2910 uint32 emote = fields[3].GetUInt32();
2911 uint32 spell = fields[4].GetUInt32();
2912 const char * text1 = fields[5].GetString();
2913 const char * text2 = fields[6].GetString();
2914 const char * text3 = fields[7].GetString();
2915 const char * text4 = fields[8].GetString();
2916 const char * text5 = fields[9].GetString();
2917 uint32 model1 = fields[10].GetUInt32();
2918 uint32 model2 = fields[11].GetUInt32();
2920 // Get the creature for which we read the waypoint
2921 Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2923 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
2924 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
2925 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
2926 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
2927 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
2928 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
2929 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1);
2930 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2);
2931 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3);
2932 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4);
2933 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5);
2935 }while( result->NextRow() );
2936 // Cleanup memory
2937 delete result;
2938 return true;
2941 if(show == "on")
2943 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
2945 QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
2946 if(!result)
2948 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
2949 SetSentErrorMessage(true);
2950 return false;
2952 // Delete all visuals for this NPC
2953 QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
2954 if(result2)
2956 bool hasError = false;
2959 Field *fields = result2->Fetch();
2960 uint32 wpguid = fields[0].GetUInt32();
2961 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpguid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
2963 if(!pCreature)
2965 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid);
2966 hasError = true;
2967 WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid);
2969 else
2971 pCreature->DeleteFromDB();
2972 pCreature->CleanupsBeforeDelete();
2973 pCreature->AddObjectToRemoveList();
2976 }while( result2->NextRow() );
2977 delete result2;
2978 if( hasError )
2980 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
2981 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
2982 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
2988 Field *fields = result->Fetch();
2989 uint32 point = fields[0].GetUInt32();
2990 float x = fields[1].GetFloat();
2991 float y = fields[2].GetFloat();
2992 float z = fields[3].GetFloat();
2994 uint32 id = VISUAL_WAYPOINT;
2996 Player *chr = m_session->GetPlayer();
2997 Map *map = chr->GetMap();
2998 float o = chr->GetOrientation();
3000 Creature* wpCreature = new Creature;
3001 if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3003 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3004 delete wpCreature;
3005 delete result;
3006 return false;
3009 wpCreature->Relocate(x, y, z, o);
3011 if(!wpCreature->IsPositionValid())
3013 sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
3014 delete wpCreature;
3015 delete result;
3016 return false;
3019 wpCreature->SetVisibility(VISIBILITY_OFF);
3020 sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3021 // set "wpguid" column to the visual waypoint
3022 WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
3024 wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3025 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3026 wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
3027 map->Add(wpCreature);
3028 //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
3029 }while( result->NextRow() );
3031 // Cleanup memory
3032 delete result;
3033 return true;
3036 if(show == "first")
3038 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
3040 QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
3041 if(!result)
3043 PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
3044 SetSentErrorMessage(true);
3045 return false;
3048 Field *fields = result->Fetch();
3049 float x = fields[0].GetFloat();
3050 float y = fields[1].GetFloat();
3051 float z = fields[2].GetFloat();
3052 uint32 id = VISUAL_WAYPOINT;
3054 Player *chr = m_session->GetPlayer();
3055 float o = chr->GetOrientation();
3056 Map *map = chr->GetMap();
3058 Creature* pCreature = new Creature;
3059 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0))
3061 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
3062 delete pCreature;
3063 delete result;
3064 return false;
3067 pCreature->Relocate(x, y, z, o);
3069 if(!pCreature->IsPositionValid())
3071 sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3072 delete pCreature;
3073 delete result;
3074 return false;
3077 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3078 pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3079 map->Add(pCreature);
3080 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3082 // Cleanup memory
3083 delete result;
3084 return true;
3087 if(show == "last")
3089 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
3091 QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
3092 if( result )
3094 Maxpoint = (*result)[0].GetUInt32();
3096 delete result;
3098 else
3099 Maxpoint = 0;
3101 result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
3102 if(!result)
3104 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
3105 SetSentErrorMessage(true);
3106 return false;
3108 Field *fields = result->Fetch();
3109 float x = fields[0].GetFloat();
3110 float y = fields[1].GetFloat();
3111 float z = fields[2].GetFloat();
3112 uint32 id = VISUAL_WAYPOINT;
3114 Player *chr = m_session->GetPlayer();
3115 float o = chr->GetOrientation();
3116 Map *map = chr->GetMap();
3118 Creature* pCreature = new Creature;
3119 if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0))
3121 PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
3122 delete pCreature;
3123 delete result;
3124 return false;
3127 pCreature->Relocate(x, y, z, o);
3129 if(!pCreature->IsPositionValid())
3131 sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
3132 delete pCreature;
3133 delete result;
3134 return false;
3137 pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3138 pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
3139 map->Add(pCreature);
3140 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3141 // Cleanup memory
3142 delete result;
3143 return true;
3146 if(show == "off")
3148 QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
3149 if(!result)
3151 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
3152 SetSentErrorMessage(true);
3153 return false;
3155 bool hasError = false;
3158 Field *fields = result->Fetch();
3159 uint32 guid = fields[0].GetUInt32();
3160 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
3162 //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3164 if(!pCreature)
3166 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
3167 hasError = true;
3168 WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid);
3170 else
3172 pCreature->DeleteFromDB();
3173 pCreature->CleanupsBeforeDelete();
3174 pCreature->AddObjectToRemoveList();
3176 }while(result->NextRow());
3177 // set "wpguid" column to "empty" - no visual waypoint spawned
3178 WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3180 if( hasError )
3182 PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
3183 PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
3184 PSendSysMessage(LANG_WAYPOINT_TOOFAR3);
3187 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED);
3188 // Cleanup memory
3189 delete result;
3191 return true;
3194 PSendSysMessage("DEBUG: wpshow - no valid command found");
3196 return true;
3197 } // HandleWpShowCommand
3199 bool ChatHandler::HandleWpExportCommand(const char *args)
3201 if(!*args)
3202 return false;
3204 // Next arg is: <GUID> <ARGUMENT>
3206 // Did user provide a GUID
3207 // or did the user select a creature?
3208 // -> variable lowguid is filled with the GUID of the NPC
3209 uint32 lowguid = 0;
3210 Creature* target = getSelectedCreature();
3211 char* arg_str = NULL;
3212 if (target)
3214 if (target->GetEntry() != VISUAL_WAYPOINT)
3215 lowguid = target->GetGUIDLow();
3216 else
3218 QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
3219 if (!result)
3221 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
3222 return true;
3224 Field *fields = result->Fetch();
3225 lowguid = fields[0].GetUInt32();;
3226 delete result;
3229 arg_str = strtok((char*)args, " ");
3231 else
3233 // user provided <GUID>
3234 char* guid_str = strtok((char*)args, " ");
3235 if( !guid_str )
3237 SendSysMessage(LANG_WAYPOINT_NOGUID);
3238 return false;
3240 lowguid = atoi((char*)guid_str);
3242 arg_str = strtok((char*)NULL, " ");
3245 if( !arg_str)
3247 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
3248 return false;
3251 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
3253 QueryResult *result = WorldDatabase.PQuery(
3254 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3255 "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
3257 if (!result)
3259 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
3260 SetSentErrorMessage(true);
3261 return false;
3264 std::ofstream outfile;
3265 outfile.open (arg_str);
3269 Field *fields = result->Fetch();
3271 outfile << "INSERT INTO creature_movement ";
3272 outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
3274 outfile << "( ";
3275 outfile << fields[15].GetUInt32(); // id
3276 outfile << ", ";
3277 outfile << fields[0].GetUInt32(); // point
3278 outfile << ", ";
3279 outfile << fields[1].GetFloat(); // position_x
3280 outfile << ", ";
3281 outfile << fields[2].GetFloat(); // position_y
3282 outfile << ", ";
3283 outfile << fields[3].GetUInt32(); // position_z
3284 outfile << ", ";
3285 outfile << fields[4].GetUInt32(); // orientation
3286 outfile << ", ";
3287 outfile << fields[5].GetUInt32(); // model1
3288 outfile << ", ";
3289 outfile << fields[6].GetUInt32(); // model2
3290 outfile << ", ";
3291 outfile << fields[7].GetUInt16(); // waittime
3292 outfile << ", ";
3293 outfile << fields[8].GetUInt32(); // emote
3294 outfile << ", ";
3295 outfile << fields[9].GetUInt32(); // spell
3296 outfile << ", ";
3297 const char *tmpChar = fields[10].GetString();
3298 if( !tmpChar )
3300 outfile << "NULL"; // text1
3302 else
3304 outfile << "'";
3305 outfile << tmpChar; // text1
3306 outfile << "'";
3308 outfile << ", ";
3309 tmpChar = fields[11].GetString();
3310 if( !tmpChar )
3312 outfile << "NULL"; // text2
3314 else
3316 outfile << "'";
3317 outfile << tmpChar; // text2
3318 outfile << "'";
3320 outfile << ", ";
3321 tmpChar = fields[12].GetString();
3322 if( !tmpChar )
3324 outfile << "NULL"; // text3
3326 else
3328 outfile << "'";
3329 outfile << tmpChar; // text3
3330 outfile << "'";
3332 outfile << ", ";
3333 tmpChar = fields[13].GetString();
3334 if( !tmpChar )
3336 outfile << "NULL"; // text4
3338 else
3340 outfile << "'";
3341 outfile << tmpChar; // text4
3342 outfile << "'";
3344 outfile << ", ";
3345 tmpChar = fields[14].GetString();
3346 if( !tmpChar )
3348 outfile << "NULL"; // text5
3350 else
3352 outfile << "'";
3353 outfile << tmpChar; // text5
3354 outfile << "'";
3356 outfile << ");\n ";
3358 } while( result->NextRow() );
3359 delete result;
3361 PSendSysMessage(LANG_WAYPOINT_EXPORTED);
3362 outfile.close();
3364 return true;
3367 bool ChatHandler::HandleWpImportCommand(const char *args)
3369 if(!*args)
3370 return false;
3372 char* arg_str = strtok((char*)args, " ");
3373 if (!arg_str)
3374 return false;
3376 std::string line;
3377 std::ifstream infile (arg_str);
3378 if (infile.is_open())
3380 while (! infile.eof() )
3382 getline (infile,line);
3383 //cout << line << endl;
3384 QueryResult *result = WorldDatabase.PQuery(line.c_str());
3385 delete result;
3387 infile.close();
3389 PSendSysMessage(LANG_WAYPOINT_IMPORTED);
3391 return true;
3394 //rename characters
3395 bool ChatHandler::HandleRenameCommand(const char* args)
3397 Player* target = NULL;
3398 uint64 targetGUID = 0;
3399 std::string oldname;
3401 char* px = strtok((char*)args, " ");
3403 if(px)
3405 oldname = px;
3407 if(!normalizePlayerName(oldname))
3409 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3410 SetSentErrorMessage(true);
3411 return false;
3414 target = objmgr.GetPlayer(oldname.c_str());
3416 if (!target)
3417 targetGUID = objmgr.GetPlayerGUIDByName(oldname);
3420 if(!target && !targetGUID)
3422 target = getSelectedPlayer();
3425 if(!target && !targetGUID)
3427 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3428 SetSentErrorMessage(true);
3429 return false;
3432 if(target)
3434 PSendSysMessage(LANG_RENAME_PLAYER, target->GetName());
3435 target->SetAtLoginFlag(AT_LOGIN_RENAME);
3436 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target->GetGUIDLow());
3438 else
3440 PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
3441 CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID));
3444 return true;
3447 //spawn go
3448 bool ChatHandler::HandleGameObjectCommand(const char* args)
3450 if (!*args)
3451 return false;
3453 char* pParam1 = strtok((char*)args, " ");
3454 if (!pParam1)
3455 return false;
3457 uint32 id = atoi((char*)pParam1);
3458 if(!id)
3459 return false;
3461 char* spawntimeSecs = strtok(NULL, " ");
3463 const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
3465 if (!goI)
3467 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
3468 SetSentErrorMessage(true);
3469 return false;
3472 Player *chr = m_session->GetPlayer();
3473 float x = float(chr->GetPositionX());
3474 float y = float(chr->GetPositionY());
3475 float z = float(chr->GetPositionZ());
3476 float o = float(chr->GetOrientation());
3477 Map *map = chr->GetMap();
3479 float rot2 = sin(o/2);
3480 float rot3 = cos(o/2);
3482 GameObject* pGameObj = new GameObject;
3483 uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
3485 if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1))
3487 delete pGameObj;
3488 return false;
3491 if( spawntimeSecs )
3493 uint32 value = atoi((char*)spawntimeSecs);
3494 pGameObj->SetRespawnTime(value);
3495 //sLog.outDebug("*** spawntimeSecs: %d", value);
3498 // fill the gameobject data and save to the db
3499 pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
3501 // this will generate a new guid if the object is in an instance
3502 if(!pGameObj->LoadFromDB(db_lowGUID, map))
3504 delete pGameObj;
3505 return false;
3508 sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
3510 map->Add(pGameObj);
3512 // TODO: is it really necessary to add both the real and DB table guid here ?
3513 objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
3515 PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
3516 return true;
3519 //show animation
3520 bool ChatHandler::HandleAnimCommand(const char* args)
3522 if (!*args)
3523 return false;
3525 uint32 anim_id = atoi((char*)args);
3526 m_session->GetPlayer()->HandleEmoteCommand(anim_id);
3527 return true;
3530 //change standstate
3531 bool ChatHandler::HandleStandStateCommand(const char* args)
3533 if (!*args)
3534 return false;
3536 uint32 anim_id = atoi((char*)args);
3537 m_session->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE , anim_id );
3539 return true;
3542 bool ChatHandler::HandleAddHonorCommand(const char* args)
3544 if (!*args)
3545 return false;
3547 Player *target = getSelectedPlayer();
3548 if(!target)
3550 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3551 SetSentErrorMessage(true);
3552 return false;
3555 uint32 amount = (uint32)atoi(args);
3556 target->RewardHonor(NULL, 1, amount);
3557 return true;
3560 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3562 Unit *target = getSelectedUnit();
3563 if(!target)
3565 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3566 SetSentErrorMessage(true);
3567 return false;
3570 m_session->GetPlayer()->RewardHonor(target, 1);
3571 return true;
3574 bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3576 Player *target = getSelectedPlayer();
3577 if(!target)
3579 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3580 SetSentErrorMessage(true);
3581 return false;
3584 target->UpdateHonorFields();
3585 return true;
3588 bool ChatHandler::HandleLookupEventCommand(const char* args)
3590 if(!*args)
3591 return false;
3593 std::string namepart = args;
3594 std::wstring wnamepart;
3596 // converting string that we try to find to lower case
3597 if(!Utf8toWStr(namepart,wnamepart))
3598 return false;
3600 wstrToLower(wnamepart);
3602 uint32 counter = 0;
3604 GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3605 GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3607 for(uint32 id = 0; id < events.size(); ++id )
3609 GameEventData const& eventData = events[id];
3611 std::string descr = eventData.description;
3612 if(descr.empty())
3613 continue;
3615 if (Utf8FitTo(descr, wnamepart))
3617 char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : "";
3619 if(m_session)
3620 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,id,id,eventData.description.c_str(),active );
3621 else
3622 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,id,eventData.description.c_str(),active );
3624 ++counter;
3628 if (counter==0)
3629 SendSysMessage(LANG_NOEVENTFOUND);
3631 return true;
3634 bool ChatHandler::HandleEventActiveListCommand(const char* args)
3636 uint32 counter = 0;
3638 GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3639 GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3641 char const* active = GetMangosString(LANG_ACTIVE);
3643 for(GameEvent::ActiveEvents::const_iterator itr = activeEvents.begin(); itr != activeEvents.end(); ++itr )
3645 uint32 event_id = *itr;
3646 GameEventData const& eventData = events[event_id];
3648 if(m_session)
3649 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT,event_id,event_id,eventData.description.c_str(),active );
3650 else
3651 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE,event_id,eventData.description.c_str(),active );
3653 ++counter;
3656 if (counter==0)
3657 SendSysMessage(LANG_NOEVENTFOUND);
3659 return true;
3662 bool ChatHandler::HandleEventInfoCommand(const char* args)
3664 if(!*args)
3665 return false;
3667 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3668 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3669 if(!cId)
3670 return false;
3672 uint32 event_id = atoi(cId);
3674 GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3676 if(event_id >=events.size())
3678 SendSysMessage(LANG_EVENT_NOT_EXIST);
3679 SetSentErrorMessage(true);
3680 return false;
3683 GameEventData const& eventData = events[event_id];
3684 if(!eventData.isValid())
3686 SendSysMessage(LANG_EVENT_NOT_EXIST);
3687 SetSentErrorMessage(true);
3688 return false;
3691 GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3692 bool active = activeEvents.find(event_id) != activeEvents.end();
3693 char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : "";
3695 std::string startTimeStr = TimeToTimestampStr(eventData.start);
3696 std::string endTimeStr = TimeToTimestampStr(eventData.end);
3698 uint32 delay = gameeventmgr.NextCheck(event_id);
3699 time_t nextTime = time(NULL)+delay;
3700 std::string nextStr = nextTime >= eventData.start && nextTime < eventData.end ? TimeToTimestampStr(time(NULL)+delay) : "-";
3702 std::string occurenceStr = secsToTimeString(eventData.occurence * MINUTE);
3703 std::string lengthStr = secsToTimeString(eventData.length * MINUTE);
3705 PSendSysMessage(LANG_EVENT_INFO,event_id,eventData.description.c_str(),activeStr,
3706 startTimeStr.c_str(),endTimeStr.c_str(),occurenceStr.c_str(),lengthStr.c_str(),
3707 nextStr.c_str());
3708 return true;
3711 bool ChatHandler::HandleEventStartCommand(const char* args)
3713 if(!*args)
3714 return false;
3716 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3717 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3718 if(!cId)
3719 return false;
3721 int32 event_id = atoi(cId);
3723 GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3725 if(event_id < 1 || event_id >=events.size())
3727 SendSysMessage(LANG_EVENT_NOT_EXIST);
3728 SetSentErrorMessage(true);
3729 return false;
3732 GameEventData const& eventData = events[event_id];
3733 if(!eventData.isValid())
3735 SendSysMessage(LANG_EVENT_NOT_EXIST);
3736 SetSentErrorMessage(true);
3737 return false;
3740 GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3741 if(activeEvents.find(event_id) != activeEvents.end())
3743 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
3744 SetSentErrorMessage(true);
3745 return false;
3748 gameeventmgr.StartEvent(event_id,true);
3749 return true;
3752 bool ChatHandler::HandleEventStopCommand(const char* args)
3754 if(!*args)
3755 return false;
3757 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3758 char* cId = extractKeyFromLink((char*)args,"Hgameevent");
3759 if(!cId)
3760 return false;
3762 int32 event_id = atoi(cId);
3764 GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
3766 if(event_id < 1 || event_id >=events.size())
3768 SendSysMessage(LANG_EVENT_NOT_EXIST);
3769 SetSentErrorMessage(true);
3770 return false;
3773 GameEventData const& eventData = events[event_id];
3774 if(!eventData.isValid())
3776 SendSysMessage(LANG_EVENT_NOT_EXIST);
3777 SetSentErrorMessage(true);
3778 return false;
3781 GameEvent::ActiveEvents const& activeEvents = gameeventmgr.GetActiveEventList();
3783 if(activeEvents.find(event_id) == activeEvents.end())
3785 PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
3786 SetSentErrorMessage(true);
3787 return false;
3790 gameeventmgr.StopEvent(event_id,true);
3791 return true;
3794 bool ChatHandler::HandleCombatStopCommand(const char* args)
3796 Player *player;
3798 if(*args)
3800 std::string playername = args;
3802 if(!normalizePlayerName(playername))
3804 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3805 SetSentErrorMessage(true);
3806 return false;
3809 player = objmgr.GetPlayer(playername.c_str());
3811 if(!player)
3813 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3814 SetSentErrorMessage(true);
3815 return false;
3818 else
3820 player = getSelectedPlayer();
3822 if (!player)
3823 player = m_session->GetPlayer();
3826 player->CombatStop();
3827 player->getHostilRefManager().deleteReferences();
3828 return true;
3831 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3833 uint32 classmask = m_session->GetPlayer()->getClassMask();
3835 for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3837 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3838 if( !skillInfo )
3839 continue;
3841 if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY )
3843 for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3845 SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3846 if( !skillLine )
3847 continue;
3849 // skip racial skills
3850 if( skillLine->racemask != 0 )
3851 continue;
3853 // skip wrong class skills
3854 if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3855 continue;
3857 if( skillLine->skillId != i || skillLine->forward_spellid )
3858 continue;
3860 SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3861 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3862 continue;
3864 m_session->GetPlayer()->learnSpell(skillLine->spellId);
3869 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT);
3870 return true;
3873 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
3875 // Learns all recipes of specified profession and sets skill to max
3876 // Example: .learn all_recipes enchanting
3878 Player* target = getSelectedPlayer();
3879 if( !target )
3881 SendSysMessage(LANG_PLAYER_NOT_FOUND);
3882 return false;
3885 if(!*args)
3886 return false;
3888 std::wstring wnamepart;
3890 if(!Utf8toWStr(args,wnamepart))
3891 return false;
3893 uint32 counter = 0; // Counter for figure out that we found smth.
3895 // converting string that we try to find to lower case
3896 wstrToLower( wnamepart );
3898 uint32 classmask = m_session->GetPlayer()->getClassMask();
3900 for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i)
3902 SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i);
3903 if( !skillInfo )
3904 continue;
3906 if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION &&
3907 skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
3908 continue;
3910 int loc = m_session->GetSessionDbcLocale();
3911 std::string name = skillInfo->name[loc];
3913 if(Utf8FitTo(name, wnamepart))
3915 for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
3917 SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
3918 if( !skillLine )
3919 continue;
3921 if( skillLine->skillId != i || skillLine->forward_spellid )
3922 continue;
3924 // skip racial skills
3925 if( skillLine->racemask != 0 )
3926 continue;
3928 // skip wrong class skills
3929 if( skillLine->classmask && (skillLine->classmask & classmask) == 0)
3930 continue;
3932 SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
3933 if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
3934 continue;
3936 if( !target->HasSpell(spellInfo->Id) )
3937 m_session->GetPlayer()->learnSpell(skillLine->spellId);
3940 uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
3941 target->SetSkill(skillInfo->id, maxLevel, maxLevel);
3942 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
3943 return true;
3947 return false;
3950 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
3953 if (!*args)
3954 return false;
3956 std::string ip = strtok ((char*)args, " ");
3957 char* limit_str = strtok (NULL, " ");
3958 int32 limit = limit_str ? atoi (limit_str) : -1;
3960 loginDatabase.escape_string (ip);
3962 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
3964 return LookupPlayerSearchCommand (result,limit);
3967 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
3969 if (!*args)
3970 return false;
3972 std::string account = strtok ((char*)args, " ");
3973 char* limit_str = strtok (NULL, " ");
3974 int32 limit = limit_str ? atoi (limit_str) : -1;
3976 if (!AccountMgr::normilizeString (account))
3977 return false;
3979 loginDatabase.escape_string (account);
3981 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
3983 return LookupPlayerSearchCommand (result,limit);
3986 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
3989 if (!*args)
3990 return false;
3992 std::string email = strtok ((char*)args, " ");
3993 char* limit_str = strtok (NULL, " ");
3994 int32 limit = limit_str ? atoi (limit_str) : -1;
3996 loginDatabase.escape_string (email);
3998 QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
4000 return LookupPlayerSearchCommand (result,limit);
4003 bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit)
4005 if(!result)
4007 PSendSysMessage(LANG_NO_PLAYERS_FOUND);
4008 SetSentErrorMessage(true);
4009 return false;
4012 int i =0;
4015 Field* fields = result->Fetch();
4016 uint32 acc_id = fields[0].GetUInt32();
4017 std::string acc_name = fields[1].GetCppString();
4019 QueryResult* chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
4020 if(chars)
4022 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT,acc_name.c_str(),acc_id);
4024 uint64 guid = 0;
4025 std::string name;
4029 Field* charfields = chars->Fetch();
4030 guid = charfields[0].GetUInt64();
4031 name = charfields[1].GetCppString();
4033 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
4034 ++i;
4036 } while( chars->NextRow() && ( limit == -1 || i < limit ) );
4038 delete chars;
4040 } while(result->NextRow());
4042 delete result;
4044 return true;
4047 /// Triggering corpses expire check in world
4048 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4050 CorpsesErase();
4051 return true;