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
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
24 #include "ObjectMgr.h"
27 #include "GameObject.h"
30 #include "ObjectAccessor.h"
31 #include "MapManager.h"
34 #include "GameEvent.h"
36 #include "AccountMgr.h"
37 #include "WaypointManager.h"
43 #include "GlobalEvents.h"
45 #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
47 static uint32 ReputationRankStrIndex
[MAX_REPUTATION_RANK
] =
49 LANG_REP_HATED
, LANG_REP_HOSTILE
, LANG_REP_UNFRIENDLY
, LANG_REP_NEUTRAL
,
50 LANG_REP_FRIENDLY
, LANG_REP_HONORED
, LANG_REP_REVERED
, LANG_REP_EXALTED
53 //mute player for some times
54 bool ChatHandler::HandleMuteCommand(const char* args
)
59 char *charname
= strtok((char*)args
, " ");
63 std::string cname
= charname
;
65 char *timetonotspeak
= strtok(NULL
, " ");
69 uint32 notspeaktime
= (uint32
) atoi(timetonotspeak
);
71 if(!normalizePlayerName(cname
))
73 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
74 SetSentErrorMessage(true);
78 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
81 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
82 SetSentErrorMessage(true);
86 Player
*chr
= objmgr
.GetPlayer(guid
);
89 uint32 account_id
= 0;
94 account_id
= chr
->GetSession()->GetAccountId();
95 security
= chr
->GetSession()->GetSecurity();
99 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
100 security
= accmgr
.GetSecurity(account_id
);
103 if(m_session
&& security
>= m_session
->GetSecurity())
105 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
106 SetSentErrorMessage(true);
110 time_t mutetime
= time(NULL
) + notspeaktime
*60;
113 chr
->GetSession()->m_muteTime
= mutetime
;
115 loginDatabase
.PExecute("UPDATE account SET mutetime = " I64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
118 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
120 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, cname
.c_str(), notspeaktime
);
126 bool ChatHandler::HandleUnmuteCommand(const char* args
)
131 char *charname
= strtok((char*)args
, " ");
135 std::string cname
= charname
;
137 if(!normalizePlayerName(cname
))
139 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
140 SetSentErrorMessage(true);
144 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
147 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
148 SetSentErrorMessage(true);
152 Player
*chr
= objmgr
.GetPlayer(guid
);
155 uint32 account_id
= 0;
160 account_id
= chr
->GetSession()->GetAccountId();
161 security
= chr
->GetSession()->GetSecurity();
165 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
166 security
= accmgr
.GetSecurity(account_id
);
169 if(m_session
&& security
>= m_session
->GetSecurity())
171 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
172 SetSentErrorMessage(true);
180 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
181 SetSentErrorMessage(true);
185 chr
->GetSession()->m_muteTime
= 0;
188 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
191 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
193 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, cname
.c_str());
197 bool ChatHandler::HandleTargetObjectCommand(const char* args
)
199 Player
* pl
= m_session
->GetPlayer();
201 GameEvent::ActiveEvents
const& activeEventsList
= gameeventmgr
.GetActiveEventList();
204 int32 id
= atoi((char*)args
);
206 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",
207 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
210 std::string name
= args
;
211 WorldDatabase
.escape_string(name
);
212 result
= WorldDatabase
.PQuery(
213 "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_ "
214 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
215 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
220 std::ostringstream eventFilter
;
221 eventFilter
<< " AND (event IS NULL ";
222 bool initString
= true;
224 for (GameEvent::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
228 eventFilter
<< "OR event IN (" <<*itr
;
232 eventFilter
<< "," << *itr
;
240 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
241 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
242 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
243 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
248 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
252 Field
*fields
= result
->Fetch();
253 uint32 lowguid
= fields
[0].GetUInt32();
254 uint32 id
= fields
[1].GetUInt32();
255 float x
= fields
[2].GetFloat();
256 float y
= fields
[3].GetFloat();
257 float z
= fields
[4].GetFloat();
258 float o
= fields
[5].GetFloat();
259 int mapid
= fields
[6].GetUInt16();
262 GameObjectInfo
const* goI
= objmgr
.GetGameObjectInfo(id
);
266 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
270 GameObject
* target
= ObjectAccessor::GetGameObject(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
272 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
276 int32 curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
277 if(curRespawnDelay
< 0)
280 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
281 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
283 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
288 //teleport to gameobject
289 bool ChatHandler::HandleGoObjectCommand(const char* args
)
294 Player
* _player
= m_session
->GetPlayer();
296 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
297 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
301 int32 guid
= atoi(cId
);
309 if (GameObjectData
const* go_data
= objmgr
.GetGOData(guid
))
314 ort
= go_data
->orientation
;
315 mapid
= go_data
->mapid
;
319 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
320 SetSentErrorMessage(true);
324 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
326 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
327 SetSentErrorMessage(true);
331 // stop flight if need
332 if(_player
->isInFlight())
334 _player
->GetMotionMaster()->MovementExpired();
335 _player
->m_taxi
.ClearTaxiDestinations();
337 // save only in non-flight case
339 _player
->SaveRecallPosition();
341 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
345 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
347 Player
* _player
= m_session
->GetPlayer();
352 char *atId
= strtok((char*)args
, " ");
356 int32 i_atId
= atoi(atId
);
361 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
364 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
365 SetSentErrorMessage(true);
369 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
371 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
372 SetSentErrorMessage(true);
376 // stop flight if need
377 if(_player
->isInFlight())
379 _player
->GetMotionMaster()->MovementExpired();
380 _player
->m_taxi
.ClearTaxiDestinations();
382 // save only in non-flight case
384 _player
->SaveRecallPosition();
386 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
390 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
392 Player
* _player
= m_session
->GetPlayer();
397 char *gyId
= strtok((char*)args
, " ");
401 int32 i_gyId
= atoi(gyId
);
406 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
409 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
410 SetSentErrorMessage(true);
414 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
416 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
417 SetSentErrorMessage(true);
421 // stop flight if need
422 if(_player
->isInFlight())
424 _player
->GetMotionMaster()->MovementExpired();
425 _player
->m_taxi
.ClearTaxiDestinations();
427 // save only in non-flight case
429 _player
->SaveRecallPosition();
431 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
435 /** \brief Teleport the GM to the specified creature
437 * .gocreature <GUID> --> TP using creature.guid
438 * .gocreature azuregos --> TP player to the mob with this name
439 * Warning: If there is more than one mob with this name
440 * you will be teleported to the first one that is found.
441 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
442 * Warning: If there is more than one mob with this "id"
443 * you will be teleported to the first one that is found.
445 //teleport to creature
446 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
450 Player
* _player
= m_session
->GetPlayer();
452 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
453 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
457 std::ostringstream whereClause
;
459 // User wants to teleport to the NPC's template entry
460 if( strcmp(pParam1
, "id") == 0 )
462 //sLog.outError("DEBUG: ID found");
464 // Get the "creature_template.entry"
465 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
466 char* tail
= strtok(NULL
,"");
469 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
473 int32 tEntry
= atoi(cId
);
474 //sLog.outError("DEBUG: ID value: %d", tEntry);
478 whereClause
<< "WHERE id = '" << tEntry
<< "'";
482 //sLog.outError("DEBUG: ID *not found*");
484 int32 guid
= atoi(pParam1
);
486 // Number is invalid - maybe the user specified the mob's name
489 std::string name
= pParam1
;
490 WorldDatabase
.escape_string(name
);
491 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
495 whereClause
<< "WHERE guid = '" << guid
<< "'";
498 //sLog.outError("DEBUG: %s", whereClause.c_str());
500 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
503 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
504 SetSentErrorMessage(true);
507 if( result
->GetRowCount() > 1 )
509 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
512 Field
*fields
= result
->Fetch();
513 float x
= fields
[0].GetFloat();
514 float y
= fields
[1].GetFloat();
515 float z
= fields
[2].GetFloat();
516 float ort
= fields
[3].GetFloat();
517 int mapid
= fields
[4].GetUInt16();
521 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
523 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
524 SetSentErrorMessage(true);
528 // stop flight if need
529 if(_player
->isInFlight())
531 _player
->GetMotionMaster()->MovementExpired();
532 _player
->m_taxi
.ClearTaxiDestinations();
534 // save only in non-flight case
536 _player
->SaveRecallPosition();
538 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
542 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
544 uint64 guid
= m_session
->GetPlayer()->GetSelection();
548 SendSysMessage(LANG_NO_SELECTION
);
549 SetSentErrorMessage(true);
553 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
557 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
562 // Can be NULL at console call
563 Player
*target
= getSelectedPlayer ();
565 std::string namepart
= args
;
566 std::wstring wnamepart
;
568 if (!Utf8toWStr (namepart
,wnamepart
))
571 // converting string that we try to find to lower case
572 wstrToLower (wnamepart
);
574 uint32 counter
= 0; // Counter for figure out that we found smth.
576 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
578 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
581 FactionState
const* repState
= NULL
;
584 FactionStateList::const_iterator repItr
= target
->m_factions
.find (factionEntry
->reputationListID
);
585 if(repItr
!= target
->m_factions
.end())
586 repState
= &repItr
->second
;
590 int loc
= m_session
? m_session
->GetSessionDbcLocale() : sWorld
.GetDefaultDbcLocale();
591 std::string name
= factionEntry
->name
[loc
];
595 if (!Utf8FitTo(name
, wnamepart
))
598 for(; loc
< MAX_LOCALE
; ++loc
)
600 if(m_session
&& loc
==m_session
->GetSessionDbcLocale())
603 name
= factionEntry
->name
[loc
];
607 if (Utf8FitTo(name
, wnamepart
))
614 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
615 // or "id - [faction] [no reputation]" format
616 std::ostringstream ss
;
618 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
620 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
622 if (repState
) // and then target!=NULL also
624 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
625 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
627 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
629 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
630 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
631 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
632 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
633 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
634 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
635 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
636 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
637 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
638 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
639 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
640 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
643 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
645 SendSysMessage(ss
.str().c_str());
651 if (counter
== 0) // if counter == 0 then we found nth
652 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
656 bool ChatHandler::HandleModifyRepCommand(const char * args
)
658 if (!*args
) return false;
660 Player
* target
= NULL
;
661 target
= getSelectedPlayer();
665 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
666 SetSentErrorMessage(true);
670 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
674 uint32 factionId
= atoi(factionTxt
);
677 char *rankTxt
= strtok(NULL
, " ");
678 if (!factionTxt
|| !rankTxt
)
681 amount
= atoi(rankTxt
);
682 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
684 std::string rankStr
= rankTxt
;
685 std::wstring wrankStr
;
686 if(!Utf8toWStr(rankStr
,wrankStr
))
688 wstrToLower( wrankStr
);
692 for (; r
< MAX_REPUTATION_RANK
; ++r
)
694 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
699 if(!Utf8toWStr(rank
,wrank
))
704 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
706 char *deltaTxt
= strtok(NULL
, " ");
709 int32 delta
= atoi(deltaTxt
);
710 if ((delta
< 0) || (delta
> Player::ReputationRank_Length
[r
] -1))
712 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (Player::ReputationRank_Length
[r
]-1));
713 SetSentErrorMessage(true);
720 amount
+= Player::ReputationRank_Length
[r
];
722 if (r
>= MAX_REPUTATION_RANK
)
724 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
725 SetSentErrorMessage(true);
730 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
734 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
735 SetSentErrorMessage(true);
739 if (factionEntry
->reputationListID
< 0)
741 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
);
742 SetSentErrorMessage(true);
746 target
->SetFactionReputation(factionEntry
,amount
);
747 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
, target
->GetName(), target
->GetReputation(factionId
));
751 bool ChatHandler::HandleNameCommand(const char* args
)
757 if(strlen((char*)args)>75)
759 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
763 for (uint8 i = 0; i < strlen(args); i++)
765 if(!isalpha(args[i]) && args[i]!=' ')
767 SendSysMessage(LANG_CHARS_ONLY);
773 guid = m_session->GetPlayer()->GetSelection();
776 SendSysMessage(LANG_NO_SELECTION);
780 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
784 SendSysMessage(LANG_SELECT_CREATURE);
788 pCreature->SetName(args);
789 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
790 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
792 pCreature->SaveToDB();
798 bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
805 if(strlen((char*)args)>75)
808 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
812 for (uint8 i = 0; i < strlen(args); i++)
814 if(!isalpha(args[i]) && args[i]!=' ')
816 SendSysMessage(LANG_CHARS_ONLY);
821 guid = m_session->GetPlayer()->GetSelection();
824 SendSysMessage(LANG_NO_SELECTION);
828 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
832 SendSysMessage(LANG_SELECT_CREATURE);
836 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
837 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
839 pCreature->SaveToDB();
844 //move item to other slot
845 bool ChatHandler::HandleItemMoveCommand(const char* args
)
849 uint8 srcslot
, dstslot
;
851 char* pParam1
= strtok((char*)args
, " ");
855 char* pParam2
= strtok(NULL
, " ");
859 srcslot
= (uint8
)atoi(pParam1
);
860 dstslot
= (uint8
)atoi(pParam2
);
865 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,srcslot
))
868 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
))
871 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
872 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
874 m_session
->GetPlayer()->SwapItem( src
, dst
);
879 //add spawn of creature
880 bool ChatHandler::HandleNpcAddCommand(const char* args
)
884 char* charID
= strtok((char*)args
, " ");
888 char* team
= strtok(NULL
, " ");
890 if (team
) { teamval
= atoi(team
); }
891 if (teamval
< 0) { teamval
= 0; }
893 uint32 id
= atoi(charID
);
895 Player
*chr
= m_session
->GetPlayer();
896 float x
= chr
->GetPositionX();
897 float y
= chr
->GetPositionY();
898 float z
= chr
->GetPositionZ();
899 float o
= chr
->GetOrientation();
900 Map
*map
= chr
->GetMap();
902 Creature
* pCreature
= new Creature
;
903 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, (uint32
)teamval
))
909 pCreature
->Relocate(x
,y
,z
,o
);
911 if(!pCreature
->IsPositionValid())
913 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());
918 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
920 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
922 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
923 pCreature
->LoadFromDB(db_guid
, map
);
926 objmgr
.AddCreatureToGrid(db_guid
, objmgr
.GetCreatureData(db_guid
));
930 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
932 Creature
* unit
= NULL
;
936 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
937 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
941 uint32 lowguid
= atoi(cId
);
945 if (CreatureData
const* cr_data
= objmgr
.GetCreatureData(lowguid
))
946 unit
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
949 unit
= getSelectedCreature();
951 if(!unit
|| unit
->isPet() || unit
->isTotem())
953 SendSysMessage(LANG_SELECT_CREATURE
);
954 SetSentErrorMessage(true);
958 // Delete the creature
960 unit
->DeleteFromDB();
961 unit
->CleanupsBeforeDelete();
962 unit
->AddObjectToRemoveList();
964 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
969 //delete object by selection or guid
970 bool ChatHandler::HandleDelObjectCommand(const char* args
)
972 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
973 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
977 uint32 lowguid
= atoi(cId
);
981 GameObject
* obj
= NULL
;
984 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
985 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
989 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
990 SetSentErrorMessage(true);
994 uint64 owner_guid
= obj
->GetOwnerGUID();
997 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
998 if(!owner
&& !IS_PLAYER_GUID(owner_guid
))
1000 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
1001 SetSentErrorMessage(true);
1005 owner
->RemoveGameObject(obj
,false);
1008 obj
->SetRespawnTime(0); // not save respawn time
1010 obj
->DeleteFromDB();
1012 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
1017 //turn selected object
1018 bool ChatHandler::HandleTurnObjectCommand(const char* args
)
1020 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
1021 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1025 uint32 lowguid
= atoi(cId
);
1029 GameObject
* obj
= NULL
;
1032 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1033 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1037 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1038 SetSentErrorMessage(true);
1042 char* po
= strtok(NULL
, " ");
1047 o
= (float)atof(po
);
1051 Player
*chr
= m_session
->GetPlayer();
1052 o
= chr
->GetOrientation();
1055 float rot2
= sin(o
/2);
1056 float rot3
= cos(o
/2);
1058 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
1059 map
->Remove(obj
,false);
1061 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
1063 obj
->SetFloatValue(GAMEOBJECT_FACING
, o
);
1064 obj
->SetFloatValue(GAMEOBJECT_ROTATION
+2, rot2
);
1065 obj
->SetFloatValue(GAMEOBJECT_ROTATION
+3, rot3
);
1072 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), o
);
1077 //move selected creature
1078 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1082 Creature
* pCreature
= getSelectedCreature();
1086 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1087 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1091 uint32 lowguid
= atoi(cId
);
1093 /* FIXME: impossibel without entry
1095 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1098 // Attempting creature load from DB data
1101 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1104 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1105 SetSentErrorMessage(true);
1109 uint32 map_id
= data
->mapid
;
1111 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1113 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1114 SetSentErrorMessage(true);
1120 lowguid
= pCreature
->GetDBTableGUIDLow();
1125 lowguid
= pCreature
->GetDBTableGUIDLow();
1128 float x
= m_session
->GetPlayer()->GetPositionX();
1129 float y
= m_session
->GetPlayer()->GetPositionY();
1130 float z
= m_session
->GetPlayer()->GetPositionZ();
1131 float o
= m_session
->GetPlayer()->GetOrientation();
1135 if(CreatureData
const* data
= objmgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1137 const_cast<CreatureData
*>(data
)->posX
= x
;
1138 const_cast<CreatureData
*>(data
)->posY
= y
;
1139 const_cast<CreatureData
*>(data
)->posZ
= z
;
1140 const_cast<CreatureData
*>(data
)->orientation
= o
;
1142 MapManager::Instance().GetMap(pCreature
->GetMapId(),pCreature
)->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1143 pCreature
->GetMotionMaster()->Initialize();
1144 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1146 pCreature
->setDeathState(JUST_DIED
);
1147 pCreature
->Respawn();
1151 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1152 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1156 //move selected object
1157 bool ChatHandler::HandleMoveObjectCommand(const char* args
)
1159 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1160 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1164 uint32 lowguid
= atoi(cId
);
1168 GameObject
* obj
= NULL
;
1171 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1172 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1176 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1177 SetSentErrorMessage(true);
1181 char* px
= strtok(NULL
, " ");
1182 char* py
= strtok(NULL
, " ");
1183 char* pz
= strtok(NULL
, " ");
1187 Player
*chr
= m_session
->GetPlayer();
1189 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
1190 map
->Remove(obj
,false);
1192 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
1193 obj
->SetFloatValue(GAMEOBJECT_POS_X
, chr
->GetPositionX());
1194 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, chr
->GetPositionY());
1195 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, chr
->GetPositionZ());
1204 float x
= (float)atof(px
);
1205 float y
= (float)atof(py
);
1206 float z
= (float)atof(pz
);
1208 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
1210 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
1211 SetSentErrorMessage(true);
1215 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
1216 map
->Remove(obj
,false);
1218 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
1219 obj
->SetFloatValue(GAMEOBJECT_POS_X
, x
);
1220 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, y
);
1221 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, z
);
1229 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow());
1234 //demorph player or unit
1235 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1237 Unit
*target
= getSelectedUnit();
1239 target
= m_session
->GetPlayer();
1246 //add item in vendorlist
1247 bool ChatHandler::HandleAddVendorItemCommand(const char* args
)
1252 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1255 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1256 SetSentErrorMessage(true);
1260 uint32 itemId
= atol(pitem
);
1262 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1263 uint32 maxcount
= 0;
1265 maxcount
= atol(fmaxcount
);
1267 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1268 uint32 incrtime
= 0;
1270 incrtime
= atol(fincrtime
);
1272 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1273 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1275 Creature
* vendor
= getSelectedCreature();
1277 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1279 if(!objmgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1281 SetSentErrorMessage(true);
1285 objmgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1287 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1289 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1293 //del item from vendor list
1294 bool ChatHandler::HandleDelVendorItemCommand(const char* args
)
1299 Creature
* vendor
= getSelectedCreature();
1300 if (!vendor
|| !vendor
->isVendor())
1302 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1303 SetSentErrorMessage(true);
1307 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1310 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1311 SetSentErrorMessage(true);
1314 uint32 itemId
= atol(pitem
);
1316 if(!objmgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1318 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1319 SetSentErrorMessage(true);
1323 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1325 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1329 //add move for creature
1330 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1335 char* guid_str
= strtok((char*)args
, " ");
1336 char* wait_str
= strtok((char*)NULL
, " ");
1338 uint32 lowguid
= atoi((char*)guid_str
);
1340 Creature
* pCreature
= NULL
;
1342 /* FIXME: impossible without entry
1344 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1347 // attempt check creature existence by DB data
1350 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1353 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1354 SetSentErrorMessage(true);
1360 // obtain real GUID for DB operations
1361 lowguid
= pCreature
->GetDBTableGUIDLow();
1364 int wait
= wait_str
? atoi(wait_str
) : 0;
1369 Player
* player
= m_session
->GetPlayer();
1371 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1373 // update movement type
1374 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1377 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1378 pCreature
->GetMotionMaster()->Initialize();
1379 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1381 pCreature
->setDeathState(JUST_DIED
);
1382 pCreature
->Respawn();
1384 pCreature
->SaveToDB();
1387 SendSysMessage(LANG_WAYPOINT_ADDED
);
1393 * Set the movement type for an NPC.<br/>
1395 * Valid movement types are:
1397 * <li> stay - NPC wont move </li>
1398 * <li> random - NPC will move randomly according to the spawndist </li>
1399 * <li> way - NPC will move with given waypoints set </li>
1401 * additional parameter: NODEL - so no waypoints are deleted, if you
1402 * change the movement type
1404 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1410 // GUID (optional - you can also select the creature)
1411 // stay|random|way (determines the kind of movement)
1412 // NODEL (optional - tells the system NOT to delete any waypoints)
1413 // this is very handy if you want to do waypoints, that are
1414 // later switched on/off according to special events (like escort
1416 char* guid_str
= strtok((char*)args
, " ");
1417 char* type_str
= strtok((char*)NULL
, " ");
1418 char* dontdel_str
= strtok((char*)NULL
, " ");
1420 bool doNotDelete
= false;
1426 Creature
* pCreature
= NULL
;
1430 //sLog.outError("DEBUG: All 3 params are set");
1432 // All 3 params are set
1436 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1438 //sLog.outError("DEBUG: doNotDelete = true;");
1444 // Only 2 params - but maybe NODEL is set
1447 sLog
.outError("DEBUG: Only 2 params ");
1448 if( stricmp( type_str
, "NODEL" ) == 0 )
1450 //sLog.outError("DEBUG: type_str, NODEL ");
1457 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1459 type_str
= guid_str
;
1460 pCreature
= getSelectedCreature();
1461 if(!pCreature
|| pCreature
->isPet())
1463 lowguid
= pCreature
->GetDBTableGUIDLow();
1465 else // case .setmovetype #creature_guid $move_type (with selected creature)
1467 lowguid
= atoi((char*)guid_str
);
1469 /* impossible without entry
1471 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1474 // attempt check creature existence by DB data
1477 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1480 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1481 SetSentErrorMessage(true);
1487 lowguid
= pCreature
->GetDBTableGUIDLow();
1491 // now lowguid is low guid really existed creature
1492 // and pCreature point (maybe) to this creature or NULL
1494 MovementGeneratorType move_type
;
1496 std::string type
= type_str
;
1499 move_type
= IDLE_MOTION_TYPE
;
1500 else if(type
== "random")
1501 move_type
= RANDOM_MOTION_TYPE
;
1502 else if(type
== "way")
1503 move_type
= WAYPOINT_MOTION_TYPE
;
1507 // update movement type
1508 if(doNotDelete
== false)
1509 WaypointMgr
.DeletePath(lowguid
);
1513 pCreature
->SetDefaultMovementType(move_type
);
1514 pCreature
->GetMotionMaster()->Initialize();
1515 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1517 pCreature
->setDeathState(JUST_DIED
);
1518 pCreature
->Respawn();
1520 pCreature
->SaveToDB();
1522 if( doNotDelete
== false )
1524 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1528 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1532 } // HandleNpcSetMoveTypeCommand
1534 //change level of creature or pet
1535 bool ChatHandler::HandleChangeLevelCommand(const char* args
)
1540 uint8 lvl
= (uint8
) atoi((char*)args
);
1541 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1543 SendSysMessage(LANG_BAD_VALUE
);
1544 SetSentErrorMessage(true);
1548 Creature
* pCreature
= getSelectedCreature();
1551 SendSysMessage(LANG_SELECT_CREATURE
);
1552 SetSentErrorMessage(true);
1556 if(pCreature
->isPet())
1558 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1562 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1563 pCreature
->SetHealth( 100 + 30*lvl
);
1564 pCreature
->SetLevel( lvl
);
1565 pCreature
->SaveToDB();
1571 //set npcflag of creature
1572 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1577 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1579 Creature
* pCreature
= getSelectedCreature();
1583 SendSysMessage(LANG_SELECT_CREATURE
);
1584 SetSentErrorMessage(true);
1588 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1590 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1592 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1597 //set model of creature
1598 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1603 uint32 displayId
= (uint32
) atoi((char*)args
);
1605 Creature
*pCreature
= getSelectedCreature();
1607 if(!pCreature
|| pCreature
->isPet())
1609 SendSysMessage(LANG_SELECT_CREATURE
);
1610 SetSentErrorMessage(true);
1614 pCreature
->SetDisplayId(displayId
);
1615 pCreature
->SetNativeDisplayId(displayId
);
1617 pCreature
->SaveToDB();
1622 //morph creature or player
1623 bool ChatHandler::HandleMorphCommand(const char* args
)
1628 uint16 display_id
= (uint16
)atoi((char*)args
);
1630 Unit
*target
= getSelectedUnit();
1632 target
= m_session
->GetPlayer();
1634 target
->SetDisplayId(display_id
);
1639 //set faction of creature
1640 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1645 uint32 factionId
= (uint32
) atoi((char*)args
);
1647 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1649 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1650 SetSentErrorMessage(true);
1654 Creature
* pCreature
= getSelectedCreature();
1658 SendSysMessage(LANG_SELECT_CREATURE
);
1659 SetSentErrorMessage(true);
1663 pCreature
->setFaction(factionId
);
1665 // faction is set in creature_template - not inside creature
1668 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1670 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1671 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1675 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1681 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
1683 char* kickName
= strtok((char*)args
, " ");
1686 Player
* player
= getSelectedPlayer();
1690 SendSysMessage(LANG_NO_CHAR_SELECTED
);
1691 SetSentErrorMessage(true);
1695 if(player
==m_session
->GetPlayer())
1697 SendSysMessage(LANG_COMMAND_KICKSELF
);
1698 SetSentErrorMessage(true);
1702 player
->GetSession()->KickPlayer();
1706 std::string name
= kickName
;
1707 if(!normalizePlayerName(name
))
1709 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1710 SetSentErrorMessage(true);
1714 if(m_session
&& name
==m_session
->GetPlayer()->GetName())
1716 SendSysMessage(LANG_COMMAND_KICKSELF
);
1717 SetSentErrorMessage(true);
1721 if(sWorld
.KickPlayer(name
))
1723 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,name
.c_str());
1726 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER
,name
.c_str());
1732 //show info of player
1733 bool ChatHandler::HandlePInfoCommand(const char* args
)
1735 Player
* target
= NULL
;
1736 uint64 targetGUID
= 0;
1738 char* px
= strtok((char*)args
, " ");
1750 if(!normalizePlayerName(name
))
1752 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1753 SetSentErrorMessage(true);
1757 target
= objmgr
.GetPlayer(name
.c_str());
1759 py
= strtok(NULL
, " ");
1762 targetGUID
= objmgr
.GetPlayerGUIDByName(name
);
1764 py
= strtok(NULL
, " ");
1770 if(!target
&& !targetGUID
)
1772 target
= getSelectedPlayer();
1775 if(!target
&& !targetGUID
)
1777 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1778 SetSentErrorMessage(true);
1784 uint32 total_player_time
= 0;
1788 // get additional information from Player object
1791 targetGUID
= target
->GetGUID();
1792 name
= target
->GetName(); // re-read for case getSelectedPlayer() target
1793 accId
= target
->GetSession()->GetAccountId();
1794 money
= target
->GetMoney();
1795 total_player_time
= target
->GetTotalPlayedTime();
1796 level
= target
->getLevel();
1797 latency
= target
->GetSession()->GetLatency();
1799 // get additional information from DB
1803 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID
));
1806 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1807 SetSentErrorMessage(true);
1810 Field
*fields
= result
->Fetch();
1811 total_player_time
= fields
[0].GetUInt32();
1815 if (!Player::LoadValuesArrayFromDB(data
,targetGUID
))
1817 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1818 SetSentErrorMessage(true);
1822 money
= Player::GetUInt32ValueFromArray(data
, PLAYER_FIELD_COINAGE
);
1823 level
= Player::GetUInt32ValueFromArray(data
, UNIT_FIELD_LEVEL
);
1825 accId
= objmgr
.GetPlayerAccountIdByGUID(targetGUID
);
1828 std::string username
= GetMangosString(LANG_ERROR
);
1829 std::string last_ip
= GetMangosString(LANG_ERROR
);
1830 uint32 security
= 0;
1831 std::string last_login
= GetMangosString(LANG_ERROR
);
1833 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
1836 Field
* fields
= result
->Fetch();
1837 username
= fields
[0].GetCppString();
1838 security
= fields
[1].GetUInt32();
1840 if(!m_session
|| m_session
->GetSecurity() >= security
)
1842 last_ip
= fields
[2].GetCppString();
1843 last_login
= fields
[3].GetCppString();
1854 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
);
1856 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
1857 uint32 gold
= money
/GOLD
;
1858 uint32 silv
= (money
% GOLD
) / SILVER
;
1859 uint32 copp
= (money
% GOLD
) % SILVER
;
1860 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
1862 if ( py
&& strncmp(py
, "rep", 3) == 0 )
1866 // rep option not implemented for offline case
1867 SendSysMessage(LANG_PINFO_NO_REP
);
1868 SetSentErrorMessage(true);
1873 for(FactionStateList::const_iterator itr
= target
->m_factions
.begin(); itr
!= target
->m_factions
.end(); ++itr
)
1875 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
1877 FactionName
= factionEntry
->name
[m_session
->GetSessionDbcLocale()];
1879 FactionName
= "#Not found#";
1880 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
1881 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
1882 std::ostringstream ss
;
1883 ss
<< itr
->second
.ID
<< ": |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << FactionName
<< "]|h|r " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
1885 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
1886 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
1887 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
1888 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
1889 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
1890 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
1891 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
1892 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
1893 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
1894 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
1895 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
1896 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
1898 SendSysMessage(ss
.str().c_str());
1905 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
1908 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
1909 name
= GetMangosString(LANG_UNKNOWN
);
1911 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, name
.c_str(),time
,text
);
1915 bool ChatHandler::HandleTicketCommand(const char* args
)
1917 char* px
= strtok((char*)args
, " ");
1924 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1925 SetSentErrorMessage(true);
1930 QueryResult
*result
= CharacterDatabase
.Query("SELECT COUNT(ticket_id) FROM character_ticket");
1933 count
= (*result
)[0].GetUInt32();
1939 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
1941 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
1946 if(strncmp(px
,"on",3) == 0)
1950 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1951 SetSentErrorMessage(true);
1955 m_session
->GetPlayer()->SetAcceptTicket(true);
1956 SendSysMessage(LANG_COMMAND_TICKETON
);
1961 if(strncmp(px
,"off",4) == 0)
1965 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1966 SetSentErrorMessage(true);
1970 m_session
->GetPlayer()->SetAcceptTicket(false);
1971 SendSysMessage(LANG_COMMAND_TICKETOFF
);
1979 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
1983 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1985 SetSentErrorMessage(true);
1989 Field
* fields
= result
->Fetch();
1991 uint64 guid
= fields
[0].GetUInt64();
1992 char const* text
= fields
[1].GetString();
1993 char const* time
= fields
[2].GetString();
1995 ShowTicket(guid
,text
,time
);
2000 std::string name
= px
;
2002 if(!normalizePlayerName(name
))
2004 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2005 SetSentErrorMessage(true);
2009 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2014 // ticket $char_name
2015 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid
));
2020 Field
* fields
= result
->Fetch();
2022 char const* text
= fields
[0].GetString();
2023 char const* time
= fields
[1].GetString();
2025 ShowTicket(guid
,text
,time
);
2031 uint32
ChatHandler::GetTicketIDByNum(uint32 num
)
2033 QueryResult
*result
= CharacterDatabase
.Query("SELECT ticket_id FROM character_ticket");
2035 if(!result
|| num
> result
->GetRowCount())
2037 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2042 for(uint32 i
= 1; i
< num
; ++i
)
2045 Field
* fields
= result
->Fetch();
2047 uint32 id
= fields
[0].GetUInt32();
2053 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2055 char* px
= strtok((char*)args
, " ");
2060 if(strncmp(px
,"all",4) == 0)
2062 QueryResult
*result
= CharacterDatabase
.Query("SELECT guid FROM character_ticket");
2067 // notify players about ticket deleting
2070 Field
* fields
= result
->Fetch();
2072 uint64 guid
= fields
[0].GetUInt64();
2074 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2075 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2077 }while(result
->NextRow());
2081 CharacterDatabase
.PExecute("DELETE FROM character_ticket");
2082 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2086 int num
= (uint32
)atoi(px
);
2091 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ticket_id,guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2095 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2097 SetSentErrorMessage(true);
2101 Field
* fields
= result
->Fetch();
2103 uint32 id
= fields
[0].GetUInt32();
2104 uint64 guid
= fields
[1].GetUInt64();
2107 CharacterDatabase
.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id
);
2109 // notify players about ticket deleting
2110 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2112 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2113 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,sender
->GetName());
2116 SendSysMessage(LANG_COMMAND_TICKETDEL
);
2121 std::string name
= px
;
2123 if(!normalizePlayerName(name
))
2125 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2126 SetSentErrorMessage(true);
2130 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2135 // delticket $char_name
2136 CharacterDatabase
.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid
));
2138 // notify players about ticket deleting
2139 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2140 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2142 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,px
);
2146 //set spawn dist of creature
2147 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
2152 float option
= atof((char*)args
);
2155 SendSysMessage(LANG_BAD_VALUE
);
2159 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
2161 mtype
= RANDOM_MOTION_TYPE
;
2163 Creature
*pCreature
= getSelectedCreature();
2164 uint32 u_guidlow
= 0;
2167 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2171 pCreature
->SetRespawnRadius((float)option
);
2172 pCreature
->SetDefaultMovementType(mtype
);
2173 pCreature
->GetMotionMaster()->Initialize();
2174 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
2176 pCreature
->setDeathState(JUST_DIED
);
2177 pCreature
->Respawn();
2180 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
2181 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
2185 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
2190 char* stime
= strtok((char*)args
, " ");
2195 int i_stime
= atoi((char*)stime
);
2199 SendSysMessage(LANG_BAD_VALUE
);
2200 SetSentErrorMessage(true);
2204 Creature
*pCreature
= getSelectedCreature();
2205 uint32 u_guidlow
= 0;
2208 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2212 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
2213 pCreature
->SetRespawnDelay((uint32
)i_stime
);
2214 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
2220 * Add a waypoint to a creature.
2222 * The user can either select an npc or provide its GUID.
2224 * The user can even select a visual waypoint - then the new waypoint
2225 * is placed *after* the selected one - this makes insertion of new
2226 * waypoints possible.
2230 * -> adds a waypoint to the npc with the GUID 12345
2233 * -> adds a waypoint to the currently selected creature
2236 * @param args if the user did not provide a GUID, it is NULL
2238 * @return true - command did succeed, false - something went wrong
2240 bool ChatHandler::HandleWpAddCommand(const char* args
)
2242 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2245 char* guid_str
= NULL
;
2249 guid_str
= strtok((char*)args
, " ");
2254 Creature
* target
= getSelectedCreature();
2255 // Did player provide a GUID?
2258 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2261 // -> Player must have selected a creature
2263 if(!target
|| target
->isPet())
2265 SendSysMessage(LANG_SELECT_CREATURE
);
2266 SetSentErrorMessage(true);
2269 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2271 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2273 QueryResult
*result
=
2274 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2275 target
->GetGUIDLow() );
2278 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2279 // User selected a visual spawnpoint -> get the NPC
2281 // Since we compare float values, we have to deal with
2282 // some difficulties.
2283 // Here we search for all waypoints that only differ in one from 1 thousand
2284 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2285 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2286 const char* maxDIFF
= "0.01";
2287 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 )",
2288 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2291 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2292 SetSentErrorMessage(true);
2298 Field
*fields
= result
->Fetch();
2299 lowguid
= fields
[0].GetUInt32();
2300 point
= fields
[1].GetUInt32();
2301 }while( result
->NextRow() );
2304 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2307 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2308 SetSentErrorMessage(true);
2312 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2315 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2316 SetSentErrorMessage(true);
2322 lowguid
= target
->GetDBTableGUIDLow();
2327 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2330 // Warn if player also selected a creature
2331 // -> Creature selection is ignored <-
2334 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2336 lowguid
= atoi((char*)guid_str
);
2338 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2341 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2342 SetSentErrorMessage(true);
2346 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2347 if(!target
|| target
->isPet())
2349 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2350 SetSentErrorMessage(true);
2354 // lowguid -> GUID of the NPC
2355 // point -> number of the waypoint (if not 0)
2356 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2358 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2360 Player
* player
= m_session
->GetPlayer();
2361 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2363 // update movement type
2366 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2367 target
->GetMotionMaster()->Initialize();
2368 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2370 target
->setDeathState(JUST_DIED
);
2376 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2378 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2381 } // HandleWpAddCommand
2384 * .wp modify emote | spell | text | del | move | add
2386 * add -> add a WP after the selected visual waypoint
2387 * User must select a visual waypoint and then issue ".wp modify add"
2390 * User has selected a visual waypoint before.
2391 * <emoteID> is added to this waypoint. Everytime the
2392 * NPC comes to this waypoint, the emote is called.
2394 * emote <GUID> <WPNUM> <emoteID>
2395 * User has not selected visual waypoint before.
2396 * For the waypoint <WPNUM> for the NPC with <GUID>
2397 * an emote <emoteID> is added.
2398 * Everytime the NPC comes to this waypoint, the emote is called.
2401 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2403 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2405 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2410 // first arg: add del text emote spell waittime move
2411 char* show_str
= strtok((char*)args
, " ");
2417 std::string show
= show_str
;
2419 // Remember: "show" must also be the name of a column!
2420 if( (show
!= "emote") && (show
!= "spell") && (show
!= "text1") && (show
!= "text2")
2421 && (show
!= "text3") && (show
!= "text4") && (show
!= "text5")
2422 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2423 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2428 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2430 // Did user provide a GUID
2431 // or did the user select a creature?
2432 // -> variable lowguid is filled with the GUID of the NPC
2436 Creature
* target
= getSelectedCreature();
2440 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2442 // Did the user select a visual spawnpoint?
2443 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2445 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2446 SetSentErrorMessage(true);
2450 wpGuid
= target
->GetGUIDLow();
2452 // The visual waypoint
2453 QueryResult
*result
=
2454 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2455 target
->GetGUIDLow() );
2458 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2459 SetSentErrorMessage(true);
2462 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2464 Field
*fields
= result
->Fetch();
2465 lowguid
= fields
[0].GetUInt32();
2466 point
= fields
[1].GetUInt32();
2469 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2474 // User did provide <GUID> <WPNUM>
2476 char* guid_str
= strtok((char*)NULL
, " ");
2479 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2482 lowguid
= atoi((char*)guid_str
);
2484 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2487 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2488 SetSentErrorMessage(true);
2492 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2494 char* point_str
= strtok((char*)NULL
, " ");
2497 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2500 point
= atoi((char*)point_str
);
2502 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2504 // Now we need the GUID of the visual waypoint
2505 // -> "del", "move", "add" command
2507 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2510 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2511 SetSentErrorMessage(true);
2515 Field
*fields
= result
->Fetch();
2516 wpGuid
= fields
[0].GetUInt32();
2522 char* arg_str
= NULL
;
2523 // Check for argument
2524 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2526 // Text is enclosed in "<>", all other arguments not
2527 if( show
.find("text") != std::string::npos
)
2528 arg_str
= strtok((char*)NULL
, "<>");
2530 arg_str
= strtok((char*)NULL
, " ");
2534 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2539 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2541 // wpGuid -> GUID of the waypoint creature
2542 // lowguid -> GUID of the NPC
2543 // point -> waypoint number
2545 // Special functions:
2546 // add - move - del -> no args commands
2547 // Add a waypoint after the selected visual
2548 if(show
== "add" && target
)
2550 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2552 // Get the creature for which we read the waypoint
2553 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2556 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2557 SetSentErrorMessage(true);
2561 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2565 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2566 SetSentErrorMessage(true);
2570 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2573 // Add the visual spawnpoint (DB only)
2574 // Adjust the waypoints
2575 // Respawn the owner of the waypoints
2576 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2578 Player
* chr
= m_session
->GetPlayer();
2579 Map
*map
= chr
->GetMap();
2583 npcCreature
->GetMotionMaster()->Initialize();
2584 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2586 npcCreature
->setDeathState(JUST_DIED
);
2587 npcCreature
->Respawn();
2591 // create the waypoint creature
2593 Creature
* wpCreature
= new Creature
;
2594 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
,VISUAL_WAYPOINT
,0))
2596 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2601 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2603 if(!wpCreature
->IsPositionValid())
2605 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());
2610 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2611 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2612 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2613 map
->Add(wpCreature
);
2614 wpGuid
= wpCreature
->GetGUIDLow();
2618 WaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2623 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2627 if(show
== "del" && target
)
2629 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2631 // Get the creature for which we read the waypoint
2632 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2635 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2636 SetSentErrorMessage(true);
2640 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2643 Creature
* wpCreature
= NULL
;
2646 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2647 wpCreature
->DeleteFromDB();
2648 wpCreature
->CleanupsBeforeDelete();
2649 wpCreature
->AddObjectToRemoveList();
2653 // Remove the visual spawnpoint
2654 // Adjust the waypoints
2655 // Respawn the owner of the waypoints
2657 WaypointMgr
.DeleteNode(lowguid
, point
);
2661 // Any waypoints left?
2662 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2665 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2669 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2672 npcCreature
->GetMotionMaster()->Initialize();
2673 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2675 npcCreature
->setDeathState(JUST_DIED
);
2676 npcCreature
->Respawn();
2678 npcCreature
->SaveToDB();
2681 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2685 if(show
== "move" && target
)
2687 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2689 Player
*chr
= m_session
->GetPlayer();
2690 Map
*map
= chr
->GetMap();
2692 // Get the creature for which we read the waypoint
2693 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2696 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2697 SetSentErrorMessage(true);
2701 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2704 Creature
* wpCreature
= NULL
;
2706 // Move the visual spawnpoint
2707 // Respawn the owner of the waypoints
2710 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2711 wpCreature
->DeleteFromDB();
2712 wpCreature
->CleanupsBeforeDelete();
2713 wpCreature
->AddObjectToRemoveList();
2715 Creature
* wpCreature2
= new Creature
;
2716 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, VISUAL_WAYPOINT
, 0))
2718 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2723 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2725 if(!wpCreature2
->IsPositionValid())
2727 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());
2732 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2733 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2734 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2735 map
->Add(wpCreature2
);
2736 //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2739 WaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2743 npcCreature
->GetMotionMaster()->Initialize();
2744 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2746 npcCreature
->setDeathState(JUST_DIED
);
2747 npcCreature
->Respawn();
2750 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2755 // Create creature - npc that has the waypoint
2756 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2759 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2760 SetSentErrorMessage(true);
2764 WaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2766 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2769 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2770 npcCreature
->GetMotionMaster()->Initialize();
2771 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2773 npcCreature
->setDeathState(JUST_DIED
);
2774 npcCreature
->Respawn();
2777 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2783 * .wp show info | on | off
2785 * info -> User has selected a visual waypoint before
2787 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2788 * provided the GUID of the NPC and the number of
2791 * on -> User has selected an NPC; all visual waypoints for this
2792 * NPC are added to the world
2794 * on <GUID> -> User did not select an NPC - instead the GUID of the
2795 * NPC is provided. All visual waypoints for this NPC
2796 * are added from the world.
2798 * off -> User has selected an NPC; all visual waypoints for this
2799 * NPC are removed from the world.
2801 * on <GUID> -> User did not select an NPC - instead the GUID of the
2802 * NPC is provided. All visual waypoints for this NPC
2803 * are removed from the world.
2807 bool ChatHandler::HandleWpShowCommand(const char* args
)
2809 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2814 // first arg: on, off, first, last
2815 char* show_str
= strtok((char*)args
, " ");
2820 // second arg: GUID (optional, if a creature is selected)
2821 char* guid_str
= strtok((char*)NULL
, " ");
2822 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2827 // Did user provide a GUID
2828 // or did the user select a creature?
2829 // -> variable lowguid is filled with the GUID
2830 Creature
* target
= getSelectedCreature();
2831 // Did player provide a GUID?
2834 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2836 // -> Player must have selected a creature
2840 SendSysMessage(LANG_SELECT_CREATURE
);
2841 SetSentErrorMessage(true);
2847 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2849 // Warn if player also selected a creature
2850 // -> Creature selection is ignored <-
2853 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2856 uint32 lowguid
= atoi((char*)guid_str
);
2858 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2861 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2862 SetSentErrorMessage(true);
2866 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2870 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2871 SetSentErrorMessage(true);
2876 uint32 lowguid
= target
->GetDBTableGUIDLow();
2878 std::string show
= show_str
;
2881 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
2883 // Show info for the selected waypoint
2886 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
2888 // Check if the user did specify a visual waypoint
2889 if( target
->GetEntry() != VISUAL_WAYPOINT
)
2891 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2892 SetSentErrorMessage(true);
2896 //PSendSysMessage("wp on, GUID: %u", lowguid);
2898 //pCreature->GetPositionX();
2900 QueryResult
*result
=
2901 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2902 target
->GetGUIDLow() );
2905 // Since we compare float values, we have to deal with
2906 // some difficulties.
2907 // Here we search for all waypoints that only differ in one from 1 thousand
2908 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2909 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2910 const char* maxDIFF
= "0.01";
2911 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
2913 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 )",
2914 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2917 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2918 SetSentErrorMessage(true);
2924 Field
*fields
= result
->Fetch();
2925 uint32 creGUID
= fields
[0].GetUInt32();
2926 uint32 point
= fields
[1].GetUInt32();
2927 int waittime
= fields
[2].GetUInt32();
2928 uint32 emote
= fields
[3].GetUInt32();
2929 uint32 spell
= fields
[4].GetUInt32();
2930 const char * text1
= fields
[5].GetString();
2931 const char * text2
= fields
[6].GetString();
2932 const char * text3
= fields
[7].GetString();
2933 const char * text4
= fields
[8].GetString();
2934 const char * text5
= fields
[9].GetString();
2935 uint32 model1
= fields
[10].GetUInt32();
2936 uint32 model2
= fields
[11].GetUInt32();
2938 // Get the creature for which we read the waypoint
2939 Creature
* wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2941 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
2942 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
2943 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
2944 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
2945 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
2946 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
2947 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 1, text1
);
2948 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 2, text2
);
2949 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 3, text3
);
2950 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 4, text4
);
2951 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 5, text5
);
2953 }while( result
->NextRow() );
2961 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
2963 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
2966 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2967 SetSentErrorMessage(true);
2970 // Delete all visuals for this NPC
2971 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
2974 bool hasError
= false;
2977 Field
*fields
= result2
->Fetch();
2978 uint32 wpguid
= fields
[0].GetUInt32();
2979 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2983 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
2985 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
2989 pCreature
->DeleteFromDB();
2990 pCreature
->CleanupsBeforeDelete();
2991 pCreature
->AddObjectToRemoveList();
2994 }while( result2
->NextRow() );
2998 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2999 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3000 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3006 Field
*fields
= result
->Fetch();
3007 uint32 point
= fields
[0].GetUInt32();
3008 float x
= fields
[1].GetFloat();
3009 float y
= fields
[2].GetFloat();
3010 float z
= fields
[3].GetFloat();
3012 uint32 id
= VISUAL_WAYPOINT
;
3014 Player
*chr
= m_session
->GetPlayer();
3015 Map
*map
= chr
->GetMap();
3016 float o
= chr
->GetOrientation();
3018 Creature
* wpCreature
= new Creature
;
3019 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
3021 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3027 wpCreature
->Relocate(x
, y
, z
, o
);
3029 if(!wpCreature
->IsPositionValid())
3031 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());
3037 wpCreature
->SetVisibility(VISIBILITY_OFF
);
3038 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3039 // set "wpguid" column to the visual waypoint
3040 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3042 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3043 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3044 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3045 map
->Add(wpCreature
);
3046 //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
3047 }while( result
->NextRow() );
3056 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3058 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3061 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3062 SetSentErrorMessage(true);
3066 Field
*fields
= result
->Fetch();
3067 float x
= fields
[0].GetFloat();
3068 float y
= fields
[1].GetFloat();
3069 float z
= fields
[2].GetFloat();
3070 uint32 id
= VISUAL_WAYPOINT
;
3072 Player
*chr
= m_session
->GetPlayer();
3073 float o
= chr
->GetOrientation();
3074 Map
*map
= chr
->GetMap();
3076 Creature
* pCreature
= new Creature
;
3077 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, id
, 0))
3079 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3085 pCreature
->Relocate(x
, y
, z
, o
);
3087 if(!pCreature
->IsPositionValid())
3089 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());
3095 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3096 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3097 map
->Add(pCreature
);
3098 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3107 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3109 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3112 Maxpoint
= (*result
)[0].GetUInt32();
3119 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3122 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3123 SetSentErrorMessage(true);
3126 Field
*fields
= result
->Fetch();
3127 float x
= fields
[0].GetFloat();
3128 float y
= fields
[1].GetFloat();
3129 float z
= fields
[2].GetFloat();
3130 uint32 id
= VISUAL_WAYPOINT
;
3132 Player
*chr
= m_session
->GetPlayer();
3133 float o
= chr
->GetOrientation();
3134 Map
*map
= chr
->GetMap();
3136 Creature
* pCreature
= new Creature
;
3137 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
3139 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3145 pCreature
->Relocate(x
, y
, z
, o
);
3147 if(!pCreature
->IsPositionValid())
3149 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());
3155 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3156 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3157 map
->Add(pCreature
);
3158 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3166 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3169 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3170 SetSentErrorMessage(true);
3173 bool hasError
= false;
3176 Field
*fields
= result
->Fetch();
3177 uint32 guid
= fields
[0].GetUInt32();
3178 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3180 //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3184 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3186 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3190 pCreature
->DeleteFromDB();
3191 pCreature
->CleanupsBeforeDelete();
3192 pCreature
->AddObjectToRemoveList();
3194 }while(result
->NextRow());
3195 // set "wpguid" column to "empty" - no visual waypoint spawned
3196 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3200 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3201 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3202 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3205 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3212 PSendSysMessage("DEBUG: wpshow - no valid command found");
3215 } // HandleWpShowCommand
3217 bool ChatHandler::HandleWpExportCommand(const char *args
)
3222 // Next arg is: <GUID> <ARGUMENT>
3224 // Did user provide a GUID
3225 // or did the user select a creature?
3226 // -> variable lowguid is filled with the GUID of the NPC
3228 Creature
* target
= getSelectedCreature();
3229 char* arg_str
= NULL
;
3232 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3233 lowguid
= target
->GetGUIDLow();
3236 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3239 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3242 Field
*fields
= result
->Fetch();
3243 lowguid
= fields
[0].GetUInt32();;
3247 arg_str
= strtok((char*)args
, " ");
3251 // user provided <GUID>
3252 char* guid_str
= strtok((char*)args
, " ");
3255 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3258 lowguid
= atoi((char*)guid_str
);
3260 arg_str
= strtok((char*)NULL
, " ");
3265 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3269 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3271 QueryResult
*result
= WorldDatabase
.PQuery(
3272 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3273 "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
);
3277 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3278 SetSentErrorMessage(true);
3282 std::ofstream outfile
;
3283 outfile
.open (arg_str
);
3287 Field
*fields
= result
->Fetch();
3289 outfile
<< "INSERT INTO creature_movement ";
3290 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
3293 outfile
<< fields
[15].GetUInt32(); // id
3295 outfile
<< fields
[0].GetUInt32(); // point
3297 outfile
<< fields
[1].GetFloat(); // position_x
3299 outfile
<< fields
[2].GetFloat(); // position_y
3301 outfile
<< fields
[3].GetUInt32(); // position_z
3303 outfile
<< fields
[4].GetUInt32(); // orientation
3305 outfile
<< fields
[5].GetUInt32(); // model1
3307 outfile
<< fields
[6].GetUInt32(); // model2
3309 outfile
<< fields
[7].GetUInt16(); // waittime
3311 outfile
<< fields
[8].GetUInt32(); // emote
3313 outfile
<< fields
[9].GetUInt32(); // spell
3315 const char *tmpChar
= fields
[10].GetString();
3318 outfile
<< "NULL"; // text1
3323 outfile
<< tmpChar
; // text1
3327 tmpChar
= fields
[11].GetString();
3330 outfile
<< "NULL"; // text2
3335 outfile
<< tmpChar
; // text2
3339 tmpChar
= fields
[12].GetString();
3342 outfile
<< "NULL"; // text3
3347 outfile
<< tmpChar
; // text3
3351 tmpChar
= fields
[13].GetString();
3354 outfile
<< "NULL"; // text4
3359 outfile
<< tmpChar
; // text4
3363 tmpChar
= fields
[14].GetString();
3366 outfile
<< "NULL"; // text5
3371 outfile
<< tmpChar
; // text5
3376 } while( result
->NextRow() );
3379 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3385 bool ChatHandler::HandleWpImportCommand(const char *args
)
3390 char* arg_str
= strtok((char*)args
, " ");
3395 std::ifstream
infile (arg_str
);
3396 if (infile
.is_open())
3398 while (! infile
.eof() )
3400 getline (infile
,line
);
3401 //cout << line << endl;
3402 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3407 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3413 bool ChatHandler::HandleRenameCommand(const char* args
)
3415 Player
* target
= NULL
;
3416 uint64 targetGUID
= 0;
3417 std::string oldname
;
3419 char* px
= strtok((char*)args
, " ");
3425 if(!normalizePlayerName(oldname
))
3427 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3428 SetSentErrorMessage(true);
3432 target
= objmgr
.GetPlayer(oldname
.c_str());
3435 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3438 if(!target
&& !targetGUID
)
3440 target
= getSelectedPlayer();
3443 if(!target
&& !targetGUID
)
3445 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3446 SetSentErrorMessage(true);
3452 PSendSysMessage(LANG_RENAME_PLAYER
, target
->GetName());
3453 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3454 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3458 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
3459 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3466 bool ChatHandler::HandleGameObjectCommand(const char* args
)
3471 char* pParam1
= strtok((char*)args
, " ");
3475 uint32 id
= atoi((char*)pParam1
);
3479 char* spawntimeSecs
= strtok(NULL
, " ");
3481 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
3485 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
3486 SetSentErrorMessage(true);
3490 Player
*chr
= m_session
->GetPlayer();
3491 float x
= float(chr
->GetPositionX());
3492 float y
= float(chr
->GetPositionY());
3493 float z
= float(chr
->GetPositionZ());
3494 float o
= float(chr
->GetOrientation());
3495 Map
*map
= chr
->GetMap();
3497 float rot2
= sin(o
/2);
3498 float rot3
= cos(o
/2);
3500 GameObject
* pGameObj
= new GameObject
;
3501 uint32 db_lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
3503 if(!pGameObj
->Create(db_lowGUID
, goI
->id
, map
, x
, y
, z
, o
, 0, 0, rot2
, rot3
, 0, 1))
3511 uint32 value
= atoi((char*)spawntimeSecs
);
3512 pGameObj
->SetRespawnTime(value
);
3513 //sLog.outDebug("*** spawntimeSecs: %d", value);
3516 // fill the gameobject data and save to the db
3517 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3519 // this will generate a new guid if the object is in an instance
3520 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
3526 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), goI
->name
, db_lowGUID
, x
, y
, z
, o
);
3530 // TODO: is it really necessary to add both the real and DB table guid here ?
3531 objmgr
.AddGameobjectToGrid(db_lowGUID
, objmgr
.GetGOData(db_lowGUID
));
3533 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,goI
->name
,db_lowGUID
,x
,y
,z
);
3538 bool ChatHandler::HandleAnimCommand(const char* args
)
3543 uint32 anim_id
= atoi((char*)args
);
3544 m_session
->GetPlayer()->HandleEmoteCommand(anim_id
);
3549 bool ChatHandler::HandleStandStateCommand(const char* args
)
3554 uint32 anim_id
= atoi((char*)args
);
3555 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3560 bool ChatHandler::HandleAddHonorCommand(const char* args
)
3565 Player
*target
= getSelectedPlayer();
3568 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3569 SetSentErrorMessage(true);
3573 uint32 amount
= (uint32
)atoi(args
);
3574 target
->RewardHonor(NULL
, 1, amount
);
3578 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3580 Unit
*target
= getSelectedUnit();
3583 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3584 SetSentErrorMessage(true);
3588 m_session
->GetPlayer()->RewardHonor(target
, 1);
3592 bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3594 Player
*target
= getSelectedPlayer();
3597 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3598 SetSentErrorMessage(true);
3602 target
->UpdateHonorFields();
3606 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3611 std::string namepart
= args
;
3612 std::wstring wnamepart
;
3614 // converting string that we try to find to lower case
3615 if(!Utf8toWStr(namepart
,wnamepart
))
3618 wstrToLower(wnamepart
);
3622 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3623 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3625 for(uint32 id
= 0; id
< events
.size(); ++id
)
3627 GameEventData
const& eventData
= events
[id
];
3629 std::string descr
= eventData
.description
;
3633 if (Utf8FitTo(descr
, wnamepart
))
3635 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3638 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3640 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3647 SendSysMessage(LANG_NOEVENTFOUND
);
3652 bool ChatHandler::HandleEventActiveListCommand(const char* args
)
3656 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3657 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3659 char const* active
= GetMangosString(LANG_ACTIVE
);
3661 for(GameEvent::ActiveEvents::const_iterator itr
= activeEvents
.begin(); itr
!= activeEvents
.end(); ++itr
)
3663 uint32 event_id
= *itr
;
3664 GameEventData
const& eventData
= events
[event_id
];
3667 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,event_id
,event_id
,eventData
.description
.c_str(),active
);
3669 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,event_id
,eventData
.description
.c_str(),active
);
3675 SendSysMessage(LANG_NOEVENTFOUND
);
3680 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3685 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3686 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3690 uint32 event_id
= atoi(cId
);
3692 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3694 if(event_id
>=events
.size())
3696 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3697 SetSentErrorMessage(true);
3701 GameEventData
const& eventData
= events
[event_id
];
3702 if(!eventData
.isValid())
3704 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3705 SetSentErrorMessage(true);
3709 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3710 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3711 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3713 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3714 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3716 uint32 delay
= gameeventmgr
.NextCheck(event_id
);
3717 time_t nextTime
= time(NULL
)+delay
;
3718 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3720 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3721 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3723 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3724 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3729 bool ChatHandler::HandleEventStartCommand(const char* args
)
3734 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3735 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3739 int32 event_id
= atoi(cId
);
3741 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3743 if(event_id
< 1 || event_id
>=events
.size())
3745 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3746 SetSentErrorMessage(true);
3750 GameEventData
const& eventData
= events
[event_id
];
3751 if(!eventData
.isValid())
3753 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3754 SetSentErrorMessage(true);
3758 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3759 if(activeEvents
.find(event_id
) != activeEvents
.end())
3761 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3762 SetSentErrorMessage(true);
3766 gameeventmgr
.StartEvent(event_id
,true);
3770 bool ChatHandler::HandleEventStopCommand(const char* args
)
3775 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3776 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3780 int32 event_id
= atoi(cId
);
3782 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3784 if(event_id
< 1 || event_id
>=events
.size())
3786 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3787 SetSentErrorMessage(true);
3791 GameEventData
const& eventData
= events
[event_id
];
3792 if(!eventData
.isValid())
3794 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3795 SetSentErrorMessage(true);
3799 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3801 if(activeEvents
.find(event_id
) == activeEvents
.end())
3803 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3804 SetSentErrorMessage(true);
3808 gameeventmgr
.StopEvent(event_id
,true);
3812 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3818 std::string playername
= args
;
3820 if(!normalizePlayerName(playername
))
3822 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3823 SetSentErrorMessage(true);
3827 player
= objmgr
.GetPlayer(playername
.c_str());
3831 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3832 SetSentErrorMessage(true);
3838 player
= getSelectedPlayer();
3841 player
= m_session
->GetPlayer();
3844 player
->CombatStop();
3845 player
->getHostilRefManager().deleteReferences();
3849 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3851 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3853 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3855 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3859 if( skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
)
3861 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3863 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3867 // skip racial skills
3868 if( skillLine
->racemask
!= 0 )
3871 // skip wrong class skills
3872 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3875 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3878 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3879 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3882 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3887 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
3891 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
3893 // Learns all recipes of specified profession and sets skill to max
3894 // Example: .learn all_recipes enchanting
3896 Player
* target
= getSelectedPlayer();
3899 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3906 std::wstring wnamepart
;
3908 if(!Utf8toWStr(args
,wnamepart
))
3911 uint32 counter
= 0; // Counter for figure out that we found smth.
3913 // converting string that we try to find to lower case
3914 wstrToLower( wnamepart
);
3916 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3918 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3920 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3924 if( skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
3925 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
)
3928 int loc
= m_session
->GetSessionDbcLocale();
3929 std::string name
= skillInfo
->name
[loc
];
3931 if(Utf8FitTo(name
, wnamepart
))
3933 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3935 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3939 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3942 // skip racial skills
3943 if( skillLine
->racemask
!= 0 )
3946 // skip wrong class skills
3947 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3950 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3951 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3954 if( !target
->HasSpell(spellInfo
->Id
) )
3955 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3958 uint16 maxLevel
= target
->GetPureMaxSkillValue(skillInfo
->id
);
3959 target
->SetSkill(skillInfo
->id
, maxLevel
, maxLevel
);
3960 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
3968 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
3974 std::string ip
= strtok ((char*)args
, " ");
3975 char* limit_str
= strtok (NULL
, " ");
3976 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3978 loginDatabase
.escape_string (ip
);
3980 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
3982 return LookupPlayerSearchCommand (result
,limit
);
3985 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
3990 std::string account
= strtok ((char*)args
, " ");
3991 char* limit_str
= strtok (NULL
, " ");
3992 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3994 if (!AccountMgr::normilizeString (account
))
3997 loginDatabase
.escape_string (account
);
3999 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
4001 return LookupPlayerSearchCommand (result
,limit
);
4004 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
4010 std::string email
= strtok ((char*)args
, " ");
4011 char* limit_str
= strtok (NULL
, " ");
4012 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4014 loginDatabase
.escape_string (email
);
4016 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
4018 return LookupPlayerSearchCommand (result
,limit
);
4021 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
4025 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4026 SetSentErrorMessage(true);
4033 Field
* fields
= result
->Fetch();
4034 uint32 acc_id
= fields
[0].GetUInt32();
4035 std::string acc_name
= fields
[1].GetCppString();
4037 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4040 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4047 Field
* charfields
= chars
->Fetch();
4048 guid
= charfields
[0].GetUInt64();
4049 name
= charfields
[1].GetCppString();
4051 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4054 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4058 } while(result
->NextRow());
4065 /// Triggering corpses expire check in world
4066 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4072 bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
4074 Player
*target
= getSelectedPlayer();
4078 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4079 SetSentErrorMessage(true);
4084 target
->DurabilityRepairAll(false, 0, false);
4086 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, target
->GetName());
4087 if(needReportToTarget(target
))
4088 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetName());
4092 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4097 Player
*player
= getSelectedPlayer();
4101 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4102 SetSentErrorMessage(true);
4106 if (strncmp(args
, "on", 3) == 0)
4107 player
->SetMovement(MOVE_WATER_WALK
); // ON
4108 else if (strncmp(args
, "off", 4) == 0)
4109 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4112 SendSysMessage(LANG_USE_BOL
);
4116 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, player
->GetName());
4117 if(needReportToTarget(player
))
4118 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetName());
4122 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
4124 Player
*player
= m_session
->GetPlayer();
4125 Creature
*creature
= getSelectedCreature();
4129 PSendSysMessage(LANG_SELECT_CREATURE
);
4130 SetSentErrorMessage(true);
4134 // Follow player - Using pet's default dist and angle
4135 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
4137 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
4141 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
4143 Player
*player
= m_session
->GetPlayer();
4144 Creature
*creature
= getSelectedCreature();
4148 PSendSysMessage(LANG_SELECT_CREATURE
);
4149 SetSentErrorMessage(true);
4153 if (creature
->GetMotionMaster()->empty() ||
4154 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE
)
4156 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4157 SetSentErrorMessage(true);
4161 TargetedMovementGenerator
<Creature
> const* mgen
4162 = static_cast<TargetedMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
4164 if(mgen
->GetTarget()!=player
)
4166 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4167 SetSentErrorMessage(true);
4172 creature
->GetMotionMaster()->MovementExpired(true);
4174 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
4178 bool ChatHandler::HandleNpcTameCommand(const char* args
)
4180 Creature
*creatureTarget
= getSelectedCreature ();
4181 if (!creatureTarget
|| creatureTarget
->isPet ())
4183 PSendSysMessage (LANG_SELECT_CREATURE
);
4184 SetSentErrorMessage (true);
4188 Player
*player
= m_session
->GetPlayer ();
4190 if(player
->GetPetGUID ())
4192 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
4193 SetSentErrorMessage (true);
4197 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
4199 if (!cInfo
->isTameable ())
4201 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4202 SetSentErrorMessage (true);
4206 // Everything looks OK, create new pet
4207 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
4210 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4211 SetSentErrorMessage (true);
4215 // place pet before player
4217 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
4218 pet
->Relocate (x
,y
,z
,M_PI
-player
->GetOrientation ());
4220 // set pet to defensive mode by default (some classes can't control contolled pets in fact).
4221 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
4223 // prepare visual effect for levelup
4224 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
,creatureTarget
->getLevel()-1);
4227 MapManager::Instance().GetMap(pet
->GetMapId(), pet
)->Add((Creature
*)pet
);
4229 // visual effect for levelup
4230 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
,creatureTarget
->getLevel());
4232 // caster have pet now
4233 player
->SetPet(pet
);
4235 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
4236 player
->PetSpellInitialize();