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 "GMTicketMgr.h"
38 #include "WaypointManager.h"
44 #include "GlobalEvents.h"
46 #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
48 static uint32 ReputationRankStrIndex
[MAX_REPUTATION_RANK
] =
50 LANG_REP_HATED
, LANG_REP_HOSTILE
, LANG_REP_UNFRIENDLY
, LANG_REP_NEUTRAL
,
51 LANG_REP_FRIENDLY
, LANG_REP_HONORED
, LANG_REP_REVERED
, LANG_REP_EXALTED
54 //mute player for some times
55 bool ChatHandler::HandleMuteCommand(const char* args
)
60 char *charname
= strtok((char*)args
, " ");
64 std::string cname
= charname
;
66 char *timetonotspeak
= strtok(NULL
, " ");
70 uint32 notspeaktime
= (uint32
) atoi(timetonotspeak
);
72 if(!normalizePlayerName(cname
))
74 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
75 SetSentErrorMessage(true);
79 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
82 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
83 SetSentErrorMessage(true);
87 Player
*chr
= objmgr
.GetPlayer(guid
);
90 uint32 account_id
= 0;
95 account_id
= chr
->GetSession()->GetAccountId();
96 security
= chr
->GetSession()->GetSecurity();
100 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
101 security
= accmgr
.GetSecurity(account_id
);
104 if(m_session
&& security
>= m_session
->GetSecurity())
106 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
107 SetSentErrorMessage(true);
111 time_t mutetime
= time(NULL
) + notspeaktime
*60;
114 chr
->GetSession()->m_muteTime
= mutetime
;
116 loginDatabase
.PExecute("UPDATE account SET mutetime = " I64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
119 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
121 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, cname
.c_str(), notspeaktime
);
127 bool ChatHandler::HandleUnmuteCommand(const char* args
)
132 char *charname
= strtok((char*)args
, " ");
136 std::string cname
= charname
;
138 if(!normalizePlayerName(cname
))
140 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
141 SetSentErrorMessage(true);
145 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
148 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
149 SetSentErrorMessage(true);
153 Player
*chr
= objmgr
.GetPlayer(guid
);
156 uint32 account_id
= 0;
161 account_id
= chr
->GetSession()->GetAccountId();
162 security
= chr
->GetSession()->GetSecurity();
166 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
167 security
= accmgr
.GetSecurity(account_id
);
170 if(m_session
&& security
>= m_session
->GetSecurity())
172 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
173 SetSentErrorMessage(true);
181 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
182 SetSentErrorMessage(true);
186 chr
->GetSession()->m_muteTime
= 0;
189 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
192 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
194 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, cname
.c_str());
198 bool ChatHandler::HandleTargetObjectCommand(const char* args
)
200 Player
* pl
= m_session
->GetPlayer();
202 GameEvent::ActiveEvents
const& activeEventsList
= gameeventmgr
.GetActiveEventList();
205 int32 id
= atoi((char*)args
);
207 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",
208 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
211 std::string name
= args
;
212 WorldDatabase
.escape_string(name
);
213 result
= WorldDatabase
.PQuery(
214 "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_ "
215 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
216 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
221 std::ostringstream eventFilter
;
222 eventFilter
<< " AND (event IS NULL ";
223 bool initString
= true;
225 for (GameEvent::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
229 eventFilter
<< "OR event IN (" <<*itr
;
233 eventFilter
<< "," << *itr
;
241 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
242 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
243 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
244 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
249 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
253 Field
*fields
= result
->Fetch();
254 uint32 lowguid
= fields
[0].GetUInt32();
255 uint32 id
= fields
[1].GetUInt32();
256 float x
= fields
[2].GetFloat();
257 float y
= fields
[3].GetFloat();
258 float z
= fields
[4].GetFloat();
259 float o
= fields
[5].GetFloat();
260 int mapid
= fields
[6].GetUInt16();
263 GameObjectInfo
const* goI
= objmgr
.GetGameObjectInfo(id
);
267 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
271 GameObject
* target
= ObjectAccessor::GetGameObject(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
273 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
277 int32 curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
278 if(curRespawnDelay
< 0)
281 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
282 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
284 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
289 //teleport to gameobject
290 bool ChatHandler::HandleGoObjectCommand(const char* args
)
295 Player
* _player
= m_session
->GetPlayer();
297 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
298 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
302 int32 guid
= atoi(cId
);
310 if (GameObjectData
const* go_data
= objmgr
.GetGOData(guid
))
315 ort
= go_data
->orientation
;
316 mapid
= go_data
->mapid
;
320 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
321 SetSentErrorMessage(true);
325 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
327 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
328 SetSentErrorMessage(true);
332 // stop flight if need
333 if(_player
->isInFlight())
335 _player
->GetMotionMaster()->MovementExpired();
336 _player
->m_taxi
.ClearTaxiDestinations();
338 // save only in non-flight case
340 _player
->SaveRecallPosition();
342 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
346 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
348 Player
* _player
= m_session
->GetPlayer();
353 char *atId
= strtok((char*)args
, " ");
357 int32 i_atId
= atoi(atId
);
362 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
365 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
366 SetSentErrorMessage(true);
370 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
372 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
373 SetSentErrorMessage(true);
377 // stop flight if need
378 if(_player
->isInFlight())
380 _player
->GetMotionMaster()->MovementExpired();
381 _player
->m_taxi
.ClearTaxiDestinations();
383 // save only in non-flight case
385 _player
->SaveRecallPosition();
387 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
391 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
393 Player
* _player
= m_session
->GetPlayer();
398 char *gyId
= strtok((char*)args
, " ");
402 int32 i_gyId
= atoi(gyId
);
407 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
410 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
411 SetSentErrorMessage(true);
415 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
417 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
418 SetSentErrorMessage(true);
422 // stop flight if need
423 if(_player
->isInFlight())
425 _player
->GetMotionMaster()->MovementExpired();
426 _player
->m_taxi
.ClearTaxiDestinations();
428 // save only in non-flight case
430 _player
->SaveRecallPosition();
432 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
436 /** \brief Teleport the GM to the specified creature
438 * .gocreature <GUID> --> TP using creature.guid
439 * .gocreature azuregos --> TP player to the mob with this name
440 * Warning: If there is more than one mob with this name
441 * you will be teleported to the first one that is found.
442 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
443 * Warning: If there is more than one mob with this "id"
444 * you will be teleported to the first one that is found.
446 //teleport to creature
447 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
451 Player
* _player
= m_session
->GetPlayer();
453 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
454 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
458 std::ostringstream whereClause
;
460 // User wants to teleport to the NPC's template entry
461 if( strcmp(pParam1
, "id") == 0 )
463 //sLog.outError("DEBUG: ID found");
465 // Get the "creature_template.entry"
466 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
467 char* tail
= strtok(NULL
,"");
470 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
474 int32 tEntry
= atoi(cId
);
475 //sLog.outError("DEBUG: ID value: %d", tEntry);
479 whereClause
<< "WHERE id = '" << tEntry
<< "'";
483 //sLog.outError("DEBUG: ID *not found*");
485 int32 guid
= atoi(pParam1
);
487 // Number is invalid - maybe the user specified the mob's name
490 std::string name
= pParam1
;
491 WorldDatabase
.escape_string(name
);
492 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
496 whereClause
<< "WHERE guid = '" << guid
<< "'";
499 //sLog.outError("DEBUG: %s", whereClause.c_str());
501 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
504 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
505 SetSentErrorMessage(true);
508 if( result
->GetRowCount() > 1 )
510 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
513 Field
*fields
= result
->Fetch();
514 float x
= fields
[0].GetFloat();
515 float y
= fields
[1].GetFloat();
516 float z
= fields
[2].GetFloat();
517 float ort
= fields
[3].GetFloat();
518 int mapid
= fields
[4].GetUInt16();
522 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
524 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
525 SetSentErrorMessage(true);
529 // stop flight if need
530 if(_player
->isInFlight())
532 _player
->GetMotionMaster()->MovementExpired();
533 _player
->m_taxi
.ClearTaxiDestinations();
535 // save only in non-flight case
537 _player
->SaveRecallPosition();
539 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
543 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
545 uint64 guid
= m_session
->GetPlayer()->GetSelection();
549 SendSysMessage(LANG_NO_SELECTION
);
550 SetSentErrorMessage(true);
554 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
558 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
563 // Can be NULL at console call
564 Player
*target
= getSelectedPlayer ();
566 std::string namepart
= args
;
567 std::wstring wnamepart
;
569 if (!Utf8toWStr (namepart
,wnamepart
))
572 // converting string that we try to find to lower case
573 wstrToLower (wnamepart
);
575 uint32 counter
= 0; // Counter for figure out that we found smth.
577 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
579 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
582 FactionState
const* repState
= NULL
;
585 FactionStateList::const_iterator repItr
= target
->m_factions
.find (factionEntry
->reputationListID
);
586 if(repItr
!= target
->m_factions
.end())
587 repState
= &repItr
->second
;
591 int loc
= m_session
? m_session
->GetSessionDbcLocale() : sWorld
.GetDefaultDbcLocale();
592 std::string name
= factionEntry
->name
[loc
];
596 if (!Utf8FitTo(name
, wnamepart
))
599 for(; loc
< MAX_LOCALE
; ++loc
)
601 if(m_session
&& loc
==m_session
->GetSessionDbcLocale())
604 name
= factionEntry
->name
[loc
];
608 if (Utf8FitTo(name
, wnamepart
))
615 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
616 // or "id - [faction] [no reputation]" format
617 std::ostringstream ss
;
619 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
621 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
623 if (repState
) // and then target!=NULL also
625 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
626 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
628 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
630 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
631 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
632 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
633 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
634 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
635 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
636 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
637 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
638 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
639 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
640 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
641 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
644 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
646 SendSysMessage(ss
.str().c_str());
652 if (counter
== 0) // if counter == 0 then we found nth
653 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
657 bool ChatHandler::HandleModifyRepCommand(const char * args
)
659 if (!*args
) return false;
661 Player
* target
= NULL
;
662 target
= getSelectedPlayer();
666 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
667 SetSentErrorMessage(true);
671 // check online security
672 if (HasLowerSecurity(target
, 0))
675 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
679 uint32 factionId
= atoi(factionTxt
);
682 char *rankTxt
= strtok(NULL
, " ");
683 if (!factionTxt
|| !rankTxt
)
686 amount
= atoi(rankTxt
);
687 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
689 std::string rankStr
= rankTxt
;
690 std::wstring wrankStr
;
691 if(!Utf8toWStr(rankStr
,wrankStr
))
693 wstrToLower( wrankStr
);
697 for (; r
< MAX_REPUTATION_RANK
; ++r
)
699 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
704 if(!Utf8toWStr(rank
,wrank
))
709 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
711 char *deltaTxt
= strtok(NULL
, " ");
714 int32 delta
= atoi(deltaTxt
);
715 if ((delta
< 0) || (delta
> Player::ReputationRank_Length
[r
] -1))
717 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (Player::ReputationRank_Length
[r
]-1));
718 SetSentErrorMessage(true);
725 amount
+= Player::ReputationRank_Length
[r
];
727 if (r
>= MAX_REPUTATION_RANK
)
729 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
730 SetSentErrorMessage(true);
735 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
739 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
740 SetSentErrorMessage(true);
744 if (factionEntry
->reputationListID
< 0)
746 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
);
747 SetSentErrorMessage(true);
751 target
->SetFactionReputation(factionEntry
,amount
);
752 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
, target
->GetName(), target
->GetReputation(factionId
));
756 bool ChatHandler::HandleNameCommand(const char* /*args*/)
762 if(strlen((char*)args)>75)
764 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
768 for (uint8 i = 0; i < strlen(args); i++)
770 if(!isalpha(args[i]) && args[i]!=' ')
772 SendSysMessage(LANG_CHARS_ONLY);
778 guid = m_session->GetPlayer()->GetSelection();
781 SendSysMessage(LANG_NO_SELECTION);
785 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
789 SendSysMessage(LANG_SELECT_CREATURE);
793 pCreature->SetName(args);
794 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
795 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
797 pCreature->SaveToDB();
803 bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
810 if(strlen((char*)args)>75)
813 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
817 for (uint8 i = 0; i < strlen(args); i++)
819 if(!isalpha(args[i]) && args[i]!=' ')
821 SendSysMessage(LANG_CHARS_ONLY);
826 guid = m_session->GetPlayer()->GetSelection();
829 SendSysMessage(LANG_NO_SELECTION);
833 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
837 SendSysMessage(LANG_SELECT_CREATURE);
841 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
842 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
844 pCreature->SaveToDB();
849 //move item to other slot
850 bool ChatHandler::HandleItemMoveCommand(const char* args
)
854 uint8 srcslot
, dstslot
;
856 char* pParam1
= strtok((char*)args
, " ");
860 char* pParam2
= strtok(NULL
, " ");
864 srcslot
= (uint8
)atoi(pParam1
);
865 dstslot
= (uint8
)atoi(pParam2
);
870 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,srcslot
))
873 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
))
876 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
877 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
879 m_session
->GetPlayer()->SwapItem( src
, dst
);
884 //add spawn of creature
885 bool ChatHandler::HandleNpcAddCommand(const char* args
)
889 char* charID
= strtok((char*)args
, " ");
893 char* team
= strtok(NULL
, " ");
895 if (team
) { teamval
= atoi(team
); }
896 if (teamval
< 0) { teamval
= 0; }
898 uint32 id
= atoi(charID
);
900 Player
*chr
= m_session
->GetPlayer();
901 float x
= chr
->GetPositionX();
902 float y
= chr
->GetPositionY();
903 float z
= chr
->GetPositionZ();
904 float o
= chr
->GetOrientation();
905 Map
*map
= chr
->GetMap();
907 Creature
* pCreature
= new Creature
;
908 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, (uint32
)teamval
))
914 pCreature
->Relocate(x
,y
,z
,o
);
916 if(!pCreature
->IsPositionValid())
918 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());
923 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
925 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
927 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
928 pCreature
->LoadFromDB(db_guid
, map
);
931 objmgr
.AddCreatureToGrid(db_guid
, objmgr
.GetCreatureData(db_guid
));
935 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
937 Creature
* unit
= NULL
;
941 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
942 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
946 uint32 lowguid
= atoi(cId
);
950 if (CreatureData
const* cr_data
= objmgr
.GetCreatureData(lowguid
))
951 unit
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
954 unit
= getSelectedCreature();
956 if(!unit
|| unit
->isPet() || unit
->isTotem() || unit
->isVehicle())
958 SendSysMessage(LANG_SELECT_CREATURE
);
959 SetSentErrorMessage(true);
963 // Delete the creature
965 unit
->DeleteFromDB();
966 unit
->CleanupsBeforeDelete();
967 unit
->AddObjectToRemoveList();
969 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
974 //delete object by selection or guid
975 bool ChatHandler::HandleDelObjectCommand(const char* args
)
977 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
978 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
982 uint32 lowguid
= atoi(cId
);
986 GameObject
* obj
= NULL
;
989 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
990 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
994 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
995 SetSentErrorMessage(true);
999 uint64 owner_guid
= obj
->GetOwnerGUID();
1002 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
1003 if(!owner
&& !IS_PLAYER_GUID(owner_guid
))
1005 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
1006 SetSentErrorMessage(true);
1010 owner
->RemoveGameObject(obj
,false);
1013 obj
->SetRespawnTime(0); // not save respawn time
1015 obj
->DeleteFromDB();
1017 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
1022 //turn selected object
1023 bool ChatHandler::HandleTurnObjectCommand(const char* args
)
1025 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
1026 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1030 uint32 lowguid
= atoi(cId
);
1034 GameObject
* obj
= NULL
;
1037 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1038 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1042 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1043 SetSentErrorMessage(true);
1047 char* po
= strtok(NULL
, " ");
1052 o
= (float)atof(po
);
1056 Player
*chr
= m_session
->GetPlayer();
1057 o
= chr
->GetOrientation();
1060 float rot2
= sin(o
/2);
1061 float rot3
= cos(o
/2);
1063 Map
* map
= obj
->GetMap();
1064 map
->Remove(obj
,false);
1066 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
1068 obj
->SetFloatValue(GAMEOBJECT_FACING
, o
);
1069 obj
->SetFloatValue(GAMEOBJECT_PARENTROTATION
+2, rot2
);
1070 obj
->SetFloatValue(GAMEOBJECT_PARENTROTATION
+3, rot3
);
1077 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), o
);
1082 //move selected creature
1083 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1087 Creature
* pCreature
= getSelectedCreature();
1091 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1092 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1096 uint32 lowguid
= atoi(cId
);
1098 /* FIXME: impossibel without entry
1100 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1103 // Attempting creature load from DB data
1106 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1109 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1110 SetSentErrorMessage(true);
1114 uint32 map_id
= data
->mapid
;
1116 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1118 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1119 SetSentErrorMessage(true);
1125 lowguid
= pCreature
->GetDBTableGUIDLow();
1130 lowguid
= pCreature
->GetDBTableGUIDLow();
1133 float x
= m_session
->GetPlayer()->GetPositionX();
1134 float y
= m_session
->GetPlayer()->GetPositionY();
1135 float z
= m_session
->GetPlayer()->GetPositionZ();
1136 float o
= m_session
->GetPlayer()->GetOrientation();
1140 if(CreatureData
const* data
= objmgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1142 const_cast<CreatureData
*>(data
)->posX
= x
;
1143 const_cast<CreatureData
*>(data
)->posY
= y
;
1144 const_cast<CreatureData
*>(data
)->posZ
= z
;
1145 const_cast<CreatureData
*>(data
)->orientation
= o
;
1147 pCreature
->GetMap()->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1148 pCreature
->GetMotionMaster()->Initialize();
1149 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1151 pCreature
->setDeathState(JUST_DIED
);
1152 pCreature
->Respawn();
1156 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1157 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1161 //move selected object
1162 bool ChatHandler::HandleMoveObjectCommand(const char* args
)
1164 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1165 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1169 uint32 lowguid
= atoi(cId
);
1173 GameObject
* obj
= NULL
;
1176 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1177 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1181 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1182 SetSentErrorMessage(true);
1186 char* px
= strtok(NULL
, " ");
1187 char* py
= strtok(NULL
, " ");
1188 char* pz
= strtok(NULL
, " ");
1192 Player
*chr
= m_session
->GetPlayer();
1194 Map
* map
= obj
->GetMap();
1195 map
->Remove(obj
,false);
1197 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
1198 obj
->SetFloatValue(GAMEOBJECT_POS_X
, chr
->GetPositionX());
1199 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, chr
->GetPositionY());
1200 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, chr
->GetPositionZ());
1209 float x
= (float)atof(px
);
1210 float y
= (float)atof(py
);
1211 float z
= (float)atof(pz
);
1213 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
1215 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
1216 SetSentErrorMessage(true);
1220 Map
* map
= obj
->GetMap();
1221 map
->Remove(obj
,false);
1223 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
1224 obj
->SetFloatValue(GAMEOBJECT_POS_X
, x
);
1225 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, y
);
1226 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, z
);
1234 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow());
1239 //demorph player or unit
1240 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1242 Unit
*target
= getSelectedUnit();
1244 target
= m_session
->GetPlayer();
1247 // check online security
1248 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1256 //add item in vendorlist
1257 bool ChatHandler::HandleAddVendorItemCommand(const char* args
)
1262 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1265 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1266 SetSentErrorMessage(true);
1270 uint32 itemId
= atol(pitem
);
1272 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1273 uint32 maxcount
= 0;
1275 maxcount
= atol(fmaxcount
);
1277 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1278 uint32 incrtime
= 0;
1280 incrtime
= atol(fincrtime
);
1282 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1283 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1285 Creature
* vendor
= getSelectedCreature();
1287 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1289 if(!objmgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1291 SetSentErrorMessage(true);
1295 objmgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1297 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1299 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1303 //del item from vendor list
1304 bool ChatHandler::HandleDelVendorItemCommand(const char* args
)
1309 Creature
* vendor
= getSelectedCreature();
1310 if (!vendor
|| !vendor
->isVendor())
1312 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1313 SetSentErrorMessage(true);
1317 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1320 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1321 SetSentErrorMessage(true);
1324 uint32 itemId
= atol(pitem
);
1326 if(!objmgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1328 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1329 SetSentErrorMessage(true);
1333 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1335 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1339 //add move for creature
1340 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1345 char* guid_str
= strtok((char*)args
, " ");
1346 char* wait_str
= strtok((char*)NULL
, " ");
1348 uint32 lowguid
= atoi((char*)guid_str
);
1350 Creature
* pCreature
= NULL
;
1352 /* FIXME: impossible without entry
1354 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1357 // attempt check creature existence by DB data
1360 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1363 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1364 SetSentErrorMessage(true);
1370 // obtain real GUID for DB operations
1371 lowguid
= pCreature
->GetDBTableGUIDLow();
1374 int wait
= wait_str
? atoi(wait_str
) : 0;
1379 Player
* player
= m_session
->GetPlayer();
1381 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1383 // update movement type
1384 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1387 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1388 pCreature
->GetMotionMaster()->Initialize();
1389 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1391 pCreature
->setDeathState(JUST_DIED
);
1392 pCreature
->Respawn();
1394 pCreature
->SaveToDB();
1397 SendSysMessage(LANG_WAYPOINT_ADDED
);
1403 * Set the movement type for an NPC.<br/>
1405 * Valid movement types are:
1407 * <li> stay - NPC wont move </li>
1408 * <li> random - NPC will move randomly according to the spawndist </li>
1409 * <li> way - NPC will move with given waypoints set </li>
1411 * additional parameter: NODEL - so no waypoints are deleted, if you
1412 * change the movement type
1414 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1420 // GUID (optional - you can also select the creature)
1421 // stay|random|way (determines the kind of movement)
1422 // NODEL (optional - tells the system NOT to delete any waypoints)
1423 // this is very handy if you want to do waypoints, that are
1424 // later switched on/off according to special events (like escort
1426 char* guid_str
= strtok((char*)args
, " ");
1427 char* type_str
= strtok((char*)NULL
, " ");
1428 char* dontdel_str
= strtok((char*)NULL
, " ");
1430 bool doNotDelete
= false;
1436 Creature
* pCreature
= NULL
;
1440 //sLog.outError("DEBUG: All 3 params are set");
1442 // All 3 params are set
1446 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1448 //sLog.outError("DEBUG: doNotDelete = true;");
1454 // Only 2 params - but maybe NODEL is set
1457 sLog
.outError("DEBUG: Only 2 params ");
1458 if( stricmp( type_str
, "NODEL" ) == 0 )
1460 //sLog.outError("DEBUG: type_str, NODEL ");
1467 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1469 type_str
= guid_str
;
1470 pCreature
= getSelectedCreature();
1471 if(!pCreature
|| pCreature
->isPet())
1473 lowguid
= pCreature
->GetDBTableGUIDLow();
1475 else // case .setmovetype #creature_guid $move_type (with selected creature)
1477 lowguid
= atoi((char*)guid_str
);
1479 /* impossible without entry
1481 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1484 // attempt check creature existence by DB data
1487 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1490 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1491 SetSentErrorMessage(true);
1497 lowguid
= pCreature
->GetDBTableGUIDLow();
1501 // now lowguid is low guid really existed creature
1502 // and pCreature point (maybe) to this creature or NULL
1504 MovementGeneratorType move_type
;
1506 std::string type
= type_str
;
1509 move_type
= IDLE_MOTION_TYPE
;
1510 else if(type
== "random")
1511 move_type
= RANDOM_MOTION_TYPE
;
1512 else if(type
== "way")
1513 move_type
= WAYPOINT_MOTION_TYPE
;
1517 // update movement type
1518 if(doNotDelete
== false)
1519 WaypointMgr
.DeletePath(lowguid
);
1523 pCreature
->SetDefaultMovementType(move_type
);
1524 pCreature
->GetMotionMaster()->Initialize();
1525 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1527 pCreature
->setDeathState(JUST_DIED
);
1528 pCreature
->Respawn();
1530 pCreature
->SaveToDB();
1532 if( doNotDelete
== false )
1534 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1538 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1542 } // HandleNpcSetMoveTypeCommand
1544 //change level of creature or pet
1545 bool ChatHandler::HandleChangeLevelCommand(const char* args
)
1550 uint8 lvl
= (uint8
) atoi((char*)args
);
1551 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1553 SendSysMessage(LANG_BAD_VALUE
);
1554 SetSentErrorMessage(true);
1558 Creature
* pCreature
= getSelectedCreature();
1561 SendSysMessage(LANG_SELECT_CREATURE
);
1562 SetSentErrorMessage(true);
1566 if(pCreature
->isPet())
1568 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1572 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1573 pCreature
->SetHealth( 100 + 30*lvl
);
1574 pCreature
->SetLevel( lvl
);
1575 pCreature
->SaveToDB();
1581 //set npcflag of creature
1582 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1587 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1589 Creature
* pCreature
= getSelectedCreature();
1593 SendSysMessage(LANG_SELECT_CREATURE
);
1594 SetSentErrorMessage(true);
1598 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1600 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1602 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1607 //set model of creature
1608 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1613 uint32 displayId
= (uint32
) atoi((char*)args
);
1615 Creature
*pCreature
= getSelectedCreature();
1617 if(!pCreature
|| pCreature
->isPet())
1619 SendSysMessage(LANG_SELECT_CREATURE
);
1620 SetSentErrorMessage(true);
1624 pCreature
->SetDisplayId(displayId
);
1625 pCreature
->SetNativeDisplayId(displayId
);
1627 pCreature
->SaveToDB();
1632 //morph creature or player
1633 bool ChatHandler::HandleMorphCommand(const char* args
)
1638 uint16 display_id
= (uint16
)atoi((char*)args
);
1640 Unit
*target
= getSelectedUnit();
1642 target
= m_session
->GetPlayer();
1644 // check online security
1645 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1648 target
->SetDisplayId(display_id
);
1653 //set faction of creature
1654 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1659 uint32 factionId
= (uint32
) atoi((char*)args
);
1661 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1663 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1664 SetSentErrorMessage(true);
1668 Creature
* pCreature
= getSelectedCreature();
1672 SendSysMessage(LANG_SELECT_CREATURE
);
1673 SetSentErrorMessage(true);
1677 pCreature
->setFaction(factionId
);
1679 // faction is set in creature_template - not inside creature
1682 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1684 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1685 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1689 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1695 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
1697 char* kickName
= strtok((char*)args
, " ");
1700 Player
* player
= getSelectedPlayer();
1704 SendSysMessage(LANG_NO_CHAR_SELECTED
);
1705 SetSentErrorMessage(true);
1709 if(player
==m_session
->GetPlayer())
1711 SendSysMessage(LANG_COMMAND_KICKSELF
);
1712 SetSentErrorMessage(true);
1716 // check online security
1717 if (HasLowerSecurity(player
, 0))
1720 player
->GetSession()->KickPlayer();
1724 std::string name
= kickName
;
1725 if(!normalizePlayerName(name
))
1727 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1728 SetSentErrorMessage(true);
1732 if(m_session
&& name
==m_session
->GetPlayer()->GetName())
1734 SendSysMessage(LANG_COMMAND_KICKSELF
);
1735 SetSentErrorMessage(true);
1739 // check online security
1740 Player
* player
= ObjectAccessor::Instance().FindPlayerByName(name
.c_str());
1741 if (player
&& HasLowerSecurity(player
, 0))
1744 if(sWorld
.KickPlayer(name
))
1746 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,name
.c_str());
1749 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER
,name
.c_str());
1755 //show info of player
1756 bool ChatHandler::HandlePInfoCommand(const char* args
)
1758 Player
* target
= NULL
;
1759 uint64 targetGUID
= 0;
1761 char* px
= strtok((char*)args
, " ");
1773 if(!normalizePlayerName(name
))
1775 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1776 SetSentErrorMessage(true);
1780 target
= objmgr
.GetPlayer(name
.c_str());
1782 py
= strtok(NULL
, " ");
1785 targetGUID
= objmgr
.GetPlayerGUIDByName(name
);
1787 py
= strtok(NULL
, " ");
1793 if(!target
&& !targetGUID
)
1795 target
= getSelectedPlayer();
1798 if(!target
&& !targetGUID
)
1800 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1801 SetSentErrorMessage(true);
1807 uint32 total_player_time
= 0;
1811 // get additional information from Player object
1814 // check online security
1815 if (HasLowerSecurity(target
, 0))
1818 targetGUID
= target
->GetGUID();
1819 name
= target
->GetName(); // re-read for case getSelectedPlayer() target
1820 accId
= target
->GetSession()->GetAccountId();
1821 money
= target
->GetMoney();
1822 total_player_time
= target
->GetTotalPlayedTime();
1823 level
= target
->getLevel();
1824 latency
= target
->GetSession()->GetLatency();
1826 // get additional information from DB
1829 // check offline security
1830 if (HasLowerSecurity(NULL
, targetGUID
))
1834 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID
));
1837 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1838 SetSentErrorMessage(true);
1841 Field
*fields
= result
->Fetch();
1842 total_player_time
= fields
[0].GetUInt32();
1846 if (!Player::LoadValuesArrayFromDB(data
,targetGUID
))
1848 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1849 SetSentErrorMessage(true);
1853 money
= Player::GetUInt32ValueFromArray(data
, PLAYER_FIELD_COINAGE
);
1854 level
= Player::GetUInt32ValueFromArray(data
, UNIT_FIELD_LEVEL
);
1856 accId
= objmgr
.GetPlayerAccountIdByGUID(targetGUID
);
1859 std::string username
= GetMangosString(LANG_ERROR
);
1860 std::string last_ip
= GetMangosString(LANG_ERROR
);
1861 uint32 security
= 0;
1862 std::string last_login
= GetMangosString(LANG_ERROR
);
1864 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
1867 Field
* fields
= result
->Fetch();
1868 username
= fields
[0].GetCppString();
1869 security
= fields
[1].GetUInt32();
1871 if(!m_session
|| m_session
->GetSecurity() >= security
)
1873 last_ip
= fields
[2].GetCppString();
1874 last_login
= fields
[3].GetCppString();
1885 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
);
1887 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
1888 uint32 gold
= money
/GOLD
;
1889 uint32 silv
= (money
% GOLD
) / SILVER
;
1890 uint32 copp
= (money
% GOLD
) % SILVER
;
1891 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
1893 if ( py
&& strncmp(py
, "rep", 3) == 0 )
1897 // rep option not implemented for offline case
1898 SendSysMessage(LANG_PINFO_NO_REP
);
1899 SetSentErrorMessage(true);
1904 for(FactionStateList::const_iterator itr
= target
->m_factions
.begin(); itr
!= target
->m_factions
.end(); ++itr
)
1906 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
1908 FactionName
= factionEntry
->name
[m_session
->GetSessionDbcLocale()];
1910 FactionName
= "#Not found#";
1911 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
1912 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
1913 std::ostringstream ss
;
1914 ss
<< itr
->second
.ID
<< ": |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << FactionName
<< "]|h|r " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
1916 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
1917 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
1918 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
1919 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
1920 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
1921 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
1922 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
1923 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
1924 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
1925 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
1926 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
1927 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
1929 SendSysMessage(ss
.str().c_str());
1936 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
1939 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
1940 name
= GetMangosString(LANG_UNKNOWN
);
1942 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, name
.c_str(),time
,text
);
1946 bool ChatHandler::HandleTicketCommand(const char* args
)
1948 char* px
= strtok((char*)args
, " ");
1955 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1956 SetSentErrorMessage(true);
1960 size_t count
= ticketmgr
.GetTicketCount();
1962 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
1964 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
1969 if(strncmp(px
,"on",3) == 0)
1973 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1974 SetSentErrorMessage(true);
1978 m_session
->GetPlayer()->SetAcceptTicket(true);
1979 SendSysMessage(LANG_COMMAND_TICKETON
);
1984 if(strncmp(px
,"off",4) == 0)
1988 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1989 SetSentErrorMessage(true);
1993 m_session
->GetPlayer()->SetAcceptTicket(false);
1994 SendSysMessage(LANG_COMMAND_TICKETOFF
);
2002 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
2006 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2007 SetSentErrorMessage(true);
2011 Field
* fields
= result
->Fetch();
2013 uint32 guid
= fields
[0].GetUInt32();
2014 char const* text
= fields
[1].GetString();
2015 char const* time
= fields
[2].GetString();
2017 ShowTicket(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
),text
,time
);
2022 std::string name
= px
;
2024 if(!normalizePlayerName(name
))
2026 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2027 SetSentErrorMessage(true);
2031 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2036 // ticket $char_name
2037 GMTicket
* ticket
= ticketmgr
.GetGMTicket(GUID_LOPART(guid
));
2041 std::string time
= TimeToTimestampStr(ticket
->GetLastUpdate());
2043 ShowTicket(guid
, ticket
->GetText(), time
.c_str());
2049 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2051 char* px
= strtok((char*)args
, " ");
2056 if(strncmp(px
,"all",4) == 0)
2058 ticketmgr
.DeleteAll();
2059 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2063 int num
= (uint32
)atoi(px
);
2068 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2071 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2072 SetSentErrorMessage(true);
2075 Field
* fields
= result
->Fetch();
2076 uint32 guid
= fields
[0].GetUInt32();
2079 ticketmgr
.Delete(guid
);
2082 if(Player
* pl
= objmgr
.GetPlayer(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
)))
2084 pl
->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2085 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
, pl
->GetName());
2088 PSendSysMessage(LANG_COMMAND_TICKETDEL
);
2093 std::string name
= px
;
2095 if(!normalizePlayerName(name
))
2097 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2098 SetSentErrorMessage(true);
2102 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2107 // delticket $char_name
2108 ticketmgr
.Delete(GUID_LOPART(guid
));
2110 // notify players about ticket deleting
2111 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2112 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2114 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,px
);
2118 //set spawn dist of creature
2119 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
2124 float option
= atof((char*)args
);
2127 SendSysMessage(LANG_BAD_VALUE
);
2131 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
2133 mtype
= RANDOM_MOTION_TYPE
;
2135 Creature
*pCreature
= getSelectedCreature();
2136 uint32 u_guidlow
= 0;
2139 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2143 pCreature
->SetRespawnRadius((float)option
);
2144 pCreature
->SetDefaultMovementType(mtype
);
2145 pCreature
->GetMotionMaster()->Initialize();
2146 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
2148 pCreature
->setDeathState(JUST_DIED
);
2149 pCreature
->Respawn();
2152 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
2153 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
2157 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
2162 char* stime
= strtok((char*)args
, " ");
2167 int i_stime
= atoi((char*)stime
);
2171 SendSysMessage(LANG_BAD_VALUE
);
2172 SetSentErrorMessage(true);
2176 Creature
*pCreature
= getSelectedCreature();
2177 uint32 u_guidlow
= 0;
2180 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2184 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
2185 pCreature
->SetRespawnDelay((uint32
)i_stime
);
2186 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
2192 * Add a waypoint to a creature.
2194 * The user can either select an npc or provide its GUID.
2196 * The user can even select a visual waypoint - then the new waypoint
2197 * is placed *after* the selected one - this makes insertion of new
2198 * waypoints possible.
2202 * -> adds a waypoint to the npc with the GUID 12345
2205 * -> adds a waypoint to the currently selected creature
2208 * @param args if the user did not provide a GUID, it is NULL
2210 * @return true - command did succeed, false - something went wrong
2212 bool ChatHandler::HandleWpAddCommand(const char* args
)
2214 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2217 char* guid_str
= NULL
;
2221 guid_str
= strtok((char*)args
, " ");
2226 Creature
* target
= getSelectedCreature();
2227 // Did player provide a GUID?
2230 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2233 // -> Player must have selected a creature
2235 if(!target
|| target
->isPet())
2237 SendSysMessage(LANG_SELECT_CREATURE
);
2238 SetSentErrorMessage(true);
2241 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2243 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2245 QueryResult
*result
=
2246 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2247 target
->GetGUIDLow() );
2250 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2251 // User selected a visual spawnpoint -> get the NPC
2253 // Since we compare float values, we have to deal with
2254 // some difficulties.
2255 // Here we search for all waypoints that only differ in one from 1 thousand
2256 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2257 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2258 const char* maxDIFF
= "0.01";
2259 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 )",
2260 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2263 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2264 SetSentErrorMessage(true);
2270 Field
*fields
= result
->Fetch();
2271 lowguid
= fields
[0].GetUInt32();
2272 point
= fields
[1].GetUInt32();
2273 }while( result
->NextRow() );
2276 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2279 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2280 SetSentErrorMessage(true);
2284 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2287 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2288 SetSentErrorMessage(true);
2294 lowguid
= target
->GetDBTableGUIDLow();
2299 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2302 // Warn if player also selected a creature
2303 // -> Creature selection is ignored <-
2306 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2308 lowguid
= atoi((char*)guid_str
);
2310 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2313 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2314 SetSentErrorMessage(true);
2318 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2319 if(!target
|| target
->isPet())
2321 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2322 SetSentErrorMessage(true);
2326 // lowguid -> GUID of the NPC
2327 // point -> number of the waypoint (if not 0)
2328 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2330 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2332 Player
* player
= m_session
->GetPlayer();
2333 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2335 // update movement type
2338 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2339 target
->GetMotionMaster()->Initialize();
2340 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2342 target
->setDeathState(JUST_DIED
);
2348 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2350 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2353 } // HandleWpAddCommand
2356 * .wp modify emote | spell | text | del | move | add
2358 * add -> add a WP after the selected visual waypoint
2359 * User must select a visual waypoint and then issue ".wp modify add"
2362 * User has selected a visual waypoint before.
2363 * <emoteID> is added to this waypoint. Everytime the
2364 * NPC comes to this waypoint, the emote is called.
2366 * emote <GUID> <WPNUM> <emoteID>
2367 * User has not selected visual waypoint before.
2368 * For the waypoint <WPNUM> for the NPC with <GUID>
2369 * an emote <emoteID> is added.
2370 * Everytime the NPC comes to this waypoint, the emote is called.
2373 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2375 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2377 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2382 // first arg: add del text emote spell waittime move
2383 char* show_str
= strtok((char*)args
, " ");
2389 std::string show
= show_str
;
2391 // Remember: "show" must also be the name of a column!
2392 if( (show
!= "emote") && (show
!= "spell") && (show
!= "textid1") && (show
!= "textid2")
2393 && (show
!= "textid3") && (show
!= "textid4") && (show
!= "textid5")
2394 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2395 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2400 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2402 // Did user provide a GUID
2403 // or did the user select a creature?
2404 // -> variable lowguid is filled with the GUID of the NPC
2408 Creature
* target
= getSelectedCreature();
2412 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2414 // Did the user select a visual spawnpoint?
2415 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2417 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2418 SetSentErrorMessage(true);
2422 wpGuid
= target
->GetGUIDLow();
2424 // The visual waypoint
2425 QueryResult
*result
=
2426 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2427 target
->GetGUIDLow() );
2430 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2431 SetSentErrorMessage(true);
2434 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2436 Field
*fields
= result
->Fetch();
2437 lowguid
= fields
[0].GetUInt32();
2438 point
= fields
[1].GetUInt32();
2441 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2446 // User did provide <GUID> <WPNUM>
2448 char* guid_str
= strtok((char*)NULL
, " ");
2451 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2454 lowguid
= atoi((char*)guid_str
);
2456 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2459 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2460 SetSentErrorMessage(true);
2464 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2466 char* point_str
= strtok((char*)NULL
, " ");
2469 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2472 point
= atoi((char*)point_str
);
2474 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2476 // Now we need the GUID of the visual waypoint
2477 // -> "del", "move", "add" command
2479 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2482 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2483 SetSentErrorMessage(true);
2487 Field
*fields
= result
->Fetch();
2488 wpGuid
= fields
[0].GetUInt32();
2494 char* arg_str
= NULL
;
2495 // Check for argument
2496 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2498 // Text is enclosed in "<>", all other arguments not
2499 if( show
.find("text") != std::string::npos
)
2500 arg_str
= strtok((char*)NULL
, "<>");
2502 arg_str
= strtok((char*)NULL
, " ");
2506 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2511 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2513 // wpGuid -> GUID of the waypoint creature
2514 // lowguid -> GUID of the NPC
2515 // point -> waypoint number
2517 // Special functions:
2518 // add - move - del -> no args commands
2519 // Add a waypoint after the selected visual
2520 if(show
== "add" && target
)
2522 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2524 // Get the creature for which we read the waypoint
2525 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2528 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2529 SetSentErrorMessage(true);
2533 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2537 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2538 SetSentErrorMessage(true);
2542 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2545 // Add the visual spawnpoint (DB only)
2546 // Adjust the waypoints
2547 // Respawn the owner of the waypoints
2548 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2550 Player
* chr
= m_session
->GetPlayer();
2551 Map
*map
= chr
->GetMap();
2555 npcCreature
->GetMotionMaster()->Initialize();
2556 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2558 npcCreature
->setDeathState(JUST_DIED
);
2559 npcCreature
->Respawn();
2563 // create the waypoint creature
2565 Creature
* wpCreature
= new Creature
;
2566 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
,VISUAL_WAYPOINT
,0))
2568 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2573 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2575 if(!wpCreature
->IsPositionValid())
2577 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());
2582 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2583 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2584 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2585 map
->Add(wpCreature
);
2586 wpGuid
= wpCreature
->GetGUIDLow();
2590 WaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2595 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2599 if(show
== "del" && target
)
2601 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2603 // Get the creature for which we read the waypoint
2604 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2607 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2608 SetSentErrorMessage(true);
2612 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2615 Creature
* wpCreature
= NULL
;
2618 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2619 wpCreature
->DeleteFromDB();
2620 wpCreature
->CleanupsBeforeDelete();
2621 wpCreature
->AddObjectToRemoveList();
2625 // Remove the visual spawnpoint
2626 // Adjust the waypoints
2627 // Respawn the owner of the waypoints
2629 WaypointMgr
.DeleteNode(lowguid
, point
);
2633 // Any waypoints left?
2634 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2637 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2641 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2644 npcCreature
->GetMotionMaster()->Initialize();
2645 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2647 npcCreature
->setDeathState(JUST_DIED
);
2648 npcCreature
->Respawn();
2650 npcCreature
->SaveToDB();
2653 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2657 if(show
== "move" && target
)
2659 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2661 Player
*chr
= m_session
->GetPlayer();
2662 Map
*map
= chr
->GetMap();
2664 // Get the creature for which we read the waypoint
2665 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2668 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2669 SetSentErrorMessage(true);
2673 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2676 Creature
* wpCreature
= NULL
;
2678 // Move the visual spawnpoint
2679 // Respawn the owner of the waypoints
2682 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2683 wpCreature
->DeleteFromDB();
2684 wpCreature
->CleanupsBeforeDelete();
2685 wpCreature
->AddObjectToRemoveList();
2687 Creature
* wpCreature2
= new Creature
;
2688 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, VISUAL_WAYPOINT
, 0))
2690 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2695 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2697 if(!wpCreature2
->IsPositionValid())
2699 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());
2704 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2705 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2706 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2707 map
->Add(wpCreature2
);
2708 //npcCreature->GetMap()->Add(wpCreature2);
2711 WaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2715 npcCreature
->GetMotionMaster()->Initialize();
2716 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2718 npcCreature
->setDeathState(JUST_DIED
);
2719 npcCreature
->Respawn();
2722 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2727 // Create creature - npc that has the waypoint
2728 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2731 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2732 SetSentErrorMessage(true);
2736 // set in game textids not supported
2737 if( show
== "textid1" || show
== "textid2" || show
== "textid3" ||
2738 show
== "textid4" || show
== "textid5" )
2743 WaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2745 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2748 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2749 npcCreature
->GetMotionMaster()->Initialize();
2750 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2752 npcCreature
->setDeathState(JUST_DIED
);
2753 npcCreature
->Respawn();
2756 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2762 * .wp show info | on | off
2764 * info -> User has selected a visual waypoint before
2766 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2767 * provided the GUID of the NPC and the number of
2770 * on -> User has selected an NPC; all visual waypoints for this
2771 * NPC are added to the world
2773 * on <GUID> -> User did not select an NPC - instead the GUID of the
2774 * NPC is provided. All visual waypoints for this NPC
2775 * are added from the world.
2777 * off -> User has selected an NPC; all visual waypoints for this
2778 * NPC are removed from the world.
2780 * on <GUID> -> User did not select an NPC - instead the GUID of the
2781 * NPC is provided. All visual waypoints for this NPC
2782 * are removed from the world.
2786 bool ChatHandler::HandleWpShowCommand(const char* args
)
2788 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2793 // first arg: on, off, first, last
2794 char* show_str
= strtok((char*)args
, " ");
2799 // second arg: GUID (optional, if a creature is selected)
2800 char* guid_str
= strtok((char*)NULL
, " ");
2801 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2806 // Did user provide a GUID
2807 // or did the user select a creature?
2808 // -> variable lowguid is filled with the GUID
2809 Creature
* target
= getSelectedCreature();
2810 // Did player provide a GUID?
2813 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2815 // -> Player must have selected a creature
2819 SendSysMessage(LANG_SELECT_CREATURE
);
2820 SetSentErrorMessage(true);
2826 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2828 // Warn if player also selected a creature
2829 // -> Creature selection is ignored <-
2832 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2835 uint32 lowguid
= atoi((char*)guid_str
);
2837 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2840 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2841 SetSentErrorMessage(true);
2845 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2849 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2850 SetSentErrorMessage(true);
2855 uint32 lowguid
= target
->GetDBTableGUIDLow();
2857 std::string show
= show_str
;
2860 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
2862 // Show info for the selected waypoint
2865 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
2867 // Check if the user did specify a visual waypoint
2868 if( target
->GetEntry() != VISUAL_WAYPOINT
)
2870 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2871 SetSentErrorMessage(true);
2875 //PSendSysMessage("wp on, GUID: %u", lowguid);
2877 //pCreature->GetPositionX();
2879 QueryResult
*result
=
2880 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2881 target
->GetGUIDLow() );
2884 // Since we compare float values, we have to deal with
2885 // some difficulties.
2886 // Here we search for all waypoints that only differ in one from 1 thousand
2887 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2888 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2889 const char* maxDIFF
= "0.01";
2890 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
2892 result
= WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2893 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2896 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2897 SetSentErrorMessage(true);
2903 Field
*fields
= result
->Fetch();
2904 uint32 creGUID
= fields
[0].GetUInt32();
2905 uint32 point
= fields
[1].GetUInt32();
2906 int waittime
= fields
[2].GetUInt32();
2907 uint32 emote
= fields
[3].GetUInt32();
2908 uint32 spell
= fields
[4].GetUInt32();
2909 uint32 textid
[MAX_WAYPOINT_TEXT
];
2910 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
2911 textid
[i
] = fields
[5+i
].GetUInt32();
2912 uint32 model1
= fields
[10].GetUInt32();
2913 uint32 model2
= fields
[11].GetUInt32();
2915 // Get the creature for which we read the waypoint
2916 Creature
* wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2918 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
2919 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
2920 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
2921 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
2922 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
2923 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
2924 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
2925 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, i
+1, textid
[i
], (textid
[i
] ? GetMangosString(textid
[i
]) : ""));
2927 }while( result
->NextRow() );
2935 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
2937 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
2940 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2941 SetSentErrorMessage(true);
2944 // Delete all visuals for this NPC
2945 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
2948 bool hasError
= false;
2951 Field
*fields
= result2
->Fetch();
2952 uint32 wpguid
= fields
[0].GetUInt32();
2953 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2957 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
2959 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
2963 pCreature
->DeleteFromDB();
2964 pCreature
->CleanupsBeforeDelete();
2965 pCreature
->AddObjectToRemoveList();
2968 }while( result2
->NextRow() );
2972 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2973 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
2974 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
2980 Field
*fields
= result
->Fetch();
2981 uint32 point
= fields
[0].GetUInt32();
2982 float x
= fields
[1].GetFloat();
2983 float y
= fields
[2].GetFloat();
2984 float z
= fields
[3].GetFloat();
2986 uint32 id
= VISUAL_WAYPOINT
;
2988 Player
*chr
= m_session
->GetPlayer();
2989 Map
*map
= chr
->GetMap();
2990 float o
= chr
->GetOrientation();
2992 Creature
* wpCreature
= new Creature
;
2993 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
2995 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3001 wpCreature
->Relocate(x
, y
, z
, o
);
3003 if(!wpCreature
->IsPositionValid())
3005 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());
3011 wpCreature
->SetVisibility(VISIBILITY_OFF
);
3012 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3013 // set "wpguid" column to the visual waypoint
3014 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3016 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3017 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3018 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3019 map
->Add(wpCreature
);
3020 //wpCreature->GetMap()->Add(wpCreature);
3021 }while( result
->NextRow() );
3030 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3032 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3035 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3036 SetSentErrorMessage(true);
3040 Field
*fields
= result
->Fetch();
3041 float x
= fields
[0].GetFloat();
3042 float y
= fields
[1].GetFloat();
3043 float z
= fields
[2].GetFloat();
3044 uint32 id
= VISUAL_WAYPOINT
;
3046 Player
*chr
= m_session
->GetPlayer();
3047 float o
= chr
->GetOrientation();
3048 Map
*map
= chr
->GetMap();
3050 Creature
* pCreature
= new Creature
;
3051 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, id
, 0))
3053 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3059 pCreature
->Relocate(x
, y
, z
, o
);
3061 if(!pCreature
->IsPositionValid())
3063 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());
3069 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3070 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3071 map
->Add(pCreature
);
3072 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3081 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3083 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3086 Maxpoint
= (*result
)[0].GetUInt32();
3093 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3096 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3097 SetSentErrorMessage(true);
3100 Field
*fields
= result
->Fetch();
3101 float x
= fields
[0].GetFloat();
3102 float y
= fields
[1].GetFloat();
3103 float z
= fields
[2].GetFloat();
3104 uint32 id
= VISUAL_WAYPOINT
;
3106 Player
*chr
= m_session
->GetPlayer();
3107 float o
= chr
->GetOrientation();
3108 Map
*map
= chr
->GetMap();
3110 Creature
* pCreature
= new Creature
;
3111 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
3113 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3119 pCreature
->Relocate(x
, y
, z
, o
);
3121 if(!pCreature
->IsPositionValid())
3123 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());
3129 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3130 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3131 map
->Add(pCreature
);
3132 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3140 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3143 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3144 SetSentErrorMessage(true);
3147 bool hasError
= false;
3150 Field
*fields
= result
->Fetch();
3151 uint32 guid
= fields
[0].GetUInt32();
3152 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3154 //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3158 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3160 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3164 pCreature
->DeleteFromDB();
3165 pCreature
->CleanupsBeforeDelete();
3166 pCreature
->AddObjectToRemoveList();
3168 }while(result
->NextRow());
3169 // set "wpguid" column to "empty" - no visual waypoint spawned
3170 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3174 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3175 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3176 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3179 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3186 PSendSysMessage("DEBUG: wpshow - no valid command found");
3189 } // HandleWpShowCommand
3191 bool ChatHandler::HandleWpExportCommand(const char *args
)
3196 // Next arg is: <GUID> <ARGUMENT>
3198 // Did user provide a GUID
3199 // or did the user select a creature?
3200 // -> variable lowguid is filled with the GUID of the NPC
3202 Creature
* target
= getSelectedCreature();
3203 char* arg_str
= NULL
;
3206 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3207 lowguid
= target
->GetGUIDLow();
3210 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3213 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3216 Field
*fields
= result
->Fetch();
3217 lowguid
= fields
[0].GetUInt32();;
3221 arg_str
= strtok((char*)args
, " ");
3225 // user provided <GUID>
3226 char* guid_str
= strtok((char*)args
, " ");
3229 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3232 lowguid
= atoi((char*)guid_str
);
3234 arg_str
= strtok((char*)NULL
, " ");
3239 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3243 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3245 QueryResult
*result
= WorldDatabase
.PQuery(
3246 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3247 "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid
);
3251 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3252 SetSentErrorMessage(true);
3256 std::ofstream outfile
;
3257 outfile
.open (arg_str
);
3261 Field
*fields
= result
->Fetch();
3263 outfile
<< "INSERT INTO creature_movement ";
3264 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3267 outfile
<< fields
[15].GetUInt32(); // id
3269 outfile
<< fields
[0].GetUInt32(); // point
3271 outfile
<< fields
[1].GetFloat(); // position_x
3273 outfile
<< fields
[2].GetFloat(); // position_y
3275 outfile
<< fields
[3].GetUInt32(); // position_z
3277 outfile
<< fields
[4].GetUInt32(); // orientation
3279 outfile
<< fields
[5].GetUInt32(); // model1
3281 outfile
<< fields
[6].GetUInt32(); // model2
3283 outfile
<< fields
[7].GetUInt16(); // waittime
3285 outfile
<< fields
[8].GetUInt32(); // emote
3287 outfile
<< fields
[9].GetUInt32(); // spell
3289 outfile
<< fields
[10].GetUInt32(); // textid1
3291 outfile
<< fields
[11].GetUInt32(); // textid2
3293 outfile
<< fields
[12].GetUInt32(); // textid3
3295 outfile
<< fields
[13].GetUInt32(); // textid4
3297 outfile
<< fields
[14].GetUInt32(); // textid5
3300 } while( result
->NextRow() );
3303 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3309 bool ChatHandler::HandleWpImportCommand(const char *args
)
3314 char* arg_str
= strtok((char*)args
, " ");
3319 std::ifstream
infile (arg_str
);
3320 if (infile
.is_open())
3322 while (! infile
.eof() )
3324 getline (infile
,line
);
3325 //cout << line << endl;
3326 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3331 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3337 bool ChatHandler::HandleRenameCommand(const char* args
)
3339 Player
* target
= NULL
;
3340 uint64 targetGUID
= 0;
3341 std::string oldname
;
3343 char* px
= strtok((char*)args
, " ");
3349 if(!normalizePlayerName(oldname
))
3351 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3352 SetSentErrorMessage(true);
3356 target
= objmgr
.GetPlayer(oldname
.c_str());
3359 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3362 if(!target
&& !targetGUID
)
3364 target
= getSelectedPlayer();
3367 if(!target
&& !targetGUID
)
3369 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3370 SetSentErrorMessage(true);
3376 // check online security
3377 if (HasLowerSecurity(target
, 0))
3380 PSendSysMessage(LANG_RENAME_PLAYER
, target
->GetName());
3381 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3382 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3386 // check offline security
3387 if (HasLowerSecurity(NULL
, targetGUID
))
3390 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
3391 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3397 // customize characters
3398 bool ChatHandler::HandleCustomizeCommand(const char* args
)
3400 Player
* target
= NULL
;
3401 uint64 targetGUID
= 0;
3402 std::string oldname
;
3404 char* px
= strtok((char*)args
, " ");
3410 if(!normalizePlayerName(oldname
))
3412 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3413 SetSentErrorMessage(true);
3417 target
= objmgr
.GetPlayer(oldname
.c_str());
3420 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3423 if(!target
&& !targetGUID
)
3425 target
= getSelectedPlayer();
3428 if(!target
&& !targetGUID
)
3430 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3431 SetSentErrorMessage(true);
3437 PSendSysMessage(LANG_CUSTOMIZE_PLAYER
, target
->GetName());
3438 target
->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE
);
3439 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target
->GetGUIDLow());
3443 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
3444 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3451 bool ChatHandler::HandleGameObjectCommand(const char* args
)
3456 char* pParam1
= strtok((char*)args
, " ");
3460 uint32 id
= atoi((char*)pParam1
);
3464 char* spawntimeSecs
= strtok(NULL
, " ");
3466 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
3470 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
3471 SetSentErrorMessage(true);
3475 Player
*chr
= m_session
->GetPlayer();
3476 float x
= float(chr
->GetPositionX());
3477 float y
= float(chr
->GetPositionY());
3478 float z
= float(chr
->GetPositionZ());
3479 float o
= float(chr
->GetOrientation());
3480 Map
*map
= chr
->GetMap();
3482 float rot2
= sin(o
/2);
3483 float rot3
= cos(o
/2);
3485 GameObject
* pGameObj
= new GameObject
;
3486 uint32 db_lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
3488 if(!pGameObj
->Create(db_lowGUID
, goI
->id
, map
, x
, y
, z
, o
, 0, 0, rot2
, rot3
, 0, 1))
3496 uint32 value
= atoi((char*)spawntimeSecs
);
3497 pGameObj
->SetRespawnTime(value
);
3498 //sLog.outDebug("*** spawntimeSecs: %d", value);
3501 // fill the gameobject data and save to the db
3502 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3504 // this will generate a new guid if the object is in an instance
3505 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
3511 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), goI
->name
, db_lowGUID
, x
, y
, z
, o
);
3515 // TODO: is it really necessary to add both the real and DB table guid here ?
3516 objmgr
.AddGameobjectToGrid(db_lowGUID
, objmgr
.GetGOData(db_lowGUID
));
3518 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,goI
->name
,db_lowGUID
,x
,y
,z
);
3523 bool ChatHandler::HandleAnimCommand(const char* args
)
3528 uint32 anim_id
= atoi((char*)args
);
3529 m_session
->GetPlayer()->HandleEmoteCommand(anim_id
);
3534 bool ChatHandler::HandleStandStateCommand(const char* args
)
3539 uint32 anim_id
= atoi((char*)args
);
3540 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3545 bool ChatHandler::HandleAddHonorCommand(const char* args
)
3550 Player
*target
= getSelectedPlayer();
3553 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3554 SetSentErrorMessage(true);
3558 // check online security
3559 if (HasLowerSecurity(target
, 0))
3562 uint32 amount
= (uint32
)atoi(args
);
3563 target
->RewardHonor(NULL
, 1, amount
);
3567 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3569 Unit
*target
= getSelectedUnit();
3572 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3573 SetSentErrorMessage(true);
3577 // check online security
3578 if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
3581 m_session
->GetPlayer()->RewardHonor(target
, 1);
3585 bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3587 Player
*target
= getSelectedPlayer();
3590 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3591 SetSentErrorMessage(true);
3595 // check online security
3596 if (HasLowerSecurity(target
, 0))
3599 target
->UpdateHonorFields();
3603 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3608 std::string namepart
= args
;
3609 std::wstring wnamepart
;
3611 // converting string that we try to find to lower case
3612 if(!Utf8toWStr(namepart
,wnamepart
))
3615 wstrToLower(wnamepart
);
3619 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3620 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3622 for(uint32 id
= 0; id
< events
.size(); ++id
)
3624 GameEventData
const& eventData
= events
[id
];
3626 std::string descr
= eventData
.description
;
3630 if (Utf8FitTo(descr
, wnamepart
))
3632 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3635 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3637 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3644 SendSysMessage(LANG_NOEVENTFOUND
);
3649 bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
3653 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3654 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3656 char const* active
= GetMangosString(LANG_ACTIVE
);
3658 for(GameEvent::ActiveEvents::const_iterator itr
= activeEvents
.begin(); itr
!= activeEvents
.end(); ++itr
)
3660 uint32 event_id
= *itr
;
3661 GameEventData
const& eventData
= events
[event_id
];
3664 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,event_id
,event_id
,eventData
.description
.c_str(),active
);
3666 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,event_id
,eventData
.description
.c_str(),active
);
3672 SendSysMessage(LANG_NOEVENTFOUND
);
3677 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3682 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3683 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3687 uint32 event_id
= atoi(cId
);
3689 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3691 if(event_id
>=events
.size())
3693 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3694 SetSentErrorMessage(true);
3698 GameEventData
const& eventData
= events
[event_id
];
3699 if(!eventData
.isValid())
3701 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3702 SetSentErrorMessage(true);
3706 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3707 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3708 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3710 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3711 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3713 uint32 delay
= gameeventmgr
.NextCheck(event_id
);
3714 time_t nextTime
= time(NULL
)+delay
;
3715 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3717 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3718 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3720 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3721 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3726 bool ChatHandler::HandleEventStartCommand(const char* args
)
3731 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3732 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3736 int32 event_id
= atoi(cId
);
3738 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3740 if(event_id
< 1 || event_id
>=events
.size())
3742 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3743 SetSentErrorMessage(true);
3747 GameEventData
const& eventData
= events
[event_id
];
3748 if(!eventData
.isValid())
3750 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3751 SetSentErrorMessage(true);
3755 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3756 if(activeEvents
.find(event_id
) != activeEvents
.end())
3758 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3759 SetSentErrorMessage(true);
3763 gameeventmgr
.StartEvent(event_id
,true);
3767 bool ChatHandler::HandleEventStopCommand(const char* args
)
3772 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3773 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3777 int32 event_id
= atoi(cId
);
3779 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3781 if(event_id
< 1 || event_id
>=events
.size())
3783 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3784 SetSentErrorMessage(true);
3788 GameEventData
const& eventData
= events
[event_id
];
3789 if(!eventData
.isValid())
3791 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3792 SetSentErrorMessage(true);
3796 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3798 if(activeEvents
.find(event_id
) == activeEvents
.end())
3800 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3801 SetSentErrorMessage(true);
3805 gameeventmgr
.StopEvent(event_id
,true);
3809 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3815 std::string playername
= args
;
3817 if(!normalizePlayerName(playername
))
3819 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3820 SetSentErrorMessage(true);
3824 player
= objmgr
.GetPlayer(playername
.c_str());
3828 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3829 SetSentErrorMessage(true);
3835 player
= getSelectedPlayer();
3838 player
= m_session
->GetPlayer();
3841 // check online security
3842 if (HasLowerSecurity(player
, 0))
3845 player
->CombatStop();
3846 player
->getHostilRefManager().deleteReferences();
3850 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3852 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3854 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3856 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3860 if( skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
)
3862 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3864 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3868 // skip racial skills
3869 if( skillLine
->racemask
!= 0 )
3872 // skip wrong class skills
3873 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3876 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3879 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3880 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3883 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3888 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
3892 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
3894 // Learns all recipes of specified profession and sets skill to max
3895 // Example: .learn all_recipes enchanting
3897 Player
* target
= getSelectedPlayer();
3900 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3907 std::wstring wnamepart
;
3909 if(!Utf8toWStr(args
,wnamepart
))
3912 // converting string that we try to find to lower case
3913 wstrToLower( wnamepart
);
3915 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3917 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3919 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3923 if( skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
3924 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
)
3927 int loc
= m_session
->GetSessionDbcLocale();
3928 std::string name
= skillInfo
->name
[loc
];
3930 if(Utf8FitTo(name
, wnamepart
))
3932 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3934 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3938 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3941 // skip racial skills
3942 if( skillLine
->racemask
!= 0 )
3945 // skip wrong class skills
3946 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3949 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3950 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3953 if( !target
->HasSpell(spellInfo
->Id
) )
3954 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3957 uint16 maxLevel
= target
->GetPureMaxSkillValue(skillInfo
->id
);
3958 target
->SetSkill(skillInfo
->id
, maxLevel
, maxLevel
);
3959 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
3967 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
3973 std::string ip
= strtok ((char*)args
, " ");
3974 char* limit_str
= strtok (NULL
, " ");
3975 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3977 loginDatabase
.escape_string (ip
);
3979 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
3981 return LookupPlayerSearchCommand (result
,limit
);
3984 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
3989 std::string account
= strtok ((char*)args
, " ");
3990 char* limit_str
= strtok (NULL
, " ");
3991 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3993 if (!AccountMgr::normilizeString (account
))
3996 loginDatabase
.escape_string (account
);
3998 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
4000 return LookupPlayerSearchCommand (result
,limit
);
4003 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
4009 std::string email
= strtok ((char*)args
, " ");
4010 char* limit_str
= strtok (NULL
, " ");
4011 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4013 loginDatabase
.escape_string (email
);
4015 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
4017 return LookupPlayerSearchCommand (result
,limit
);
4020 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
4024 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4025 SetSentErrorMessage(true);
4032 Field
* fields
= result
->Fetch();
4033 uint32 acc_id
= fields
[0].GetUInt32();
4034 std::string acc_name
= fields
[1].GetCppString();
4036 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4039 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4046 Field
* charfields
= chars
->Fetch();
4047 guid
= charfields
[0].GetUInt64();
4048 name
= charfields
[1].GetCppString();
4050 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4053 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4057 } while(result
->NextRow());
4064 /// Triggering corpses expire check in world
4065 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4071 bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
4073 Player
*target
= getSelectedPlayer();
4077 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4078 SetSentErrorMessage(true);
4082 // check online security
4083 if (HasLowerSecurity(target
, 0))
4087 target
->DurabilityRepairAll(false, 0, false);
4089 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, target
->GetName());
4090 if(needReportToTarget(target
))
4091 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetName());
4095 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4100 Player
*player
= getSelectedPlayer();
4104 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4105 SetSentErrorMessage(true);
4109 // check online security
4110 if (HasLowerSecurity(player
, 0))
4113 if (strncmp(args
, "on", 3) == 0)
4114 player
->SetMovement(MOVE_WATER_WALK
); // ON
4115 else if (strncmp(args
, "off", 4) == 0)
4116 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4119 SendSysMessage(LANG_USE_BOL
);
4123 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, player
->GetName());
4124 if(needReportToTarget(player
))
4125 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetName());
4129 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
4131 Player
*player
= m_session
->GetPlayer();
4132 Creature
*creature
= getSelectedCreature();
4136 PSendSysMessage(LANG_SELECT_CREATURE
);
4137 SetSentErrorMessage(true);
4141 // Follow player - Using pet's default dist and angle
4142 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
4144 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
4148 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
4150 Player
*player
= m_session
->GetPlayer();
4151 Creature
*creature
= getSelectedCreature();
4155 PSendSysMessage(LANG_SELECT_CREATURE
);
4156 SetSentErrorMessage(true);
4160 if (creature
->GetMotionMaster()->empty() ||
4161 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE
)
4163 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4164 SetSentErrorMessage(true);
4168 TargetedMovementGenerator
<Creature
> const* mgen
4169 = static_cast<TargetedMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
4171 if(mgen
->GetTarget()!=player
)
4173 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4174 SetSentErrorMessage(true);
4179 creature
->GetMotionMaster()->MovementExpired(true);
4181 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
4185 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
4187 Creature
*creatureTarget
= getSelectedCreature ();
4188 if (!creatureTarget
|| creatureTarget
->isPet ())
4190 PSendSysMessage (LANG_SELECT_CREATURE
);
4191 SetSentErrorMessage (true);
4195 Player
*player
= m_session
->GetPlayer ();
4197 if(player
->GetPetGUID ())
4199 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
4200 SetSentErrorMessage (true);
4204 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
4206 if (!cInfo
->isTameable ())
4208 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4209 SetSentErrorMessage (true);
4213 // Everything looks OK, create new pet
4214 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
4217 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4218 SetSentErrorMessage (true);
4222 // place pet before player
4224 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
4225 pet
->Relocate (x
,y
,z
,M_PI
-player
->GetOrientation ());
4227 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
4228 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
4230 // calculate proper level
4231 uint32 level
= (creatureTarget
->getLevel() < (player
->getLevel() - 5)) ? (player
->getLevel() - 5) : creatureTarget
->getLevel();
4233 // prepare visual effect for levelup
4234 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
- 1);
4237 pet
->GetMap()->Add((Creature
*)pet
);
4239 // visual effect for levelup
4240 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
);
4242 // caster have pet now
4243 player
->SetPet(pet
);
4245 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
4246 player
->PetSpellInitialize();