2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
);
89 // must have strong lesser security level
90 if(HasLowerSecurity (chr
,guid
,true))
93 uint32 account_id
= chr
? chr
->GetSession()->GetAccountId() : objmgr
.GetPlayerAccountIdByGUID(guid
);
95 time_t mutetime
= time(NULL
) + notspeaktime
*60;
98 chr
->GetSession()->m_muteTime
= mutetime
;
100 loginDatabase
.PExecute("UPDATE account SET mutetime = " I64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
103 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
105 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, cname
.c_str(), notspeaktime
);
111 bool ChatHandler::HandleUnmuteCommand(const char* args
)
116 char *charname
= strtok((char*)args
, " ");
120 std::string cname
= charname
;
122 if(!normalizePlayerName(cname
))
124 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
125 SetSentErrorMessage(true);
129 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
132 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
133 SetSentErrorMessage(true);
137 Player
*chr
= objmgr
.GetPlayer(guid
);
139 // must have strong lesser security level
140 if(HasLowerSecurity (chr
,guid
,true))
143 uint32 account_id
= chr
? chr
->GetSession()->GetAccountId() : objmgr
.GetPlayerAccountIdByGUID(guid
);
149 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
150 SetSentErrorMessage(true);
154 chr
->GetSession()->m_muteTime
= 0;
157 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
160 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
162 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, cname
.c_str());
166 bool ChatHandler::HandleTargetObjectCommand(const char* args
)
168 Player
* pl
= m_session
->GetPlayer();
170 GameEvent::ActiveEvents
const& activeEventsList
= gameeventmgr
.GetActiveEventList();
173 int32 id
= atoi((char*)args
);
175 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",
176 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
179 std::string name
= args
;
180 WorldDatabase
.escape_string(name
);
181 result
= WorldDatabase
.PQuery(
182 "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_ "
183 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
184 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
189 std::ostringstream eventFilter
;
190 eventFilter
<< " AND (event IS NULL ";
191 bool initString
= true;
193 for (GameEvent::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
197 eventFilter
<< "OR event IN (" <<*itr
;
201 eventFilter
<< "," << *itr
;
209 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
210 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
211 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
212 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
217 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
221 Field
*fields
= result
->Fetch();
222 uint32 lowguid
= fields
[0].GetUInt32();
223 uint32 id
= fields
[1].GetUInt32();
224 float x
= fields
[2].GetFloat();
225 float y
= fields
[3].GetFloat();
226 float z
= fields
[4].GetFloat();
227 float o
= fields
[5].GetFloat();
228 int mapid
= fields
[6].GetUInt16();
231 GameObjectInfo
const* goI
= objmgr
.GetGameObjectInfo(id
);
235 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
239 GameObject
* target
= ObjectAccessor::GetGameObject(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
241 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
245 int32 curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
246 if(curRespawnDelay
< 0)
249 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
250 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
252 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
257 //teleport to gameobject
258 bool ChatHandler::HandleGoObjectCommand(const char* args
)
263 Player
* _player
= m_session
->GetPlayer();
265 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
266 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
270 int32 guid
= atoi(cId
);
278 if (GameObjectData
const* go_data
= objmgr
.GetGOData(guid
))
283 ort
= go_data
->orientation
;
284 mapid
= go_data
->mapid
;
288 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
289 SetSentErrorMessage(true);
293 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
295 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
296 SetSentErrorMessage(true);
300 // stop flight if need
301 if(_player
->isInFlight())
303 _player
->GetMotionMaster()->MovementExpired();
304 _player
->m_taxi
.ClearTaxiDestinations();
306 // save only in non-flight case
308 _player
->SaveRecallPosition();
310 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
314 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
316 Player
* _player
= m_session
->GetPlayer();
321 char *atId
= strtok((char*)args
, " ");
325 int32 i_atId
= atoi(atId
);
330 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
333 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
334 SetSentErrorMessage(true);
338 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
340 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
341 SetSentErrorMessage(true);
345 // stop flight if need
346 if(_player
->isInFlight())
348 _player
->GetMotionMaster()->MovementExpired();
349 _player
->m_taxi
.ClearTaxiDestinations();
351 // save only in non-flight case
353 _player
->SaveRecallPosition();
355 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
359 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
361 Player
* _player
= m_session
->GetPlayer();
366 char *gyId
= strtok((char*)args
, " ");
370 int32 i_gyId
= atoi(gyId
);
375 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
378 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
379 SetSentErrorMessage(true);
383 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
385 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
386 SetSentErrorMessage(true);
390 // stop flight if need
391 if(_player
->isInFlight())
393 _player
->GetMotionMaster()->MovementExpired();
394 _player
->m_taxi
.ClearTaxiDestinations();
396 // save only in non-flight case
398 _player
->SaveRecallPosition();
400 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
404 /** \brief Teleport the GM to the specified creature
406 * .gocreature <GUID> --> TP using creature.guid
407 * .gocreature azuregos --> TP player to the mob with this name
408 * Warning: If there is more than one mob with this name
409 * you will be teleported to the first one that is found.
410 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
411 * Warning: If there is more than one mob with this "id"
412 * you will be teleported to the first one that is found.
414 //teleport to creature
415 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
419 Player
* _player
= m_session
->GetPlayer();
421 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
422 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
426 std::ostringstream whereClause
;
428 // User wants to teleport to the NPC's template entry
429 if( strcmp(pParam1
, "id") == 0 )
431 //sLog.outError("DEBUG: ID found");
433 // Get the "creature_template.entry"
434 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
435 char* tail
= strtok(NULL
,"");
438 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
442 int32 tEntry
= atoi(cId
);
443 //sLog.outError("DEBUG: ID value: %d", tEntry);
447 whereClause
<< "WHERE id = '" << tEntry
<< "'";
451 //sLog.outError("DEBUG: ID *not found*");
453 int32 guid
= atoi(pParam1
);
455 // Number is invalid - maybe the user specified the mob's name
458 std::string name
= pParam1
;
459 WorldDatabase
.escape_string(name
);
460 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
464 whereClause
<< "WHERE guid = '" << guid
<< "'";
467 //sLog.outError("DEBUG: %s", whereClause.c_str());
469 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
472 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
473 SetSentErrorMessage(true);
476 if( result
->GetRowCount() > 1 )
478 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
481 Field
*fields
= result
->Fetch();
482 float x
= fields
[0].GetFloat();
483 float y
= fields
[1].GetFloat();
484 float z
= fields
[2].GetFloat();
485 float ort
= fields
[3].GetFloat();
486 int mapid
= fields
[4].GetUInt16();
490 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
492 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
493 SetSentErrorMessage(true);
497 // stop flight if need
498 if(_player
->isInFlight())
500 _player
->GetMotionMaster()->MovementExpired();
501 _player
->m_taxi
.ClearTaxiDestinations();
503 // save only in non-flight case
505 _player
->SaveRecallPosition();
507 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
511 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
513 uint64 guid
= m_session
->GetPlayer()->GetSelection();
517 SendSysMessage(LANG_NO_SELECTION
);
518 SetSentErrorMessage(true);
522 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
526 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
531 // Can be NULL at console call
532 Player
*target
= getSelectedPlayer ();
534 std::string namepart
= args
;
535 std::wstring wnamepart
;
537 if (!Utf8toWStr (namepart
,wnamepart
))
540 // converting string that we try to find to lower case
541 wstrToLower (wnamepart
);
543 uint32 counter
= 0; // Counter for figure out that we found smth.
545 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
547 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
550 FactionState
const* repState
= NULL
;
553 FactionStateList::const_iterator repItr
= target
->m_factions
.find (factionEntry
->reputationListID
);
554 if(repItr
!= target
->m_factions
.end())
555 repState
= &repItr
->second
;
559 int loc
= m_session
? m_session
->GetSessionDbcLocale() : sWorld
.GetDefaultDbcLocale();
560 std::string name
= factionEntry
->name
[loc
];
564 if (!Utf8FitTo(name
, wnamepart
))
567 for(; loc
< MAX_LOCALE
; ++loc
)
569 if(m_session
&& loc
==m_session
->GetSessionDbcLocale())
572 name
= factionEntry
->name
[loc
];
576 if (Utf8FitTo(name
, wnamepart
))
583 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
584 // or "id - [faction] [no reputation]" format
585 std::ostringstream ss
;
587 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
589 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
591 if (repState
) // and then target!=NULL also
593 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
594 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
596 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
598 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
599 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
600 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
601 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
602 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
603 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
604 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
605 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
606 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
607 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
608 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
609 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
612 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
614 SendSysMessage(ss
.str().c_str());
620 if (counter
== 0) // if counter == 0 then we found nth
621 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
625 bool ChatHandler::HandleModifyRepCommand(const char * args
)
627 if (!*args
) return false;
629 Player
* target
= NULL
;
630 target
= getSelectedPlayer();
634 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
635 SetSentErrorMessage(true);
639 // check online security
640 if (HasLowerSecurity(target
, 0))
643 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
647 uint32 factionId
= atoi(factionTxt
);
650 char *rankTxt
= strtok(NULL
, " ");
651 if (!factionTxt
|| !rankTxt
)
654 amount
= atoi(rankTxt
);
655 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
657 std::string rankStr
= rankTxt
;
658 std::wstring wrankStr
;
659 if(!Utf8toWStr(rankStr
,wrankStr
))
661 wstrToLower( wrankStr
);
665 for (; r
< MAX_REPUTATION_RANK
; ++r
)
667 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
672 if(!Utf8toWStr(rank
,wrank
))
677 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
679 char *deltaTxt
= strtok(NULL
, " ");
682 int32 delta
= atoi(deltaTxt
);
683 if ((delta
< 0) || (delta
> Player::ReputationRank_Length
[r
] -1))
685 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (Player::ReputationRank_Length
[r
]-1));
686 SetSentErrorMessage(true);
693 amount
+= Player::ReputationRank_Length
[r
];
695 if (r
>= MAX_REPUTATION_RANK
)
697 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
698 SetSentErrorMessage(true);
703 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
707 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
708 SetSentErrorMessage(true);
712 if (factionEntry
->reputationListID
< 0)
714 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
);
715 SetSentErrorMessage(true);
719 target
->SetFactionReputation(factionEntry
,amount
);
720 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
, target
->GetName(), target
->GetReputation(factionId
));
724 bool ChatHandler::HandleNameCommand(const char* /*args*/)
730 if(strlen((char*)args)>75)
732 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
736 for (uint8 i = 0; i < strlen(args); i++)
738 if(!isalpha(args[i]) && args[i]!=' ')
740 SendSysMessage(LANG_CHARS_ONLY);
746 guid = m_session->GetPlayer()->GetSelection();
749 SendSysMessage(LANG_NO_SELECTION);
753 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
757 SendSysMessage(LANG_SELECT_CREATURE);
761 pCreature->SetName(args);
762 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
763 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
765 pCreature->SaveToDB();
771 bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
778 if(strlen((char*)args)>75)
781 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
785 for (uint8 i = 0; i < strlen(args); i++)
787 if(!isalpha(args[i]) && args[i]!=' ')
789 SendSysMessage(LANG_CHARS_ONLY);
794 guid = m_session->GetPlayer()->GetSelection();
797 SendSysMessage(LANG_NO_SELECTION);
801 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
805 SendSysMessage(LANG_SELECT_CREATURE);
809 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
810 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
812 pCreature->SaveToDB();
817 //move item to other slot
818 bool ChatHandler::HandleItemMoveCommand(const char* args
)
822 uint8 srcslot
, dstslot
;
824 char* pParam1
= strtok((char*)args
, " ");
828 char* pParam2
= strtok(NULL
, " ");
832 srcslot
= (uint8
)atoi(pParam1
);
833 dstslot
= (uint8
)atoi(pParam2
);
838 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,srcslot
))
841 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
))
844 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
845 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
847 m_session
->GetPlayer()->SwapItem( src
, dst
);
852 //add spawn of creature
853 bool ChatHandler::HandleNpcAddCommand(const char* args
)
857 char* charID
= extractKeyFromLink((char*)args
,"Hcreature_entry");
861 char* team
= strtok(NULL
, " ");
863 if (team
) { teamval
= atoi(team
); }
864 if (teamval
< 0) { teamval
= 0; }
866 uint32 id
= atoi(charID
);
868 Player
*chr
= m_session
->GetPlayer();
869 float x
= chr
->GetPositionX();
870 float y
= chr
->GetPositionY();
871 float z
= chr
->GetPositionZ();
872 float o
= chr
->GetOrientation();
873 Map
*map
= chr
->GetMap();
875 Creature
* pCreature
= new Creature
;
876 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, (uint32
)teamval
))
882 pCreature
->Relocate(x
,y
,z
,o
);
884 if(!pCreature
->IsPositionValid())
886 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());
891 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
893 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
895 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
896 pCreature
->LoadFromDB(db_guid
, map
);
899 objmgr
.AddCreatureToGrid(db_guid
, objmgr
.GetCreatureData(db_guid
));
903 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
905 Creature
* unit
= NULL
;
909 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
910 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
914 uint32 lowguid
= atoi(cId
);
918 if (CreatureData
const* cr_data
= objmgr
.GetCreatureData(lowguid
))
919 unit
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
922 unit
= getSelectedCreature();
924 if(!unit
|| unit
->isPet() || unit
->isTotem() || unit
->isVehicle())
926 SendSysMessage(LANG_SELECT_CREATURE
);
927 SetSentErrorMessage(true);
931 // Delete the creature
933 unit
->DeleteFromDB();
934 unit
->CleanupsBeforeDelete();
935 unit
->AddObjectToRemoveList();
937 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
942 //delete object by selection or guid
943 bool ChatHandler::HandleDelObjectCommand(const char* args
)
945 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
946 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
950 uint32 lowguid
= atoi(cId
);
954 GameObject
* obj
= NULL
;
957 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
958 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
962 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
963 SetSentErrorMessage(true);
967 uint64 owner_guid
= obj
->GetOwnerGUID();
970 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
971 if(!owner
&& !IS_PLAYER_GUID(owner_guid
))
973 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
974 SetSentErrorMessage(true);
978 owner
->RemoveGameObject(obj
,false);
981 obj
->SetRespawnTime(0); // not save respawn time
985 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
990 //turn selected object
991 bool ChatHandler::HandleTurnObjectCommand(const char* args
)
993 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
994 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
998 uint32 lowguid
= atoi(cId
);
1002 GameObject
* obj
= NULL
;
1005 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1006 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1010 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1011 SetSentErrorMessage(true);
1015 char* po
= strtok(NULL
, " ");
1020 o
= (float)atof(po
);
1024 Player
*chr
= m_session
->GetPlayer();
1025 o
= chr
->GetOrientation();
1028 float rot2
= sin(o
/2);
1029 float rot3
= cos(o
/2);
1031 Map
* map
= obj
->GetMap();
1032 map
->Remove(obj
,false);
1034 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
1036 obj
->SetFloatValue(GAMEOBJECT_FACING
, o
);
1037 obj
->SetFloatValue(GAMEOBJECT_PARENTROTATION
+2, rot2
);
1038 obj
->SetFloatValue(GAMEOBJECT_PARENTROTATION
+3, rot3
);
1045 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), o
);
1050 //move selected creature
1051 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1055 Creature
* pCreature
= getSelectedCreature();
1059 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1060 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1064 uint32 lowguid
= atoi(cId
);
1066 /* FIXME: impossibel without entry
1068 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1071 // Attempting creature load from DB data
1074 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1077 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1078 SetSentErrorMessage(true);
1082 uint32 map_id
= data
->mapid
;
1084 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1086 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1087 SetSentErrorMessage(true);
1093 lowguid
= pCreature
->GetDBTableGUIDLow();
1098 lowguid
= pCreature
->GetDBTableGUIDLow();
1101 float x
= m_session
->GetPlayer()->GetPositionX();
1102 float y
= m_session
->GetPlayer()->GetPositionY();
1103 float z
= m_session
->GetPlayer()->GetPositionZ();
1104 float o
= m_session
->GetPlayer()->GetOrientation();
1108 if(CreatureData
const* data
= objmgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1110 const_cast<CreatureData
*>(data
)->posX
= x
;
1111 const_cast<CreatureData
*>(data
)->posY
= y
;
1112 const_cast<CreatureData
*>(data
)->posZ
= z
;
1113 const_cast<CreatureData
*>(data
)->orientation
= o
;
1115 pCreature
->GetMap()->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1116 pCreature
->GetMotionMaster()->Initialize();
1117 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1119 pCreature
->setDeathState(JUST_DIED
);
1120 pCreature
->Respawn();
1124 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1125 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1129 //move selected object
1130 bool ChatHandler::HandleMoveObjectCommand(const char* args
)
1132 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1133 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1137 uint32 lowguid
= atoi(cId
);
1141 GameObject
* obj
= NULL
;
1144 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1145 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1149 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1150 SetSentErrorMessage(true);
1154 char* px
= strtok(NULL
, " ");
1155 char* py
= strtok(NULL
, " ");
1156 char* pz
= strtok(NULL
, " ");
1160 Player
*chr
= m_session
->GetPlayer();
1162 Map
* map
= obj
->GetMap();
1163 map
->Remove(obj
,false);
1165 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
1166 obj
->SetFloatValue(GAMEOBJECT_POS_X
, chr
->GetPositionX());
1167 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, chr
->GetPositionY());
1168 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, chr
->GetPositionZ());
1177 float x
= (float)atof(px
);
1178 float y
= (float)atof(py
);
1179 float z
= (float)atof(pz
);
1181 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
1183 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
1184 SetSentErrorMessage(true);
1188 Map
* map
= obj
->GetMap();
1189 map
->Remove(obj
,false);
1191 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
1192 obj
->SetFloatValue(GAMEOBJECT_POS_X
, x
);
1193 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, y
);
1194 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, z
);
1202 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow());
1207 //demorph player or unit
1208 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1210 Unit
*target
= getSelectedUnit();
1212 target
= m_session
->GetPlayer();
1215 // check online security
1216 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1224 //add item in vendorlist
1225 bool ChatHandler::HandleAddVendorItemCommand(const char* args
)
1230 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1233 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1234 SetSentErrorMessage(true);
1238 uint32 itemId
= atol(pitem
);
1240 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1241 uint32 maxcount
= 0;
1243 maxcount
= atol(fmaxcount
);
1245 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1246 uint32 incrtime
= 0;
1248 incrtime
= atol(fincrtime
);
1250 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1251 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1253 Creature
* vendor
= getSelectedCreature();
1255 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1257 if(!objmgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1259 SetSentErrorMessage(true);
1263 objmgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1265 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1267 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1271 //del item from vendor list
1272 bool ChatHandler::HandleDelVendorItemCommand(const char* args
)
1277 Creature
* vendor
= getSelectedCreature();
1278 if (!vendor
|| !vendor
->isVendor())
1280 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1281 SetSentErrorMessage(true);
1285 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1288 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1289 SetSentErrorMessage(true);
1292 uint32 itemId
= atol(pitem
);
1294 if(!objmgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1296 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1297 SetSentErrorMessage(true);
1301 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1303 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1307 //add move for creature
1308 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1313 char* guid_str
= strtok((char*)args
, " ");
1314 char* wait_str
= strtok((char*)NULL
, " ");
1316 uint32 lowguid
= atoi((char*)guid_str
);
1318 Creature
* pCreature
= NULL
;
1320 /* FIXME: impossible without entry
1322 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1325 // attempt check creature existence by DB data
1328 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1331 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1332 SetSentErrorMessage(true);
1338 // obtain real GUID for DB operations
1339 lowguid
= pCreature
->GetDBTableGUIDLow();
1342 int wait
= wait_str
? atoi(wait_str
) : 0;
1347 Player
* player
= m_session
->GetPlayer();
1349 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1351 // update movement type
1352 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1355 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1356 pCreature
->GetMotionMaster()->Initialize();
1357 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1359 pCreature
->setDeathState(JUST_DIED
);
1360 pCreature
->Respawn();
1362 pCreature
->SaveToDB();
1365 SendSysMessage(LANG_WAYPOINT_ADDED
);
1371 * Set the movement type for an NPC.<br/>
1373 * Valid movement types are:
1375 * <li> stay - NPC wont move </li>
1376 * <li> random - NPC will move randomly according to the spawndist </li>
1377 * <li> way - NPC will move with given waypoints set </li>
1379 * additional parameter: NODEL - so no waypoints are deleted, if you
1380 * change the movement type
1382 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1388 // GUID (optional - you can also select the creature)
1389 // stay|random|way (determines the kind of movement)
1390 // NODEL (optional - tells the system NOT to delete any waypoints)
1391 // this is very handy if you want to do waypoints, that are
1392 // later switched on/off according to special events (like escort
1394 char* guid_str
= strtok((char*)args
, " ");
1395 char* type_str
= strtok((char*)NULL
, " ");
1396 char* dontdel_str
= strtok((char*)NULL
, " ");
1398 bool doNotDelete
= false;
1404 Creature
* pCreature
= NULL
;
1408 //sLog.outError("DEBUG: All 3 params are set");
1410 // All 3 params are set
1414 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1416 //sLog.outError("DEBUG: doNotDelete = true;");
1422 // Only 2 params - but maybe NODEL is set
1425 sLog
.outError("DEBUG: Only 2 params ");
1426 if( stricmp( type_str
, "NODEL" ) == 0 )
1428 //sLog.outError("DEBUG: type_str, NODEL ");
1435 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1437 type_str
= guid_str
;
1438 pCreature
= getSelectedCreature();
1439 if(!pCreature
|| pCreature
->isPet())
1441 lowguid
= pCreature
->GetDBTableGUIDLow();
1443 else // case .setmovetype #creature_guid $move_type (with selected creature)
1445 lowguid
= atoi((char*)guid_str
);
1447 /* impossible without entry
1449 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1452 // attempt check creature existence by DB data
1455 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1458 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1459 SetSentErrorMessage(true);
1465 lowguid
= pCreature
->GetDBTableGUIDLow();
1469 // now lowguid is low guid really existed creature
1470 // and pCreature point (maybe) to this creature or NULL
1472 MovementGeneratorType move_type
;
1474 std::string type
= type_str
;
1477 move_type
= IDLE_MOTION_TYPE
;
1478 else if(type
== "random")
1479 move_type
= RANDOM_MOTION_TYPE
;
1480 else if(type
== "way")
1481 move_type
= WAYPOINT_MOTION_TYPE
;
1485 // update movement type
1486 if(doNotDelete
== false)
1487 WaypointMgr
.DeletePath(lowguid
);
1491 pCreature
->SetDefaultMovementType(move_type
);
1492 pCreature
->GetMotionMaster()->Initialize();
1493 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1495 pCreature
->setDeathState(JUST_DIED
);
1496 pCreature
->Respawn();
1498 pCreature
->SaveToDB();
1500 if( doNotDelete
== false )
1502 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1506 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1510 } // HandleNpcSetMoveTypeCommand
1512 //change level of creature or pet
1513 bool ChatHandler::HandleChangeLevelCommand(const char* args
)
1518 uint8 lvl
= (uint8
) atoi((char*)args
);
1519 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1521 SendSysMessage(LANG_BAD_VALUE
);
1522 SetSentErrorMessage(true);
1526 Creature
* pCreature
= getSelectedCreature();
1529 SendSysMessage(LANG_SELECT_CREATURE
);
1530 SetSentErrorMessage(true);
1534 if(pCreature
->isPet())
1536 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1540 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1541 pCreature
->SetHealth( 100 + 30*lvl
);
1542 pCreature
->SetLevel( lvl
);
1543 pCreature
->SaveToDB();
1549 //set npcflag of creature
1550 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1555 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1557 Creature
* pCreature
= getSelectedCreature();
1561 SendSysMessage(LANG_SELECT_CREATURE
);
1562 SetSentErrorMessage(true);
1566 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1568 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1570 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1575 //set model of creature
1576 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1581 uint32 displayId
= (uint32
) atoi((char*)args
);
1583 Creature
*pCreature
= getSelectedCreature();
1585 if(!pCreature
|| pCreature
->isPet())
1587 SendSysMessage(LANG_SELECT_CREATURE
);
1588 SetSentErrorMessage(true);
1592 pCreature
->SetDisplayId(displayId
);
1593 pCreature
->SetNativeDisplayId(displayId
);
1595 pCreature
->SaveToDB();
1600 //morph creature or player
1601 bool ChatHandler::HandleMorphCommand(const char* args
)
1606 uint16 display_id
= (uint16
)atoi((char*)args
);
1608 Unit
*target
= getSelectedUnit();
1610 target
= m_session
->GetPlayer();
1612 // check online security
1613 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1616 target
->SetDisplayId(display_id
);
1621 //set faction of creature
1622 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1627 uint32 factionId
= (uint32
) atoi((char*)args
);
1629 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1631 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1632 SetSentErrorMessage(true);
1636 Creature
* pCreature
= getSelectedCreature();
1640 SendSysMessage(LANG_SELECT_CREATURE
);
1641 SetSentErrorMessage(true);
1645 pCreature
->setFaction(factionId
);
1647 // faction is set in creature_template - not inside creature
1650 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1652 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1653 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1657 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1663 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
1665 char* kickName
= strtok((char*)args
, " ");
1668 Player
* player
= getSelectedPlayer();
1672 SendSysMessage(LANG_NO_CHAR_SELECTED
);
1673 SetSentErrorMessage(true);
1677 if(player
==m_session
->GetPlayer())
1679 SendSysMessage(LANG_COMMAND_KICKSELF
);
1680 SetSentErrorMessage(true);
1684 // check online security
1685 if (HasLowerSecurity(player
, 0))
1688 player
->GetSession()->KickPlayer();
1692 std::string name
= kickName
;
1693 if(!normalizePlayerName(name
))
1695 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1696 SetSentErrorMessage(true);
1700 if(m_session
&& name
==m_session
->GetPlayer()->GetName())
1702 SendSysMessage(LANG_COMMAND_KICKSELF
);
1703 SetSentErrorMessage(true);
1707 // check online security
1708 Player
* player
= ObjectAccessor::Instance().FindPlayerByName(name
.c_str());
1709 if (player
&& HasLowerSecurity(player
, 0))
1712 if(sWorld
.KickPlayer(name
))
1714 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,name
.c_str());
1717 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER
,name
.c_str());
1723 //show info of player
1724 bool ChatHandler::HandlePInfoCommand(const char* args
)
1726 Player
* target
= NULL
;
1727 uint64 targetGUID
= 0;
1729 char* px
= strtok((char*)args
, " ");
1741 if(!normalizePlayerName(name
))
1743 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1744 SetSentErrorMessage(true);
1748 target
= objmgr
.GetPlayer(name
.c_str());
1750 py
= strtok(NULL
, " ");
1753 targetGUID
= objmgr
.GetPlayerGUIDByName(name
);
1755 py
= strtok(NULL
, " ");
1761 if(!target
&& !targetGUID
)
1763 target
= getSelectedPlayer();
1766 if(!target
&& !targetGUID
)
1768 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1769 SetSentErrorMessage(true);
1775 uint32 total_player_time
= 0;
1779 // get additional information from Player object
1782 // check online security
1783 if (HasLowerSecurity(target
, 0))
1786 targetGUID
= target
->GetGUID();
1787 name
= target
->GetName(); // re-read for case getSelectedPlayer() target
1788 accId
= target
->GetSession()->GetAccountId();
1789 money
= target
->GetMoney();
1790 total_player_time
= target
->GetTotalPlayedTime();
1791 level
= target
->getLevel();
1792 latency
= target
->GetSession()->GetLatency();
1794 // get additional information from DB
1797 // check offline security
1798 if (HasLowerSecurity(NULL
, targetGUID
))
1802 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID
));
1805 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1806 SetSentErrorMessage(true);
1809 Field
*fields
= result
->Fetch();
1810 total_player_time
= fields
[0].GetUInt32();
1814 if (!Player::LoadValuesArrayFromDB(data
,targetGUID
))
1816 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1817 SetSentErrorMessage(true);
1821 money
= Player::GetUInt32ValueFromArray(data
, PLAYER_FIELD_COINAGE
);
1822 level
= Player::GetUInt32ValueFromArray(data
, UNIT_FIELD_LEVEL
);
1824 accId
= objmgr
.GetPlayerAccountIdByGUID(targetGUID
);
1827 std::string username
= GetMangosString(LANG_ERROR
);
1828 std::string last_ip
= GetMangosString(LANG_ERROR
);
1829 uint32 security
= 0;
1830 std::string last_login
= GetMangosString(LANG_ERROR
);
1832 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
1835 Field
* fields
= result
->Fetch();
1836 username
= fields
[0].GetCppString();
1837 security
= fields
[1].GetUInt32();
1839 if(!m_session
|| m_session
->GetSecurity() >= security
)
1841 last_ip
= fields
[2].GetCppString();
1842 last_login
= fields
[3].GetCppString();
1853 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
);
1855 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
1856 uint32 gold
= money
/GOLD
;
1857 uint32 silv
= (money
% GOLD
) / SILVER
;
1858 uint32 copp
= (money
% GOLD
) % SILVER
;
1859 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
1861 if ( py
&& strncmp(py
, "rep", 3) == 0 )
1865 // rep option not implemented for offline case
1866 SendSysMessage(LANG_PINFO_NO_REP
);
1867 SetSentErrorMessage(true);
1872 for(FactionStateList::const_iterator itr
= target
->m_factions
.begin(); itr
!= target
->m_factions
.end(); ++itr
)
1874 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
1876 FactionName
= factionEntry
->name
[m_session
->GetSessionDbcLocale()];
1878 FactionName
= "#Not found#";
1879 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
1880 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
1881 std::ostringstream ss
;
1882 ss
<< itr
->second
.ID
<< ": |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << FactionName
<< "]|h|r " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
1884 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
1885 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
1886 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
1887 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
1888 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
1889 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
1890 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
1891 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
1892 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
1893 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
1894 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
1895 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
1897 SendSysMessage(ss
.str().c_str());
1904 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
1907 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
1908 name
= GetMangosString(LANG_UNKNOWN
);
1910 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, name
.c_str(),time
,text
);
1914 bool ChatHandler::HandleTicketCommand(const char* args
)
1916 char* px
= strtok((char*)args
, " ");
1923 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1924 SetSentErrorMessage(true);
1928 size_t count
= ticketmgr
.GetTicketCount();
1930 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
1932 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
1937 if(strncmp(px
,"on",3) == 0)
1941 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1942 SetSentErrorMessage(true);
1946 m_session
->GetPlayer()->SetAcceptTicket(true);
1947 SendSysMessage(LANG_COMMAND_TICKETON
);
1952 if(strncmp(px
,"off",4) == 0)
1956 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1957 SetSentErrorMessage(true);
1961 m_session
->GetPlayer()->SetAcceptTicket(false);
1962 SendSysMessage(LANG_COMMAND_TICKETOFF
);
1970 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
1974 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1975 SetSentErrorMessage(true);
1979 Field
* fields
= result
->Fetch();
1981 uint32 guid
= fields
[0].GetUInt32();
1982 char const* text
= fields
[1].GetString();
1983 char const* time
= fields
[2].GetString();
1985 ShowTicket(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
),text
,time
);
1990 std::string name
= px
;
1992 if(!normalizePlayerName(name
))
1994 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1995 SetSentErrorMessage(true);
1999 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2004 // ticket $char_name
2005 GMTicket
* ticket
= ticketmgr
.GetGMTicket(GUID_LOPART(guid
));
2009 std::string time
= TimeToTimestampStr(ticket
->GetLastUpdate());
2011 ShowTicket(guid
, ticket
->GetText(), time
.c_str());
2017 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2019 char* px
= strtok((char*)args
, " ");
2024 if(strncmp(px
,"all",4) == 0)
2026 ticketmgr
.DeleteAll();
2027 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2031 int num
= (uint32
)atoi(px
);
2036 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2039 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2040 SetSentErrorMessage(true);
2043 Field
* fields
= result
->Fetch();
2044 uint32 guid
= fields
[0].GetUInt32();
2047 ticketmgr
.Delete(guid
);
2050 if(Player
* pl
= objmgr
.GetPlayer(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
)))
2052 pl
->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2053 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
, pl
->GetName());
2056 PSendSysMessage(LANG_COMMAND_TICKETDEL
);
2061 std::string name
= px
;
2063 if(!normalizePlayerName(name
))
2065 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2066 SetSentErrorMessage(true);
2070 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2075 // delticket $char_name
2076 ticketmgr
.Delete(GUID_LOPART(guid
));
2078 // notify players about ticket deleting
2079 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2080 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2082 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,px
);
2086 //set spawn dist of creature
2087 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
2092 float option
= atof((char*)args
);
2095 SendSysMessage(LANG_BAD_VALUE
);
2099 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
2101 mtype
= RANDOM_MOTION_TYPE
;
2103 Creature
*pCreature
= getSelectedCreature();
2104 uint32 u_guidlow
= 0;
2107 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2111 pCreature
->SetRespawnRadius((float)option
);
2112 pCreature
->SetDefaultMovementType(mtype
);
2113 pCreature
->GetMotionMaster()->Initialize();
2114 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
2116 pCreature
->setDeathState(JUST_DIED
);
2117 pCreature
->Respawn();
2120 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
2121 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
2125 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
2130 char* stime
= strtok((char*)args
, " ");
2135 int i_stime
= atoi((char*)stime
);
2139 SendSysMessage(LANG_BAD_VALUE
);
2140 SetSentErrorMessage(true);
2144 Creature
*pCreature
= getSelectedCreature();
2145 uint32 u_guidlow
= 0;
2148 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2152 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
2153 pCreature
->SetRespawnDelay((uint32
)i_stime
);
2154 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
2160 * Add a waypoint to a creature.
2162 * The user can either select an npc or provide its GUID.
2164 * The user can even select a visual waypoint - then the new waypoint
2165 * is placed *after* the selected one - this makes insertion of new
2166 * waypoints possible.
2170 * -> adds a waypoint to the npc with the GUID 12345
2173 * -> adds a waypoint to the currently selected creature
2176 * @param args if the user did not provide a GUID, it is NULL
2178 * @return true - command did succeed, false - something went wrong
2180 bool ChatHandler::HandleWpAddCommand(const char* args
)
2182 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2185 char* guid_str
= NULL
;
2189 guid_str
= strtok((char*)args
, " ");
2194 Creature
* target
= getSelectedCreature();
2195 // Did player provide a GUID?
2198 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2201 // -> Player must have selected a creature
2203 if(!target
|| target
->isPet())
2205 SendSysMessage(LANG_SELECT_CREATURE
);
2206 SetSentErrorMessage(true);
2209 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2211 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2213 QueryResult
*result
=
2214 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2215 target
->GetGUIDLow() );
2218 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2219 // User selected a visual spawnpoint -> get the NPC
2221 // Since we compare float values, we have to deal with
2222 // some difficulties.
2223 // Here we search for all waypoints that only differ in one from 1 thousand
2224 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2225 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2226 const char* maxDIFF
= "0.01";
2227 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 )",
2228 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2231 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2232 SetSentErrorMessage(true);
2238 Field
*fields
= result
->Fetch();
2239 lowguid
= fields
[0].GetUInt32();
2240 point
= fields
[1].GetUInt32();
2241 }while( result
->NextRow() );
2244 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2247 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2248 SetSentErrorMessage(true);
2252 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2255 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2256 SetSentErrorMessage(true);
2262 lowguid
= target
->GetDBTableGUIDLow();
2267 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2270 // Warn if player also selected a creature
2271 // -> Creature selection is ignored <-
2274 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2276 lowguid
= atoi((char*)guid_str
);
2278 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2281 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2282 SetSentErrorMessage(true);
2286 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2287 if(!target
|| target
->isPet())
2289 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2290 SetSentErrorMessage(true);
2294 // lowguid -> GUID of the NPC
2295 // point -> number of the waypoint (if not 0)
2296 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2298 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2300 Player
* player
= m_session
->GetPlayer();
2301 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2303 // update movement type
2306 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2307 target
->GetMotionMaster()->Initialize();
2308 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2310 target
->setDeathState(JUST_DIED
);
2316 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2318 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2321 } // HandleWpAddCommand
2324 * .wp modify emote | spell | text | del | move | add
2326 * add -> add a WP after the selected visual waypoint
2327 * User must select a visual waypoint and then issue ".wp modify add"
2330 * User has selected a visual waypoint before.
2331 * <emoteID> is added to this waypoint. Everytime the
2332 * NPC comes to this waypoint, the emote is called.
2334 * emote <GUID> <WPNUM> <emoteID>
2335 * User has not selected visual waypoint before.
2336 * For the waypoint <WPNUM> for the NPC with <GUID>
2337 * an emote <emoteID> is added.
2338 * Everytime the NPC comes to this waypoint, the emote is called.
2341 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2343 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2345 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2350 // first arg: add del text emote spell waittime move
2351 char* show_str
= strtok((char*)args
, " ");
2357 std::string show
= show_str
;
2359 // Remember: "show" must also be the name of a column!
2360 if( (show
!= "emote") && (show
!= "spell") && (show
!= "textid1") && (show
!= "textid2")
2361 && (show
!= "textid3") && (show
!= "textid4") && (show
!= "textid5")
2362 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2363 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2368 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2370 // Did user provide a GUID
2371 // or did the user select a creature?
2372 // -> variable lowguid is filled with the GUID of the NPC
2376 Creature
* target
= getSelectedCreature();
2380 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2382 // Did the user select a visual spawnpoint?
2383 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2385 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2386 SetSentErrorMessage(true);
2390 wpGuid
= target
->GetGUIDLow();
2392 // The visual waypoint
2393 QueryResult
*result
=
2394 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2395 target
->GetGUIDLow() );
2398 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2399 SetSentErrorMessage(true);
2402 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2404 Field
*fields
= result
->Fetch();
2405 lowguid
= fields
[0].GetUInt32();
2406 point
= fields
[1].GetUInt32();
2409 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2414 // User did provide <GUID> <WPNUM>
2416 char* guid_str
= strtok((char*)NULL
, " ");
2419 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2422 lowguid
= atoi((char*)guid_str
);
2424 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2427 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2428 SetSentErrorMessage(true);
2432 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2434 char* point_str
= strtok((char*)NULL
, " ");
2437 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2440 point
= atoi((char*)point_str
);
2442 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2444 // Now we need the GUID of the visual waypoint
2445 // -> "del", "move", "add" command
2447 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2450 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2451 SetSentErrorMessage(true);
2455 Field
*fields
= result
->Fetch();
2456 wpGuid
= fields
[0].GetUInt32();
2462 char* arg_str
= NULL
;
2463 // Check for argument
2464 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2466 // Text is enclosed in "<>", all other arguments not
2467 if( show
.find("text") != std::string::npos
)
2468 arg_str
= strtok((char*)NULL
, "<>");
2470 arg_str
= strtok((char*)NULL
, " ");
2474 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2479 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2481 // wpGuid -> GUID of the waypoint creature
2482 // lowguid -> GUID of the NPC
2483 // point -> waypoint number
2485 // Special functions:
2486 // add - move - del -> no args commands
2487 // Add a waypoint after the selected visual
2488 if(show
== "add" && target
)
2490 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2492 // Get the creature for which we read the waypoint
2493 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2496 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2497 SetSentErrorMessage(true);
2501 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2505 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2506 SetSentErrorMessage(true);
2510 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2513 // Add the visual spawnpoint (DB only)
2514 // Adjust the waypoints
2515 // Respawn the owner of the waypoints
2516 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2518 Player
* chr
= m_session
->GetPlayer();
2519 Map
*map
= chr
->GetMap();
2523 npcCreature
->GetMotionMaster()->Initialize();
2524 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2526 npcCreature
->setDeathState(JUST_DIED
);
2527 npcCreature
->Respawn();
2531 // create the waypoint creature
2533 Creature
* wpCreature
= new Creature
;
2534 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
,VISUAL_WAYPOINT
,0))
2536 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2541 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2543 if(!wpCreature
->IsPositionValid())
2545 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());
2550 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2551 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2552 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2553 map
->Add(wpCreature
);
2554 wpGuid
= wpCreature
->GetGUIDLow();
2558 WaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2563 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2567 if(show
== "del" && target
)
2569 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2571 // Get the creature for which we read the waypoint
2572 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2575 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2576 SetSentErrorMessage(true);
2580 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2583 Creature
* wpCreature
= NULL
;
2586 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2587 wpCreature
->DeleteFromDB();
2588 wpCreature
->CleanupsBeforeDelete();
2589 wpCreature
->AddObjectToRemoveList();
2593 // Remove the visual spawnpoint
2594 // Adjust the waypoints
2595 // Respawn the owner of the waypoints
2597 WaypointMgr
.DeleteNode(lowguid
, point
);
2601 // Any waypoints left?
2602 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2605 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2609 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2612 npcCreature
->GetMotionMaster()->Initialize();
2613 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2615 npcCreature
->setDeathState(JUST_DIED
);
2616 npcCreature
->Respawn();
2618 npcCreature
->SaveToDB();
2621 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2625 if(show
== "move" && target
)
2627 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2629 Player
*chr
= m_session
->GetPlayer();
2630 Map
*map
= chr
->GetMap();
2632 // Get the creature for which we read the waypoint
2633 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2636 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2637 SetSentErrorMessage(true);
2641 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2644 Creature
* wpCreature
= NULL
;
2646 // Move the visual spawnpoint
2647 // Respawn the owner of the waypoints
2650 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2651 wpCreature
->DeleteFromDB();
2652 wpCreature
->CleanupsBeforeDelete();
2653 wpCreature
->AddObjectToRemoveList();
2655 Creature
* wpCreature2
= new Creature
;
2656 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, VISUAL_WAYPOINT
, 0))
2658 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2663 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2665 if(!wpCreature2
->IsPositionValid())
2667 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());
2672 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2673 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2674 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2675 map
->Add(wpCreature2
);
2676 //npcCreature->GetMap()->Add(wpCreature2);
2679 WaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2683 npcCreature
->GetMotionMaster()->Initialize();
2684 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2686 npcCreature
->setDeathState(JUST_DIED
);
2687 npcCreature
->Respawn();
2690 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2695 // Create creature - npc that has the waypoint
2696 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2699 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2700 SetSentErrorMessage(true);
2704 // set in game textids not supported
2705 if( show
== "textid1" || show
== "textid2" || show
== "textid3" ||
2706 show
== "textid4" || show
== "textid5" )
2711 WaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2713 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2716 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2717 npcCreature
->GetMotionMaster()->Initialize();
2718 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2720 npcCreature
->setDeathState(JUST_DIED
);
2721 npcCreature
->Respawn();
2724 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2730 * .wp show info | on | off
2732 * info -> User has selected a visual waypoint before
2734 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2735 * provided the GUID of the NPC and the number of
2738 * on -> User has selected an NPC; all visual waypoints for this
2739 * NPC are added to the world
2741 * on <GUID> -> User did not select an NPC - instead the GUID of the
2742 * NPC is provided. All visual waypoints for this NPC
2743 * are added from the world.
2745 * off -> User has selected an NPC; all visual waypoints for this
2746 * NPC are removed from the world.
2748 * on <GUID> -> User did not select an NPC - instead the GUID of the
2749 * NPC is provided. All visual waypoints for this NPC
2750 * are removed from the world.
2754 bool ChatHandler::HandleWpShowCommand(const char* args
)
2756 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2761 // first arg: on, off, first, last
2762 char* show_str
= strtok((char*)args
, " ");
2767 // second arg: GUID (optional, if a creature is selected)
2768 char* guid_str
= strtok((char*)NULL
, " ");
2769 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2774 // Did user provide a GUID
2775 // or did the user select a creature?
2776 // -> variable lowguid is filled with the GUID
2777 Creature
* target
= getSelectedCreature();
2778 // Did player provide a GUID?
2781 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2783 // -> Player must have selected a creature
2787 SendSysMessage(LANG_SELECT_CREATURE
);
2788 SetSentErrorMessage(true);
2794 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2796 // Warn if player also selected a creature
2797 // -> Creature selection is ignored <-
2800 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2803 uint32 lowguid
= atoi((char*)guid_str
);
2805 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2808 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2809 SetSentErrorMessage(true);
2813 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2817 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2818 SetSentErrorMessage(true);
2823 uint32 lowguid
= target
->GetDBTableGUIDLow();
2825 std::string show
= show_str
;
2828 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
2830 // Show info for the selected waypoint
2833 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
2835 // Check if the user did specify a visual waypoint
2836 if( target
->GetEntry() != VISUAL_WAYPOINT
)
2838 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2839 SetSentErrorMessage(true);
2843 //PSendSysMessage("wp on, GUID: %u", lowguid);
2845 //pCreature->GetPositionX();
2847 QueryResult
*result
=
2848 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2849 target
->GetGUIDLow() );
2852 // Since we compare float values, we have to deal with
2853 // some difficulties.
2854 // Here we search for all waypoints that only differ in one from 1 thousand
2855 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2856 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2857 const char* maxDIFF
= "0.01";
2858 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
2860 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 )",
2861 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2864 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2865 SetSentErrorMessage(true);
2871 Field
*fields
= result
->Fetch();
2872 uint32 creGUID
= fields
[0].GetUInt32();
2873 uint32 point
= fields
[1].GetUInt32();
2874 int waittime
= fields
[2].GetUInt32();
2875 uint32 emote
= fields
[3].GetUInt32();
2876 uint32 spell
= fields
[4].GetUInt32();
2877 uint32 textid
[MAX_WAYPOINT_TEXT
];
2878 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
2879 textid
[i
] = fields
[5+i
].GetUInt32();
2880 uint32 model1
= fields
[10].GetUInt32();
2881 uint32 model2
= fields
[11].GetUInt32();
2883 // Get the creature for which we read the waypoint
2884 Creature
* wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2886 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
2887 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
2888 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
2889 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
2890 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
2891 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
2892 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
2893 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, i
+1, textid
[i
], (textid
[i
] ? GetMangosString(textid
[i
]) : ""));
2895 }while( result
->NextRow() );
2903 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
2905 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
2908 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2909 SetSentErrorMessage(true);
2912 // Delete all visuals for this NPC
2913 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
2916 bool hasError
= false;
2919 Field
*fields
= result2
->Fetch();
2920 uint32 wpguid
= fields
[0].GetUInt32();
2921 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2925 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
2927 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
2931 pCreature
->DeleteFromDB();
2932 pCreature
->CleanupsBeforeDelete();
2933 pCreature
->AddObjectToRemoveList();
2936 }while( result2
->NextRow() );
2940 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2941 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
2942 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
2948 Field
*fields
= result
->Fetch();
2949 uint32 point
= fields
[0].GetUInt32();
2950 float x
= fields
[1].GetFloat();
2951 float y
= fields
[2].GetFloat();
2952 float z
= fields
[3].GetFloat();
2954 uint32 id
= VISUAL_WAYPOINT
;
2956 Player
*chr
= m_session
->GetPlayer();
2957 Map
*map
= chr
->GetMap();
2958 float o
= chr
->GetOrientation();
2960 Creature
* wpCreature
= new Creature
;
2961 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
2963 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
2969 wpCreature
->Relocate(x
, y
, z
, o
);
2971 if(!wpCreature
->IsPositionValid())
2973 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());
2979 wpCreature
->SetVisibility(VISIBILITY_OFF
);
2980 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
2981 // set "wpguid" column to the visual waypoint
2982 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
2984 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2985 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2986 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
2987 map
->Add(wpCreature
);
2988 //wpCreature->GetMap()->Add(wpCreature);
2989 }while( result
->NextRow() );
2998 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3000 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3003 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3004 SetSentErrorMessage(true);
3008 Field
*fields
= result
->Fetch();
3009 float x
= fields
[0].GetFloat();
3010 float y
= fields
[1].GetFloat();
3011 float z
= fields
[2].GetFloat();
3012 uint32 id
= VISUAL_WAYPOINT
;
3014 Player
*chr
= m_session
->GetPlayer();
3015 float o
= chr
->GetOrientation();
3016 Map
*map
= chr
->GetMap();
3018 Creature
* pCreature
= new Creature
;
3019 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, id
, 0))
3021 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3027 pCreature
->Relocate(x
, y
, z
, o
);
3029 if(!pCreature
->IsPositionValid())
3031 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());
3037 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3038 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3039 map
->Add(pCreature
);
3040 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3049 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3051 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3054 Maxpoint
= (*result
)[0].GetUInt32();
3061 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3064 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3065 SetSentErrorMessage(true);
3068 Field
*fields
= result
->Fetch();
3069 float x
= fields
[0].GetFloat();
3070 float y
= fields
[1].GetFloat();
3071 float z
= fields
[2].GetFloat();
3072 uint32 id
= VISUAL_WAYPOINT
;
3074 Player
*chr
= m_session
->GetPlayer();
3075 float o
= chr
->GetOrientation();
3076 Map
*map
= chr
->GetMap();
3078 Creature
* pCreature
= new Creature
;
3079 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
3081 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3087 pCreature
->Relocate(x
, y
, z
, o
);
3089 if(!pCreature
->IsPositionValid())
3091 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());
3097 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3098 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3099 map
->Add(pCreature
);
3100 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3108 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3111 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3112 SetSentErrorMessage(true);
3115 bool hasError
= false;
3118 Field
*fields
= result
->Fetch();
3119 uint32 guid
= fields
[0].GetUInt32();
3120 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3122 //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3126 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3128 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3132 pCreature
->DeleteFromDB();
3133 pCreature
->CleanupsBeforeDelete();
3134 pCreature
->AddObjectToRemoveList();
3136 }while(result
->NextRow());
3137 // set "wpguid" column to "empty" - no visual waypoint spawned
3138 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3142 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3143 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3144 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3147 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3154 PSendSysMessage("DEBUG: wpshow - no valid command found");
3157 } // HandleWpShowCommand
3159 bool ChatHandler::HandleWpExportCommand(const char *args
)
3164 // Next arg is: <GUID> <ARGUMENT>
3166 // Did user provide a GUID
3167 // or did the user select a creature?
3168 // -> variable lowguid is filled with the GUID of the NPC
3170 Creature
* target
= getSelectedCreature();
3171 char* arg_str
= NULL
;
3174 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3175 lowguid
= target
->GetGUIDLow();
3178 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3181 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3184 Field
*fields
= result
->Fetch();
3185 lowguid
= fields
[0].GetUInt32();;
3189 arg_str
= strtok((char*)args
, " ");
3193 // user provided <GUID>
3194 char* guid_str
= strtok((char*)args
, " ");
3197 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3200 lowguid
= atoi((char*)guid_str
);
3202 arg_str
= strtok((char*)NULL
, " ");
3207 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3211 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3213 QueryResult
*result
= WorldDatabase
.PQuery(
3214 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3215 "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
);
3219 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3220 SetSentErrorMessage(true);
3224 std::ofstream outfile
;
3225 outfile
.open (arg_str
);
3229 Field
*fields
= result
->Fetch();
3231 outfile
<< "INSERT INTO creature_movement ";
3232 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3235 outfile
<< fields
[15].GetUInt32(); // id
3237 outfile
<< fields
[0].GetUInt32(); // point
3239 outfile
<< fields
[1].GetFloat(); // position_x
3241 outfile
<< fields
[2].GetFloat(); // position_y
3243 outfile
<< fields
[3].GetUInt32(); // position_z
3245 outfile
<< fields
[4].GetUInt32(); // orientation
3247 outfile
<< fields
[5].GetUInt32(); // model1
3249 outfile
<< fields
[6].GetUInt32(); // model2
3251 outfile
<< fields
[7].GetUInt16(); // waittime
3253 outfile
<< fields
[8].GetUInt32(); // emote
3255 outfile
<< fields
[9].GetUInt32(); // spell
3257 outfile
<< fields
[10].GetUInt32(); // textid1
3259 outfile
<< fields
[11].GetUInt32(); // textid2
3261 outfile
<< fields
[12].GetUInt32(); // textid3
3263 outfile
<< fields
[13].GetUInt32(); // textid4
3265 outfile
<< fields
[14].GetUInt32(); // textid5
3268 } while( result
->NextRow() );
3271 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3277 bool ChatHandler::HandleWpImportCommand(const char *args
)
3282 char* arg_str
= strtok((char*)args
, " ");
3287 std::ifstream
infile (arg_str
);
3288 if (infile
.is_open())
3290 while (! infile
.eof() )
3292 getline (infile
,line
);
3293 //cout << line << endl;
3294 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3299 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3305 bool ChatHandler::HandleRenameCommand(const char* args
)
3307 Player
* target
= NULL
;
3308 uint64 targetGUID
= 0;
3309 std::string oldname
;
3311 char* px
= strtok((char*)args
, " ");
3317 if(!normalizePlayerName(oldname
))
3319 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3320 SetSentErrorMessage(true);
3324 target
= objmgr
.GetPlayer(oldname
.c_str());
3327 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3330 if(!target
&& !targetGUID
)
3332 target
= getSelectedPlayer();
3335 if(!target
&& !targetGUID
)
3337 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3338 SetSentErrorMessage(true);
3344 // check online security
3345 if (HasLowerSecurity(target
, 0))
3348 PSendSysMessage(LANG_RENAME_PLAYER
, target
->GetName());
3349 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3350 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3354 // check offline security
3355 if (HasLowerSecurity(NULL
, targetGUID
))
3358 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
3359 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3365 // customize characters
3366 bool ChatHandler::HandleCustomizeCommand(const char* args
)
3368 Player
* target
= NULL
;
3369 uint64 targetGUID
= 0;
3370 std::string oldname
;
3372 char* px
= strtok((char*)args
, " ");
3378 if(!normalizePlayerName(oldname
))
3380 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3381 SetSentErrorMessage(true);
3385 target
= objmgr
.GetPlayer(oldname
.c_str());
3388 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3391 if(!target
&& !targetGUID
)
3393 target
= getSelectedPlayer();
3396 if(!target
&& !targetGUID
)
3398 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3399 SetSentErrorMessage(true);
3405 PSendSysMessage(LANG_CUSTOMIZE_PLAYER
, target
->GetName());
3406 target
->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE
);
3407 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target
->GetGUIDLow());
3411 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
3412 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3419 bool ChatHandler::HandleGameObjectCommand(const char* args
)
3424 char* pParam1
= strtok((char*)args
, " ");
3428 uint32 id
= atoi((char*)pParam1
);
3432 char* spawntimeSecs
= strtok(NULL
, " ");
3434 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
3438 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
3439 SetSentErrorMessage(true);
3443 Player
*chr
= m_session
->GetPlayer();
3444 float x
= float(chr
->GetPositionX());
3445 float y
= float(chr
->GetPositionY());
3446 float z
= float(chr
->GetPositionZ());
3447 float o
= float(chr
->GetOrientation());
3448 Map
*map
= chr
->GetMap();
3450 float rot2
= sin(o
/2);
3451 float rot3
= cos(o
/2);
3453 GameObject
* pGameObj
= new GameObject
;
3454 uint32 db_lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
3456 if(!pGameObj
->Create(db_lowGUID
, goI
->id
, map
, x
, y
, z
, o
, 0, 0, rot2
, rot3
, 0, 1))
3464 uint32 value
= atoi((char*)spawntimeSecs
);
3465 pGameObj
->SetRespawnTime(value
);
3466 //sLog.outDebug("*** spawntimeSecs: %d", value);
3469 // fill the gameobject data and save to the db
3470 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3472 // this will generate a new guid if the object is in an instance
3473 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
3479 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), goI
->name
, db_lowGUID
, x
, y
, z
, o
);
3483 // TODO: is it really necessary to add both the real and DB table guid here ?
3484 objmgr
.AddGameobjectToGrid(db_lowGUID
, objmgr
.GetGOData(db_lowGUID
));
3486 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,goI
->name
,db_lowGUID
,x
,y
,z
);
3491 bool ChatHandler::HandleAnimCommand(const char* args
)
3496 uint32 anim_id
= atoi((char*)args
);
3497 m_session
->GetPlayer()->HandleEmoteCommand(anim_id
);
3502 bool ChatHandler::HandleStandStateCommand(const char* args
)
3507 uint32 anim_id
= atoi((char*)args
);
3508 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3513 bool ChatHandler::HandleAddHonorCommand(const char* args
)
3518 Player
*target
= getSelectedPlayer();
3521 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3522 SetSentErrorMessage(true);
3526 // check online security
3527 if (HasLowerSecurity(target
, 0))
3530 uint32 amount
= (uint32
)atoi(args
);
3531 target
->RewardHonor(NULL
, 1, amount
);
3535 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3537 Unit
*target
= getSelectedUnit();
3540 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3541 SetSentErrorMessage(true);
3545 // check online security
3546 if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
3549 m_session
->GetPlayer()->RewardHonor(target
, 1);
3553 bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3555 Player
*target
= getSelectedPlayer();
3558 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3559 SetSentErrorMessage(true);
3563 // check online security
3564 if (HasLowerSecurity(target
, 0))
3567 target
->UpdateHonorFields();
3571 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3576 std::string namepart
= args
;
3577 std::wstring wnamepart
;
3579 // converting string that we try to find to lower case
3580 if(!Utf8toWStr(namepart
,wnamepart
))
3583 wstrToLower(wnamepart
);
3587 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3588 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3590 for(uint32 id
= 0; id
< events
.size(); ++id
)
3592 GameEventData
const& eventData
= events
[id
];
3594 std::string descr
= eventData
.description
;
3598 if (Utf8FitTo(descr
, wnamepart
))
3600 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3603 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3605 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3612 SendSysMessage(LANG_NOEVENTFOUND
);
3617 bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
3621 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3622 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3624 char const* active
= GetMangosString(LANG_ACTIVE
);
3626 for(GameEvent::ActiveEvents::const_iterator itr
= activeEvents
.begin(); itr
!= activeEvents
.end(); ++itr
)
3628 uint32 event_id
= *itr
;
3629 GameEventData
const& eventData
= events
[event_id
];
3632 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,event_id
,event_id
,eventData
.description
.c_str(),active
);
3634 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,event_id
,eventData
.description
.c_str(),active
);
3640 SendSysMessage(LANG_NOEVENTFOUND
);
3645 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3650 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3651 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3655 uint32 event_id
= atoi(cId
);
3657 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3659 if(event_id
>=events
.size())
3661 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3662 SetSentErrorMessage(true);
3666 GameEventData
const& eventData
= events
[event_id
];
3667 if(!eventData
.isValid())
3669 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3670 SetSentErrorMessage(true);
3674 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3675 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3676 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3678 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3679 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3681 uint32 delay
= gameeventmgr
.NextCheck(event_id
);
3682 time_t nextTime
= time(NULL
)+delay
;
3683 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3685 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3686 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3688 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3689 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3694 bool ChatHandler::HandleEventStartCommand(const char* args
)
3699 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3700 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3704 int32 event_id
= atoi(cId
);
3706 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3708 if(event_id
< 1 || event_id
>=events
.size())
3710 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3711 SetSentErrorMessage(true);
3715 GameEventData
const& eventData
= events
[event_id
];
3716 if(!eventData
.isValid())
3718 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3719 SetSentErrorMessage(true);
3723 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3724 if(activeEvents
.find(event_id
) != activeEvents
.end())
3726 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3727 SetSentErrorMessage(true);
3731 gameeventmgr
.StartEvent(event_id
,true);
3735 bool ChatHandler::HandleEventStopCommand(const char* args
)
3740 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3741 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3745 int32 event_id
= atoi(cId
);
3747 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3749 if(event_id
< 1 || event_id
>=events
.size())
3751 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3752 SetSentErrorMessage(true);
3756 GameEventData
const& eventData
= events
[event_id
];
3757 if(!eventData
.isValid())
3759 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3760 SetSentErrorMessage(true);
3764 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3766 if(activeEvents
.find(event_id
) == activeEvents
.end())
3768 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3769 SetSentErrorMessage(true);
3773 gameeventmgr
.StopEvent(event_id
,true);
3777 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3783 std::string playername
= args
;
3785 if(!normalizePlayerName(playername
))
3787 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3788 SetSentErrorMessage(true);
3792 player
= objmgr
.GetPlayer(playername
.c_str());
3796 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3797 SetSentErrorMessage(true);
3803 player
= getSelectedPlayer();
3806 player
= m_session
->GetPlayer();
3809 // check online security
3810 if (HasLowerSecurity(player
, 0))
3813 player
->CombatStop();
3814 player
->getHostilRefManager().deleteReferences();
3818 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3820 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3822 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3824 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3828 if( skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
)
3830 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3832 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3836 // skip racial skills
3837 if( skillLine
->racemask
!= 0 )
3840 // skip wrong class skills
3841 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3844 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3847 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3848 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3851 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3856 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
3860 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
3862 // Learns all recipes of specified profession and sets skill to max
3863 // Example: .learn all_recipes enchanting
3865 Player
* target
= getSelectedPlayer();
3868 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3875 std::wstring wnamepart
;
3877 if(!Utf8toWStr(args
,wnamepart
))
3880 // converting string that we try to find to lower case
3881 wstrToLower( wnamepart
);
3883 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3885 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3887 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3891 if( skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
3892 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
)
3895 int loc
= m_session
->GetSessionDbcLocale();
3896 std::string name
= skillInfo
->name
[loc
];
3898 if(Utf8FitTo(name
, wnamepart
))
3900 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3902 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3906 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3909 // skip racial skills
3910 if( skillLine
->racemask
!= 0 )
3913 // skip wrong class skills
3914 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3917 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3918 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3921 if( !target
->HasSpell(spellInfo
->Id
) )
3922 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3925 uint16 maxLevel
= target
->GetPureMaxSkillValue(skillInfo
->id
);
3926 target
->SetSkill(skillInfo
->id
, maxLevel
, maxLevel
);
3927 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
3935 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
3941 std::string ip
= strtok ((char*)args
, " ");
3942 char* limit_str
= strtok (NULL
, " ");
3943 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3945 loginDatabase
.escape_string (ip
);
3947 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
3949 return LookupPlayerSearchCommand (result
,limit
);
3952 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
3957 std::string account
= strtok ((char*)args
, " ");
3958 char* limit_str
= strtok (NULL
, " ");
3959 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3961 if (!AccountMgr::normilizeString (account
))
3964 loginDatabase
.escape_string (account
);
3966 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
3968 return LookupPlayerSearchCommand (result
,limit
);
3971 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
3977 std::string email
= strtok ((char*)args
, " ");
3978 char* limit_str
= strtok (NULL
, " ");
3979 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3981 loginDatabase
.escape_string (email
);
3983 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
3985 return LookupPlayerSearchCommand (result
,limit
);
3988 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
3992 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
3993 SetSentErrorMessage(true);
4000 Field
* fields
= result
->Fetch();
4001 uint32 acc_id
= fields
[0].GetUInt32();
4002 std::string acc_name
= fields
[1].GetCppString();
4004 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4007 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4014 Field
* charfields
= chars
->Fetch();
4015 guid
= charfields
[0].GetUInt64();
4016 name
= charfields
[1].GetCppString();
4018 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4021 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4025 } while(result
->NextRow());
4032 /// Triggering corpses expire check in world
4033 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4039 bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
4041 Player
*target
= getSelectedPlayer();
4045 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4046 SetSentErrorMessage(true);
4050 // check online security
4051 if (HasLowerSecurity(target
, 0))
4055 target
->DurabilityRepairAll(false, 0, false);
4057 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, target
->GetName());
4058 if(needReportToTarget(target
))
4059 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetName());
4063 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4068 Player
*player
= getSelectedPlayer();
4072 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4073 SetSentErrorMessage(true);
4077 // check online security
4078 if (HasLowerSecurity(player
, 0))
4081 if (strncmp(args
, "on", 3) == 0)
4082 player
->SetMovement(MOVE_WATER_WALK
); // ON
4083 else if (strncmp(args
, "off", 4) == 0)
4084 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4087 SendSysMessage(LANG_USE_BOL
);
4091 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, player
->GetName());
4092 if(needReportToTarget(player
))
4093 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetName());
4097 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
4099 Player
*player
= m_session
->GetPlayer();
4100 Creature
*creature
= getSelectedCreature();
4104 PSendSysMessage(LANG_SELECT_CREATURE
);
4105 SetSentErrorMessage(true);
4109 // Follow player - Using pet's default dist and angle
4110 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
4112 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
4116 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
4118 Player
*player
= m_session
->GetPlayer();
4119 Creature
*creature
= getSelectedCreature();
4123 PSendSysMessage(LANG_SELECT_CREATURE
);
4124 SetSentErrorMessage(true);
4128 if (creature
->GetMotionMaster()->empty() ||
4129 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE
)
4131 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4132 SetSentErrorMessage(true);
4136 TargetedMovementGenerator
<Creature
> const* mgen
4137 = static_cast<TargetedMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
4139 if(mgen
->GetTarget()!=player
)
4141 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4142 SetSentErrorMessage(true);
4147 creature
->GetMotionMaster()->MovementExpired(true);
4149 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
4153 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
4155 Creature
*creatureTarget
= getSelectedCreature ();
4156 if (!creatureTarget
|| creatureTarget
->isPet ())
4158 PSendSysMessage (LANG_SELECT_CREATURE
);
4159 SetSentErrorMessage (true);
4163 Player
*player
= m_session
->GetPlayer ();
4165 if(player
->GetPetGUID ())
4167 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
4168 SetSentErrorMessage (true);
4172 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
4174 if (!cInfo
->isTameable ())
4176 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4177 SetSentErrorMessage (true);
4181 // Everything looks OK, create new pet
4182 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
4185 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4186 SetSentErrorMessage (true);
4190 // place pet before player
4192 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
4193 pet
->Relocate (x
,y
,z
,M_PI
-player
->GetOrientation ());
4195 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
4196 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
4198 // calculate proper level
4199 uint32 level
= (creatureTarget
->getLevel() < (player
->getLevel() - 5)) ? (player
->getLevel() - 5) : creatureTarget
->getLevel();
4201 // prepare visual effect for levelup
4202 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
- 1);
4205 pet
->GetMap()->Add((Creature
*)pet
);
4207 // visual effect for levelup
4208 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
);
4210 // caster have pet now
4211 player
->SetPet(pet
);
4213 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
4214 player
->PetSpellInitialize();