2 * Copyright (C) 2005-2010 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 "DBCStores.h"
22 #include "ObjectMgr.h"
23 #include "ObjectGuid.h"
26 #include "GameObject.h"
29 #include "ObjectAccessor.h"
30 #include "MapManager.h"
33 #include "GameEventMgr.h"
35 #include "PoolManager.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
)
59 extractOptFirstArg((char*)args
,&nameStr
,&delayStr
);
65 std::string target_name
;
66 if(!extractPlayerTarget(nameStr
,&target
,&target_guid
,&target_name
))
69 uint32 account_id
= target
? target
->GetSession()->GetAccountId() : sObjectMgr
.GetPlayerAccountIdByGUID(target_guid
);
71 // find only player from same account if any
74 if(WorldSession
* session
= sWorld
.FindSession(account_id
))
75 target
= session
->GetPlayer();
78 uint32 notspeaktime
= (uint32
) atoi(delayStr
);
80 // must have strong lesser security level
81 if(HasLowerSecurity (target
,target_guid
,true))
84 time_t mutetime
= time(NULL
) + notspeaktime
*60;
87 target
->GetSession()->m_muteTime
= mutetime
;
89 loginDatabase
.PExecute("UPDATE account SET mutetime = " UI64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
92 ChatHandler(target
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
94 std::string nameLink
= playerLink(target_name
);
96 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, nameLink
.c_str(), notspeaktime
);
101 bool ChatHandler::HandleUnmuteCommand(const char* args
)
105 std::string target_name
;
106 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
109 uint32 account_id
= target
? target
->GetSession()->GetAccountId() : sObjectMgr
.GetPlayerAccountIdByGUID(target_guid
);
111 // find only player from same account if any
114 if(WorldSession
* session
= sWorld
.FindSession(account_id
))
115 target
= session
->GetPlayer();
118 // must have strong lesser security level
119 if(HasLowerSecurity (target
,target_guid
,true))
124 if(target
->CanSpeak())
126 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
127 SetSentErrorMessage(true);
131 target
->GetSession()->m_muteTime
= 0;
134 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
137 ChatHandler(target
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
139 std::string nameLink
= playerLink(target_name
);
141 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, nameLink
.c_str());
145 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
147 Player
* _player
= m_session
->GetPlayer();
152 char *atId
= strtok((char*)args
, " ");
156 int32 i_atId
= atoi(atId
);
161 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
164 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
165 SetSentErrorMessage(true);
169 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
171 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
172 SetSentErrorMessage(true);
176 // stop flight if need
177 if(_player
->isInFlight())
179 _player
->GetMotionMaster()->MovementExpired();
180 _player
->m_taxi
.ClearTaxiDestinations();
182 // save only in non-flight case
184 _player
->SaveRecallPosition();
186 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
190 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
192 Player
* _player
= m_session
->GetPlayer();
197 char *gyId
= strtok((char*)args
, " ");
201 int32 i_gyId
= atoi(gyId
);
206 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
209 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
210 SetSentErrorMessage(true);
214 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
216 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
217 SetSentErrorMessage(true);
221 // stop flight if need
222 if(_player
->isInFlight())
224 _player
->GetMotionMaster()->MovementExpired();
225 _player
->m_taxi
.ClearTaxiDestinations();
227 // save only in non-flight case
229 _player
->SaveRecallPosition();
231 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
235 /** \brief Teleport the GM to the specified creature
237 * .gocreature <GUID> --> TP using creature.guid
238 * .gocreature azuregos --> TP player to the mob with this name
239 * Warning: If there is more than one mob with this name
240 * you will be teleported to the first one that is found.
241 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
242 * Warning: If there is more than one mob with this "id"
243 * you will be teleported to the first one that is found.
245 //teleport to creature
246 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
250 Player
* _player
= m_session
->GetPlayer();
252 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
253 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
257 std::ostringstream whereClause
;
259 // User wants to teleport to the NPC's template entry
260 if( strcmp(pParam1
, "id") == 0 )
262 //sLog.outError("DEBUG: ID found");
264 // Get the "creature_template.entry"
265 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
266 char* tail
= strtok(NULL
,"");
269 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
273 int32 tEntry
= atoi(cId
);
274 //sLog.outError("DEBUG: ID value: %d", tEntry);
278 whereClause
<< "WHERE id = '" << tEntry
<< "'";
282 //sLog.outError("DEBUG: ID *not found*");
284 int32 guid
= atoi(pParam1
);
286 // Number is invalid - maybe the user specified the mob's name
289 std::string name
= pParam1
;
290 WorldDatabase
.escape_string(name
);
291 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
295 whereClause
<< "WHERE guid = '" << guid
<< "'";
298 //sLog.outError("DEBUG: %s", whereClause.c_str());
300 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
303 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
304 SetSentErrorMessage(true);
307 if( result
->GetRowCount() > 1 )
309 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
312 Field
*fields
= result
->Fetch();
313 float x
= fields
[0].GetFloat();
314 float y
= fields
[1].GetFloat();
315 float z
= fields
[2].GetFloat();
316 float ort
= fields
[3].GetFloat();
317 int mapid
= fields
[4].GetUInt16();
321 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
323 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
324 SetSentErrorMessage(true);
328 // stop flight if need
329 if(_player
->isInFlight())
331 _player
->GetMotionMaster()->MovementExpired();
332 _player
->m_taxi
.ClearTaxiDestinations();
334 // save only in non-flight case
336 _player
->SaveRecallPosition();
338 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
342 //teleport to gameobject
343 bool ChatHandler::HandleGoObjectCommand(const char* args
)
348 Player
* _player
= m_session
->GetPlayer();
350 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
351 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
355 int32 guid
= atoi(cId
);
363 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(guid
))
368 ort
= go_data
->orientation
;
369 mapid
= go_data
->mapid
;
373 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
374 SetSentErrorMessage(true);
378 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
380 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
381 SetSentErrorMessage(true);
385 // stop flight if need
386 if(_player
->isInFlight())
388 _player
->GetMotionMaster()->MovementExpired();
389 _player
->m_taxi
.ClearTaxiDestinations();
391 // save only in non-flight case
393 _player
->SaveRecallPosition();
395 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
399 bool ChatHandler::HandleGameObjectTargetCommand(const char* args
)
401 Player
* pl
= m_session
->GetPlayer();
403 GameEventMgr::ActiveEvents
const& activeEventsList
= sGameEventMgr
.GetActiveEventList();
406 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
407 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject_entry");
411 uint32 id
= atol(cId
);
414 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",
415 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
418 std::string name
= cId
;
419 WorldDatabase
.escape_string(name
);
420 result
= WorldDatabase
.PQuery(
421 "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_ "
422 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
423 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
428 std::ostringstream eventFilter
;
429 eventFilter
<< " AND (event IS NULL ";
430 bool initString
= true;
432 for (GameEventMgr::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
436 eventFilter
<< "OR event IN (" <<*itr
;
440 eventFilter
<< "," << *itr
;
448 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
449 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
450 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
451 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
456 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
463 uint16 mapid
, pool_id
;
467 Field
*fields
= result
->Fetch();
468 lowguid
= fields
[0].GetUInt32();
469 id
= fields
[1].GetUInt32();
470 x
= fields
[2].GetFloat();
471 y
= fields
[3].GetFloat();
472 z
= fields
[4].GetFloat();
473 o
= fields
[5].GetFloat();
474 mapid
= fields
[6].GetUInt16();
475 pool_id
= sPoolMgr
.IsPartOfAPool
<GameObject
>(lowguid
);
476 if (!pool_id
|| sPoolMgr
.IsSpawnedObject
<GameObject
>(lowguid
))
478 } while( result
->NextRow() && (!found
) );
484 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
488 GameObjectInfo
const* goI
= ObjectMgr::GetGameObjectInfo(id
);
492 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
496 GameObject
* target
= m_session
->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
498 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
502 time_t curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
503 if(curRespawnDelay
< 0)
506 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
507 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
509 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
514 //delete object by selection or guid
515 bool ChatHandler::HandleGameObjectDeleteCommand(const char* args
)
517 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
518 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
522 uint32 lowguid
= atoi(cId
);
526 GameObject
* obj
= NULL
;
529 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
530 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
534 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
535 SetSentErrorMessage(true);
539 uint64 owner_guid
= obj
->GetOwnerGUID();
542 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
543 if(!owner
|| !IS_PLAYER_GUID(owner_guid
))
545 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
546 SetSentErrorMessage(true);
550 owner
->RemoveGameObject(obj
,false);
553 obj
->SetRespawnTime(0); // not save respawn time
557 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
562 //turn selected object
563 bool ChatHandler::HandleGameObjectTurnCommand(const char* args
)
565 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
566 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
570 uint32 lowguid
= atoi(cId
);
574 GameObject
* obj
= NULL
;
577 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
578 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
582 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
583 SetSentErrorMessage(true);
587 char* po
= strtok(NULL
, " ");
596 Player
*chr
= m_session
->GetPlayer();
597 o
= chr
->GetOrientation();
600 Map
* map
= obj
->GetMap();
601 map
->Remove(obj
,false);
603 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
604 obj
->UpdateRotationFields();
611 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), obj
->GetGOInfo()->name
, obj
->GetGUIDLow(), o
);
616 //move selected object
617 bool ChatHandler::HandleGameObjectMoveCommand(const char* args
)
619 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
620 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
624 uint32 lowguid
= atoi(cId
);
628 GameObject
* obj
= NULL
;
631 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
632 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
636 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
637 SetSentErrorMessage(true);
641 char* px
= strtok(NULL
, " ");
642 char* py
= strtok(NULL
, " ");
643 char* pz
= strtok(NULL
, " ");
647 Player
*chr
= m_session
->GetPlayer();
649 Map
* map
= obj
->GetMap();
650 map
->Remove(obj
,false);
652 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
661 float x
= (float)atof(px
);
662 float y
= (float)atof(py
);
663 float z
= (float)atof(pz
);
665 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
667 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
668 SetSentErrorMessage(true);
672 Map
* map
= obj
->GetMap();
673 map
->Remove(obj
,false);
675 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
683 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow(), obj
->GetGOInfo()->name
, obj
->GetGUIDLow());
689 bool ChatHandler::HandleGameObjectAddCommand(const char* args
)
694 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
695 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject_entry");
699 uint32 id
= atol(cId
);
703 char* spawntimeSecs
= strtok(NULL
, " ");
705 const GameObjectInfo
*gInfo
= ObjectMgr::GetGameObjectInfo(id
);
709 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
710 SetSentErrorMessage(true);
714 if (gInfo
->displayId
&& !sGameObjectDisplayInfoStore
.LookupEntry(gInfo
->displayId
))
716 // report to DB errors log as in loading case
717 sLog
.outErrorDb("Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.",id
, gInfo
->type
, gInfo
->displayId
);
718 PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA
,id
);
719 SetSentErrorMessage(true);
723 Player
*chr
= m_session
->GetPlayer();
724 float x
= float(chr
->GetPositionX());
725 float y
= float(chr
->GetPositionY());
726 float z
= float(chr
->GetPositionZ());
727 float o
= float(chr
->GetOrientation());
728 Map
*map
= chr
->GetMap();
730 GameObject
* pGameObj
= new GameObject
;
731 uint32 db_lowGUID
= sObjectMgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
733 if(!pGameObj
->Create(db_lowGUID
, gInfo
->id
, map
, chr
->GetPhaseMaskForSpawn(), x
, y
, z
, o
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, 0, GO_STATE_READY
))
741 uint32 value
= atoi((char*)spawntimeSecs
);
742 pGameObj
->SetRespawnTime(value
);
743 //sLog.outDebug("*** spawntimeSecs: %d", value);
746 // fill the gameobject data and save to the db
747 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()),chr
->GetPhaseMaskForSpawn());
749 // this will generate a new guid if the object is in an instance
750 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
756 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), gInfo
->name
, db_lowGUID
, x
, y
, z
, o
);
760 // TODO: is it really necessary to add both the real and DB table guid here ?
761 sObjectMgr
.AddGameobjectToGrid(db_lowGUID
, sObjectMgr
.GetGOData(db_lowGUID
));
763 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,gInfo
->name
,db_lowGUID
,x
,y
,z
);
767 //set pahsemask for selected object
768 bool ChatHandler::HandleGameObjectPhaseCommand(const char* args
)
770 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
771 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
775 uint32 lowguid
= atoi(cId
);
779 GameObject
* obj
= NULL
;
782 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
783 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
787 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
788 SetSentErrorMessage(true);
792 char* phaseStr
= strtok (NULL
, " ");
793 uint32 phasemask
= phaseStr
? atoi(phaseStr
) : 0;
794 if ( phasemask
== 0 )
796 SendSysMessage(LANG_BAD_VALUE
);
797 SetSentErrorMessage(true);
801 obj
->SetPhaseMask(phasemask
,true);
806 bool ChatHandler::HandleGameObjectNearCommand(const char* args
)
808 float distance
= (!*args
) ? 10.0f
: (float)atof(args
);
811 Player
* pl
= m_session
->GetPlayer();
812 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
813 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
814 "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
815 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(),
816 pl
->GetMapId(),pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(),distance
*distance
);
822 Field
*fields
= result
->Fetch();
823 uint32 guid
= fields
[0].GetUInt32();
824 uint32 entry
= fields
[1].GetUInt32();
825 float x
= fields
[2].GetFloat();
826 float y
= fields
[3].GetFloat();
827 float z
= fields
[4].GetFloat();
828 int mapid
= fields
[5].GetUInt16();
830 GameObjectInfo
const * gInfo
= ObjectMgr::GetGameObjectInfo(entry
);
835 PSendSysMessage(LANG_GO_LIST_CHAT
, guid
, guid
, gInfo
->name
, x
, y
, z
, mapid
);
838 } while (result
->NextRow());
843 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE
,distance
,count
);
847 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
849 uint64 guid
= m_session
->GetPlayer()->GetSelection();
853 SendSysMessage(LANG_NO_SELECTION
);
854 SetSentErrorMessage(true);
858 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
862 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
867 // Can be NULL at console call
868 Player
*target
= getSelectedPlayer ();
870 std::string namepart
= args
;
871 std::wstring wnamepart
;
873 if (!Utf8toWStr (namepart
,wnamepart
))
876 // converting string that we try to find to lower case
877 wstrToLower (wnamepart
);
879 uint32 counter
= 0; // Counter for figure out that we found smth.
881 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
883 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
886 FactionState
const* repState
= target
? target
->GetReputationMgr().GetState(factionEntry
) : NULL
;
888 int loc
= GetSessionDbcLocale();
889 std::string name
= factionEntry
->name
[loc
];
893 if (!Utf8FitTo(name
, wnamepart
))
896 for(; loc
< MAX_LOCALE
; ++loc
)
898 if(loc
==GetSessionDbcLocale())
901 name
= factionEntry
->name
[loc
];
905 if (Utf8FitTo(name
, wnamepart
))
912 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
913 // or "id - [faction] [no reputation]" format
914 std::ostringstream ss
;
916 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
918 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
920 if (repState
) // and then target!=NULL also
922 ReputationRank rank
= target
->GetReputationMgr().GetRank(factionEntry
);
923 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
925 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputationMgr().GetReputation(factionEntry
) << ")";
927 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
928 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
929 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
930 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
931 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
932 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
933 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
934 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
935 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
936 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
937 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
938 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
941 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
943 SendSysMessage(ss
.str().c_str());
949 if (counter
== 0) // if counter == 0 then we found nth
950 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
954 bool ChatHandler::HandleModifyRepCommand(const char * args
)
956 if (!*args
) return false;
958 Player
* target
= NULL
;
959 target
= getSelectedPlayer();
963 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
964 SetSentErrorMessage(true);
968 // check online security
969 if (HasLowerSecurity(target
, 0))
972 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
976 uint32 factionId
= atoi(factionTxt
);
979 char *rankTxt
= strtok(NULL
, " ");
980 if (!factionTxt
|| !rankTxt
)
983 amount
= atoi(rankTxt
);
984 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
986 std::string rankStr
= rankTxt
;
987 std::wstring wrankStr
;
988 if(!Utf8toWStr(rankStr
,wrankStr
))
990 wstrToLower( wrankStr
);
994 for (; r
< MAX_REPUTATION_RANK
; ++r
)
996 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
1001 if(!Utf8toWStr(rank
,wrank
))
1006 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
1008 char *deltaTxt
= strtok(NULL
, " ");
1011 int32 delta
= atoi(deltaTxt
);
1012 if ((delta
< 0) || (delta
> ReputationMgr::PointsInRank
[r
] -1))
1014 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (ReputationMgr::PointsInRank
[r
]-1));
1015 SetSentErrorMessage(true);
1022 amount
+= ReputationMgr::PointsInRank
[r
];
1024 if (r
>= MAX_REPUTATION_RANK
)
1026 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
1027 SetSentErrorMessage(true);
1032 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
1036 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
1037 SetSentErrorMessage(true);
1041 if (factionEntry
->reputationListID
< 0)
1043 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[GetSessionDbcLocale()], factionId
);
1044 SetSentErrorMessage(true);
1048 target
->GetReputationMgr().SetReputation(factionEntry
,amount
);
1049 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[GetSessionDbcLocale()], factionId
,
1050 GetNameLink(target
).c_str(), target
->GetReputationMgr().GetReputation(factionEntry
));
1054 //-----------------------Npc Commands-----------------------
1055 //add spawn of creature
1056 bool ChatHandler::HandleNpcAddCommand(const char* args
)
1060 char* charID
= extractKeyFromLink((char*)args
,"Hcreature_entry");
1064 char* team
= strtok(NULL
, " ");
1066 if (team
) { teamval
= atoi(team
); }
1067 if (teamval
< 0) { teamval
= 0; }
1069 uint32 id
= atoi(charID
);
1071 Player
*chr
= m_session
->GetPlayer();
1072 float x
= chr
->GetPositionX();
1073 float y
= chr
->GetPositionY();
1074 float z
= chr
->GetPositionZ();
1075 float o
= chr
->GetOrientation();
1076 Map
*map
= chr
->GetMap();
1078 Creature
* pCreature
= new Creature
;
1079 if (!pCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, (uint32
)teamval
))
1085 pCreature
->Relocate(x
,y
,z
,o
);
1087 if(!pCreature
->IsPositionValid())
1089 sLog
.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature
->GetGUIDLow(),pCreature
->GetEntry(),pCreature
->GetPositionX(),pCreature
->GetPositionY());
1094 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
1096 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
1098 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
1099 pCreature
->LoadFromDB(db_guid
, map
);
1101 map
->Add(pCreature
);
1102 sObjectMgr
.AddCreatureToGrid(db_guid
, sObjectMgr
.GetCreatureData(db_guid
));
1106 //add item in vendorlist
1107 bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args
)
1112 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1115 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1116 SetSentErrorMessage(true);
1120 uint32 itemId
= atol(pitem
);
1122 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1123 uint32 maxcount
= 0;
1125 maxcount
= atol(fmaxcount
);
1127 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1128 uint32 incrtime
= 0;
1130 incrtime
= atol(fincrtime
);
1132 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1133 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1135 Creature
* vendor
= getSelectedCreature();
1137 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1139 if(!sObjectMgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1141 SetSentErrorMessage(true);
1145 sObjectMgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1147 ItemPrototype
const* pProto
= ObjectMgr::GetItemPrototype(itemId
);
1149 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1153 //del item from vendor list
1154 bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args
)
1159 Creature
* vendor
= getSelectedCreature();
1160 if (!vendor
|| !vendor
->isVendor())
1162 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1163 SetSentErrorMessage(true);
1167 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1170 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1171 SetSentErrorMessage(true);
1174 uint32 itemId
= atol(pitem
);
1176 if(!sObjectMgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1178 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1179 SetSentErrorMessage(true);
1183 ItemPrototype
const* pProto
= ObjectMgr::GetItemPrototype(itemId
);
1185 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1189 //add move for creature
1190 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1195 char* guid_str
= strtok((char*)args
, " ");
1196 char* wait_str
= strtok((char*)NULL
, " ");
1198 uint32 lowguid
= atoi((char*)guid_str
);
1200 Creature
* pCreature
= NULL
;
1202 /* FIXME: impossible without entry
1204 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1207 // attempt check creature existence by DB data
1210 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
1213 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1214 SetSentErrorMessage(true);
1220 // obtain real GUID for DB operations
1221 lowguid
= pCreature
->GetDBTableGUIDLow();
1224 int wait
= wait_str
? atoi(wait_str
) : 0;
1229 Player
* player
= m_session
->GetPlayer();
1231 sWaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1233 // update movement type
1234 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1237 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1238 pCreature
->GetMotionMaster()->Initialize();
1239 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1241 pCreature
->setDeathState(JUST_DIED
);
1242 pCreature
->Respawn();
1244 pCreature
->SaveToDB();
1247 SendSysMessage(LANG_WAYPOINT_ADDED
);
1252 //change level of creature or pet
1253 bool ChatHandler::HandleNpcChangeLevelCommand(const char* args
)
1258 uint8 lvl
= (uint8
) atoi((char*)args
);
1259 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL
) + 3)
1261 SendSysMessage(LANG_BAD_VALUE
);
1262 SetSentErrorMessage(true);
1266 Creature
* pCreature
= getSelectedCreature();
1269 SendSysMessage(LANG_SELECT_CREATURE
);
1270 SetSentErrorMessage(true);
1274 if(pCreature
->isPet())
1276 if(((Pet
*)pCreature
)->getPetType()==HUNTER_PET
)
1278 pCreature
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
, sObjectMgr
.GetXPForPetLevel(lvl
));
1279 pCreature
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
, 0);
1281 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1285 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1286 pCreature
->SetHealth( 100 + 30*lvl
);
1287 pCreature
->SetLevel( lvl
);
1288 pCreature
->SaveToDB();
1294 //set npcflag of creature
1295 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1300 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1302 Creature
* pCreature
= getSelectedCreature();
1306 SendSysMessage(LANG_SELECT_CREATURE
);
1307 SetSentErrorMessage(true);
1311 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1313 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1315 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1320 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
1322 Creature
* unit
= NULL
;
1326 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1327 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1331 uint32 lowguid
= atoi(cId
);
1335 if (CreatureData
const* cr_data
= sObjectMgr
.GetCreatureData(lowguid
))
1336 unit
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
1339 unit
= getSelectedCreature();
1341 if(!unit
|| unit
->isPet() || unit
->isTotem() || unit
->isVehicle())
1343 SendSysMessage(LANG_SELECT_CREATURE
);
1344 SetSentErrorMessage(true);
1348 // Delete the creature
1350 unit
->DeleteFromDB();
1351 unit
->AddObjectToRemoveList();
1353 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
1358 //move selected creature
1359 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1363 Creature
* pCreature
= getSelectedCreature();
1367 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1368 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1372 lowguid
= atoi(cId
);
1374 /* FIXME: impossibel without entry
1376 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1379 // Attempting creature load from DB data
1382 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
1385 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1386 SetSentErrorMessage(true);
1390 uint32 map_id
= data
->mapid
;
1392 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1394 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1395 SetSentErrorMessage(true);
1401 lowguid
= pCreature
->GetDBTableGUIDLow();
1406 lowguid
= pCreature
->GetDBTableGUIDLow();
1409 float x
= m_session
->GetPlayer()->GetPositionX();
1410 float y
= m_session
->GetPlayer()->GetPositionY();
1411 float z
= m_session
->GetPlayer()->GetPositionZ();
1412 float o
= m_session
->GetPlayer()->GetOrientation();
1416 if(CreatureData
const* data
= sObjectMgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1418 const_cast<CreatureData
*>(data
)->posX
= x
;
1419 const_cast<CreatureData
*>(data
)->posY
= y
;
1420 const_cast<CreatureData
*>(data
)->posZ
= z
;
1421 const_cast<CreatureData
*>(data
)->orientation
= o
;
1423 pCreature
->GetMap()->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1424 pCreature
->GetMotionMaster()->Initialize();
1425 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1427 pCreature
->setDeathState(JUST_DIED
);
1428 pCreature
->Respawn();
1432 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1433 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1437 /**HandleNpcSetMoveTypeCommand
1438 * Set the movement type for an NPC.<br/>
1440 * Valid movement types are:
1442 * <li> stay - NPC wont move </li>
1443 * <li> random - NPC will move randomly according to the spawndist </li>
1444 * <li> way - NPC will move with given waypoints set </li>
1446 * additional parameter: NODEL - so no waypoints are deleted, if you
1447 * change the movement type
1449 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1455 // GUID (optional - you can also select the creature)
1456 // stay|random|way (determines the kind of movement)
1457 // NODEL (optional - tells the system NOT to delete any waypoints)
1458 // this is very handy if you want to do waypoints, that are
1459 // later switched on/off according to special events (like escort
1461 char* guid_str
= strtok((char*)args
, " ");
1462 char* type_str
= strtok((char*)NULL
, " ");
1463 char* dontdel_str
= strtok((char*)NULL
, " ");
1465 bool doNotDelete
= false;
1471 Creature
* pCreature
= NULL
;
1475 //sLog.outError("DEBUG: All 3 params are set");
1477 // All 3 params are set
1481 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1483 //sLog.outError("DEBUG: doNotDelete = true;");
1489 // Only 2 params - but maybe NODEL is set
1492 sLog
.outError("DEBUG: Only 2 params ");
1493 if( stricmp( type_str
, "NODEL" ) == 0 )
1495 //sLog.outError("DEBUG: type_str, NODEL ");
1502 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1504 type_str
= guid_str
;
1505 pCreature
= getSelectedCreature();
1506 if(!pCreature
|| pCreature
->isPet())
1508 lowguid
= pCreature
->GetDBTableGUIDLow();
1510 else // case .setmovetype #creature_guid $move_type (with selected creature)
1512 lowguid
= atoi((char*)guid_str
);
1514 /* impossible without entry
1516 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1519 // attempt check creature existence by DB data
1522 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
1525 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1526 SetSentErrorMessage(true);
1532 lowguid
= pCreature
->GetDBTableGUIDLow();
1536 // now lowguid is low guid really existed creature
1537 // and pCreature point (maybe) to this creature or NULL
1539 MovementGeneratorType move_type
;
1541 std::string type
= type_str
;
1544 move_type
= IDLE_MOTION_TYPE
;
1545 else if(type
== "random")
1546 move_type
= RANDOM_MOTION_TYPE
;
1547 else if(type
== "way")
1548 move_type
= WAYPOINT_MOTION_TYPE
;
1552 // update movement type
1553 if(doNotDelete
== false)
1554 sWaypointMgr
.DeletePath(lowguid
);
1558 pCreature
->SetDefaultMovementType(move_type
);
1559 pCreature
->GetMotionMaster()->Initialize();
1560 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1562 pCreature
->setDeathState(JUST_DIED
);
1563 pCreature
->Respawn();
1565 pCreature
->SaveToDB();
1567 if( doNotDelete
== false )
1569 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1573 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1579 //set model of creature
1580 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1585 uint32 displayId
= (uint32
) atoi((char*)args
);
1587 Creature
*pCreature
= getSelectedCreature();
1589 if(!pCreature
|| pCreature
->isPet())
1591 SendSysMessage(LANG_SELECT_CREATURE
);
1592 SetSentErrorMessage(true);
1596 pCreature
->SetDisplayId(displayId
);
1597 pCreature
->SetNativeDisplayId(displayId
);
1599 pCreature
->SaveToDB();
1603 //set faction of creature
1604 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1609 uint32 factionId
= (uint32
) atoi((char*)args
);
1611 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1613 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1614 SetSentErrorMessage(true);
1618 Creature
* pCreature
= getSelectedCreature();
1622 SendSysMessage(LANG_SELECT_CREATURE
);
1623 SetSentErrorMessage(true);
1627 pCreature
->setFaction(factionId
);
1629 // faction is set in creature_template - not inside creature
1632 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1634 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1635 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1639 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1643 //set spawn dist of creature
1644 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
1649 float option
= (float)atof((char*)args
);
1652 SendSysMessage(LANG_BAD_VALUE
);
1656 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
1658 mtype
= RANDOM_MOTION_TYPE
;
1660 Creature
*pCreature
= getSelectedCreature();
1661 uint32 u_guidlow
= 0;
1664 u_guidlow
= pCreature
->GetDBTableGUIDLow();
1668 pCreature
->SetRespawnRadius((float)option
);
1669 pCreature
->SetDefaultMovementType(mtype
);
1670 pCreature
->GetMotionMaster()->Initialize();
1671 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1673 pCreature
->setDeathState(JUST_DIED
);
1674 pCreature
->Respawn();
1677 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
1678 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
1681 //spawn time handling
1682 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
1687 char* stime
= strtok((char*)args
, " ");
1692 int i_stime
= atoi((char*)stime
);
1696 SendSysMessage(LANG_BAD_VALUE
);
1697 SetSentErrorMessage(true);
1701 Creature
*pCreature
= getSelectedCreature();
1702 uint32 u_guidlow
= 0;
1705 u_guidlow
= pCreature
->GetDBTableGUIDLow();
1709 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
1710 pCreature
->SetRespawnDelay((uint32
)i_stime
);
1711 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
1715 //npc follow handling
1716 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
1718 Player
*player
= m_session
->GetPlayer();
1719 Creature
*creature
= getSelectedCreature();
1723 PSendSysMessage(LANG_SELECT_CREATURE
);
1724 SetSentErrorMessage(true);
1728 // Follow player - Using pet's default dist and angle
1729 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
1731 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
1734 //npc unfollow handling
1735 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
1737 Player
*player
= m_session
->GetPlayer();
1738 Creature
*creature
= getSelectedCreature();
1742 PSendSysMessage(LANG_SELECT_CREATURE
);
1743 SetSentErrorMessage(true);
1747 if (creature
->GetMotionMaster()->empty() ||
1748 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=FOLLOW_MOTION_TYPE
)
1750 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
1751 SetSentErrorMessage(true);
1755 FollowMovementGenerator
<Creature
> const* mgen
1756 = static_cast<FollowMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
1758 if(mgen
->GetTarget()!=player
)
1760 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
1761 SetSentErrorMessage(true);
1766 creature
->GetMotionMaster()->MovementExpired(true);
1768 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
1772 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
1774 Creature
*creatureTarget
= getSelectedCreature ();
1775 if (!creatureTarget
|| creatureTarget
->isPet ())
1777 PSendSysMessage (LANG_SELECT_CREATURE
);
1778 SetSentErrorMessage (true);
1782 Player
*player
= m_session
->GetPlayer ();
1784 if(player
->GetPetGUID ())
1786 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
1787 SetSentErrorMessage (true);
1791 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
1793 if (!cInfo
->isTameable (player
->CanTameExoticPets()))
1795 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
1796 SetSentErrorMessage (true);
1800 // Everything looks OK, create new pet
1801 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
1804 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
1805 SetSentErrorMessage (true);
1809 // place pet before player
1811 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
1812 pet
->Relocate (x
,y
,z
,M_PI_F
-player
->GetOrientation ());
1814 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
1815 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
1817 // calculate proper level
1818 uint32 level
= (creatureTarget
->getLevel() < (player
->getLevel() - 5)) ? (player
->getLevel() - 5) : creatureTarget
->getLevel();
1820 // prepare visual effect for levelup
1821 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
- 1);
1824 pet
->GetMap()->Add((Creature
*)pet
);
1826 // visual effect for levelup
1827 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
);
1829 // caster have pet now
1830 player
->SetPet(pet
);
1832 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
1833 player
->PetSpellInitialize();
1837 //npc phasemask handling
1838 //change phasemask of creature or pet
1839 bool ChatHandler::HandleNpcSetPhaseCommand(const char* args
)
1844 uint32 phasemask
= (uint32
) atoi((char*)args
);
1845 if ( phasemask
== 0 )
1847 SendSysMessage(LANG_BAD_VALUE
);
1848 SetSentErrorMessage(true);
1852 Creature
* pCreature
= getSelectedCreature();
1855 SendSysMessage(LANG_SELECT_CREATURE
);
1856 SetSentErrorMessage(true);
1860 pCreature
->SetPhaseMask(phasemask
,true);
1862 if(!pCreature
->isPet())
1863 pCreature
->SaveToDB();
1867 //npc deathstate handling
1868 bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args
)
1873 Creature
* pCreature
= getSelectedCreature();
1874 if(!pCreature
|| pCreature
->isPet())
1876 SendSysMessage(LANG_SELECT_CREATURE
);
1877 SetSentErrorMessage(true);
1881 if (strncmp(args
, "on", 3) == 0)
1882 pCreature
->SetDeadByDefault(true);
1883 else if (strncmp(args
, "off", 4) == 0)
1884 pCreature
->SetDeadByDefault(false);
1887 SendSysMessage(LANG_USE_BOL
);
1888 SetSentErrorMessage(true);
1892 pCreature
->SaveToDB();
1893 pCreature
->Respawn();
1898 //TODO: NpcCommands that need to be fixed :
1900 bool ChatHandler::HandleNpcNameCommand(const char* /*args*/)
1906 if(strlen((char*)args)>75)
1908 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
1912 for (uint8 i = 0; i < strlen(args); ++i)
1914 if(!isalpha(args[i]) && args[i]!=' ')
1916 SendSysMessage(LANG_CHARS_ONLY);
1922 guid = m_session->GetPlayer()->GetSelection();
1925 SendSysMessage(LANG_NO_SELECTION);
1929 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1933 SendSysMessage(LANG_SELECT_CREATURE);
1937 pCreature->SetName(args);
1938 uint32 idname = sObjectMgr.AddCreatureTemplate(pCreature->GetName());
1939 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1941 pCreature->SaveToDB();
1947 bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
1954 if(strlen((char*)args)>75)
1957 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
1961 for (uint8 i = 0; i < strlen(args); i++)
1963 if(!isalpha(args[i]) && args[i]!=' ')
1965 SendSysMessage(LANG_CHARS_ONLY);
1970 guid = m_session->GetPlayer()->GetSelection();
1973 SendSysMessage(LANG_NO_SELECTION);
1977 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1981 SendSysMessage(LANG_SELECT_CREATURE);
1985 uint32 idname = sObjectMgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
1986 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1988 pCreature->SaveToDB();
1993 //move item to other slot
1994 bool ChatHandler::HandleItemMoveCommand(const char* args
)
1998 uint8 srcslot
, dstslot
;
2000 char* pParam1
= strtok((char*)args
, " ");
2004 char* pParam2
= strtok(NULL
, " ");
2008 srcslot
= (uint8
)atoi(pParam1
);
2009 dstslot
= (uint8
)atoi(pParam2
);
2011 if(srcslot
==dstslot
)
2014 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
, srcslot
, true))
2017 // can be autostore pos
2018 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
, false))
2021 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
2022 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
2024 m_session
->GetPlayer()->SwapItem( src
, dst
);
2029 //demorph player or unit
2030 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
2032 Unit
*target
= getSelectedUnit();
2034 target
= m_session
->GetPlayer();
2037 // check online security
2038 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2046 //morph creature or player
2047 bool ChatHandler::HandleModifyMorphCommand(const char* args
)
2052 uint16 display_id
= (uint16
)atoi((char*)args
);
2054 Unit
*target
= getSelectedUnit();
2056 target
= m_session
->GetPlayer();
2058 // check online security
2059 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2062 target
->SetDisplayId(display_id
);
2068 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
2071 if(!extractPlayerTarget((char*)args
,&target
))
2074 if (m_session
&& target
==m_session
->GetPlayer())
2076 SendSysMessage(LANG_COMMAND_KICKSELF
);
2077 SetSentErrorMessage(true);
2081 // check online security
2082 if (HasLowerSecurity(target
, 0))
2085 // send before target pointer invalidate
2086 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,GetNameLink(target
).c_str());
2087 target
->GetSession()->KickPlayer();
2091 //set temporary phase mask for player
2092 bool ChatHandler::HandleModifyPhaseCommand(const char* args
)
2097 uint32 phasemask
= (uint32
)atoi((char*)args
);
2099 Unit
*target
= getSelectedUnit();
2101 target
= m_session
->GetPlayer();
2103 // check online security
2104 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2107 target
->SetPhaseMask(phasemask
,true);
2112 //show info of player
2113 bool ChatHandler::HandlePInfoCommand(const char* args
)
2117 std::string target_name
;
2118 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
2123 uint32 total_player_time
= 0;
2127 // get additional information from Player object
2130 // check online security
2131 if (HasLowerSecurity(target
, 0))
2134 accId
= target
->GetSession()->GetAccountId();
2135 money
= target
->GetMoney();
2136 total_player_time
= target
->GetTotalPlayedTime();
2137 level
= target
->getLevel();
2138 latency
= target
->GetSession()->GetLatency();
2140 // get additional information from DB
2143 // check offline security
2144 if (HasLowerSecurity(NULL
, target_guid
))
2148 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime, level, money, account FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid
));
2152 Field
*fields
= result
->Fetch();
2153 total_player_time
= fields
[0].GetUInt32();
2154 level
= fields
[1].GetUInt32();
2155 money
= fields
[2].GetUInt32();
2156 accId
= fields
[3].GetUInt32();
2160 std::string username
= GetMangosString(LANG_ERROR
);
2161 std::string last_ip
= GetMangosString(LANG_ERROR
);
2162 AccountTypes security
= SEC_PLAYER
;
2163 std::string last_login
= GetMangosString(LANG_ERROR
);
2165 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
2168 Field
* fields
= result
->Fetch();
2169 username
= fields
[0].GetCppString();
2170 security
= (AccountTypes
)fields
[1].GetUInt32();
2172 if(GetAccessLevel() >= security
)
2174 last_ip
= fields
[2].GetCppString();
2175 last_login
= fields
[3].GetCppString();
2186 std::string nameLink
= playerLink(target_name
);
2188 PSendSysMessage(LANG_PINFO_ACCOUNT
, (target
?"":GetMangosString(LANG_OFFLINE
)), nameLink
.c_str(), GUID_LOPART(target_guid
), username
.c_str(), accId
, security
, last_ip
.c_str(), last_login
.c_str(), latency
);
2190 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
2191 uint32 gold
= money
/GOLD
;
2192 uint32 silv
= (money
% GOLD
) / SILVER
;
2193 uint32 copp
= (money
% GOLD
) % SILVER
;
2194 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
2200 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
2203 if(!sObjectMgr
.GetPlayerNameByGUID(guid
,name
))
2204 name
= GetMangosString(LANG_UNKNOWN
);
2206 std::string nameLink
= playerLink(name
);
2208 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, nameLink
.c_str(),time
,text
);
2212 bool ChatHandler::HandleTicketCommand(const char* args
)
2214 char* px
= strtok((char*)args
, " ");
2221 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2222 SetSentErrorMessage(true);
2226 size_t count
= sTicketMgr
.GetTicketCount();
2228 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
2230 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
2235 if(strncmp(px
,"on",3) == 0)
2239 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2240 SetSentErrorMessage(true);
2244 m_session
->GetPlayer()->SetAcceptTicket(true);
2245 SendSysMessage(LANG_COMMAND_TICKETON
);
2250 if(strncmp(px
,"off",4) == 0)
2254 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2255 SetSentErrorMessage(true);
2259 m_session
->GetPlayer()->SetAcceptTicket(false);
2260 SendSysMessage(LANG_COMMAND_TICKETOFF
);
2265 if(strncmp(px
,"respond",8) == 0)
2267 char *name
= strtok(NULL
, " ");
2271 SendSysMessage(LANG_CMD_SYNTAX
);
2272 SetSentErrorMessage(true);
2276 std::string plName
= name
;
2277 uint64 guid
= sObjectMgr
.GetPlayerGUIDByName(plName
);
2281 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2282 SetSentErrorMessage(true);
2286 GMTicket
* ticket
= sTicketMgr
.GetGMTicket(GUID_LOPART(guid
));
2290 PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST
, GUID_LOPART(guid
));
2291 SetSentErrorMessage(true);
2295 char* response
= strtok(NULL
, "");
2299 SendSysMessage(LANG_CMD_SYNTAX
);
2300 SetSentErrorMessage(true);
2304 ticket
->SetResponseText(response
);
2306 if(Player
* pl
= sObjectMgr
.GetPlayer(guid
))
2307 pl
->GetSession()->SendGMResponse(ticket
);
2316 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
2320 PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST
, num
);
2321 SetSentErrorMessage(true);
2325 Field
* fields
= result
->Fetch();
2327 uint32 guid
= fields
[0].GetUInt32();
2328 char const* text
= fields
[1].GetString();
2329 char const* time
= fields
[2].GetString();
2331 ShowTicket(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
),text
,time
);
2337 if(!extractPlayerTarget(px
,NULL
,&target_guid
))
2340 // ticket $char_name
2341 GMTicket
* ticket
= sTicketMgr
.GetGMTicket(GUID_LOPART(target_guid
));
2345 std::string time
= TimeToTimestampStr(ticket
->GetLastUpdate());
2347 ShowTicket(target_guid
, ticket
->GetText(), time
.c_str());
2353 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2355 char* px
= strtok((char*)args
, " ");
2360 if(strncmp(px
,"all",4) == 0)
2362 sTicketMgr
.DeleteAll();
2363 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2367 int num
= (uint32
)atoi(px
);
2372 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2375 PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST
, num
);
2376 SetSentErrorMessage(true);
2379 Field
* fields
= result
->Fetch();
2380 uint32 guid
= fields
[0].GetUInt32();
2383 sTicketMgr
.Delete(guid
);
2386 if(Player
* pl
= sObjectMgr
.GetPlayer(ObjectGuid(HIGHGUID_PLAYER
, guid
)))
2388 pl
->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2389 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
, GetNameLink(pl
).c_str());
2392 PSendSysMessage(LANG_COMMAND_TICKETDEL
);
2399 std::string target_name
;
2400 if(!extractPlayerTarget(px
,&target
,&target_guid
,&target_name
))
2403 // delticket $char_name
2404 sTicketMgr
.Delete(GUID_LOPART(target_guid
));
2406 // notify players about ticket deleting
2408 target
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2410 std::string nameLink
= playerLink(target_name
);
2412 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,nameLink
.c_str());
2417 * Add a waypoint to a creature.
2419 * The user can either select an npc or provide its GUID.
2421 * The user can even select a visual waypoint - then the new waypoint
2422 * is placed *after* the selected one - this makes insertion of new
2423 * waypoints possible.
2427 * -> adds a waypoint to the npc with the GUID 12345
2430 * -> adds a waypoint to the currently selected creature
2433 * @param args if the user did not provide a GUID, it is NULL
2435 * @return true - command did succeed, false - something went wrong
2437 bool ChatHandler::HandleWpAddCommand(const char* args
)
2439 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2442 char* guid_str
= NULL
;
2446 guid_str
= strtok((char*)args
, " ");
2451 Creature
* target
= getSelectedCreature();
2452 // Did player provide a GUID?
2455 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2458 // -> Player must have selected a creature
2460 if(!target
|| target
->isPet())
2462 SendSysMessage(LANG_SELECT_CREATURE
);
2463 SetSentErrorMessage(true);
2466 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2468 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2470 QueryResult
*result
=
2471 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2472 target
->GetGUIDLow() );
2475 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2476 // User selected a visual spawnpoint -> get the NPC
2478 // Since we compare float values, we have to deal with
2479 // some difficulties.
2480 // Here we search for all waypoints that only differ in one from 1 thousand
2481 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2482 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2483 const char* maxDIFF
= "0.01";
2484 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 )",
2485 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2488 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2489 SetSentErrorMessage(true);
2495 Field
*fields
= result
->Fetch();
2496 lowguid
= fields
[0].GetUInt32();
2497 point
= fields
[1].GetUInt32();
2498 }while( result
->NextRow() );
2501 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2504 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2505 SetSentErrorMessage(true);
2509 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2512 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2513 SetSentErrorMessage(true);
2519 lowguid
= target
->GetDBTableGUIDLow();
2524 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2527 // Warn if player also selected a creature
2528 // -> Creature selection is ignored <-
2531 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2533 lowguid
= atoi((char*)guid_str
);
2535 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2538 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2539 SetSentErrorMessage(true);
2543 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2544 if(!target
|| target
->isPet())
2546 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2547 SetSentErrorMessage(true);
2551 // lowguid -> GUID of the NPC
2552 // point -> number of the waypoint (if not 0)
2553 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2555 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2557 Player
* player
= m_session
->GetPlayer();
2558 sWaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2560 // update movement type
2563 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2564 target
->GetMotionMaster()->Initialize();
2565 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2567 target
->setDeathState(JUST_DIED
);
2573 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2575 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2578 } // HandleWpAddCommand
2581 * .wp modify emote | spell | text | del | move | add
2583 * add -> add a WP after the selected visual waypoint
2584 * User must select a visual waypoint and then issue ".wp modify add"
2587 * User has selected a visual waypoint before.
2588 * <emoteID> is added to this waypoint. Everytime the
2589 * NPC comes to this waypoint, the emote is called.
2591 * emote <GUID> <WPNUM> <emoteID>
2592 * User has not selected visual waypoint before.
2593 * For the waypoint <WPNUM> for the NPC with <GUID>
2594 * an emote <emoteID> is added.
2595 * Everytime the NPC comes to this waypoint, the emote is called.
2598 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2600 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2602 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2607 // first arg: add del text emote spell waittime move
2608 char* show_str
= strtok((char*)args
, " ");
2614 std::string show
= show_str
;
2616 // Remember: "show" must also be the name of a column!
2617 if( (show
!= "emote") && (show
!= "spell") && (show
!= "textid1") && (show
!= "textid2")
2618 && (show
!= "textid3") && (show
!= "textid4") && (show
!= "textid5")
2619 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2620 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2625 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2627 // Did user provide a GUID
2628 // or did the user select a creature?
2629 // -> variable lowguid is filled with the GUID of the NPC
2633 Creature
* target
= getSelectedCreature();
2637 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2639 // Did the user select a visual spawnpoint?
2640 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2642 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2643 SetSentErrorMessage(true);
2647 wpGuid
= target
->GetGUIDLow();
2649 // The visual waypoint
2650 QueryResult
*result
=
2651 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2652 target
->GetGUIDLow() );
2655 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2656 SetSentErrorMessage(true);
2659 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2661 Field
*fields
= result
->Fetch();
2662 lowguid
= fields
[0].GetUInt32();
2663 point
= fields
[1].GetUInt32();
2666 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2671 // User did provide <GUID> <WPNUM>
2673 char* guid_str
= strtok((char*)NULL
, " ");
2676 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2679 lowguid
= atoi((char*)guid_str
);
2681 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2684 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2685 SetSentErrorMessage(true);
2689 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2691 char* point_str
= strtok((char*)NULL
, " ");
2694 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2697 point
= atoi((char*)point_str
);
2699 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2701 // Now we need the GUID of the visual waypoint
2702 // -> "del", "move", "add" command
2704 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2707 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2708 SetSentErrorMessage(true);
2712 Field
*fields
= result
->Fetch();
2713 wpGuid
= fields
[0].GetUInt32();
2719 char* arg_str
= NULL
;
2720 // Check for argument
2721 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2723 // Text is enclosed in "<>", all other arguments not
2724 if( show
.find("text") != std::string::npos
)
2725 arg_str
= strtok((char*)NULL
, "<>");
2727 arg_str
= strtok((char*)NULL
, " ");
2731 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2736 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2738 // wpGuid -> GUID of the waypoint creature
2739 // lowguid -> GUID of the NPC
2740 // point -> waypoint number
2742 // Special functions:
2743 // add - move - del -> no args commands
2744 // Add a waypoint after the selected visual
2745 if(show
== "add" && target
)
2747 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2749 // Get the creature for which we read the waypoint
2750 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2753 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2754 SetSentErrorMessage(true);
2758 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2762 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2763 SetSentErrorMessage(true);
2767 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2770 // Add the visual spawnpoint (DB only)
2771 // Adjust the waypoints
2772 // Respawn the owner of the waypoints
2773 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2775 Player
* chr
= m_session
->GetPlayer();
2776 Map
*map
= chr
->GetMap();
2780 npcCreature
->GetMotionMaster()->Initialize();
2781 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2783 npcCreature
->setDeathState(JUST_DIED
);
2784 npcCreature
->Respawn();
2788 // create the waypoint creature
2790 Creature
* wpCreature
= new Creature
;
2791 if (!wpCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
,0))
2793 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2798 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2800 if(!wpCreature
->IsPositionValid())
2802 sLog
.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature
->GetGUIDLow(),wpCreature
->GetEntry(),wpCreature
->GetPositionX(),wpCreature
->GetPositionY());
2807 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2808 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2809 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2810 map
->Add(wpCreature
);
2811 wpGuid
= wpCreature
->GetGUIDLow();
2815 sWaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2820 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2824 if(show
== "del" && target
)
2826 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2828 // Get the creature for which we read the waypoint
2829 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2832 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2833 SetSentErrorMessage(true);
2837 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2840 Creature
* wpCreature
= NULL
;
2843 wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2844 wpCreature
->DeleteFromDB();
2845 wpCreature
->AddObjectToRemoveList();
2849 // Remove the visual spawnpoint
2850 // Adjust the waypoints
2851 // Respawn the owner of the waypoints
2853 sWaypointMgr
.DeleteNode(lowguid
, point
);
2857 // Any waypoints left?
2858 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2861 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2865 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2868 npcCreature
->GetMotionMaster()->Initialize();
2869 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2871 npcCreature
->setDeathState(JUST_DIED
);
2872 npcCreature
->Respawn();
2874 npcCreature
->SaveToDB();
2877 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2881 if(show
== "move" && target
)
2883 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2885 Player
*chr
= m_session
->GetPlayer();
2886 Map
*map
= chr
->GetMap();
2888 // Get the creature for which we read the waypoint
2889 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2892 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2893 SetSentErrorMessage(true);
2897 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2900 Creature
* wpCreature
= NULL
;
2902 // Move the visual spawnpoint
2903 // Respawn the owner of the waypoints
2906 wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2907 wpCreature
->DeleteFromDB();
2908 wpCreature
->AddObjectToRemoveList();
2910 Creature
* wpCreature2
= new Creature
;
2911 if (!wpCreature2
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
, 0))
2913 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2918 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2920 if(!wpCreature2
->IsPositionValid())
2922 sLog
.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2
->GetGUIDLow(),wpCreature2
->GetEntry(),wpCreature2
->GetPositionX(),wpCreature2
->GetPositionY());
2927 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2928 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2929 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2930 map
->Add(wpCreature2
);
2931 //npcCreature->GetMap()->Add(wpCreature2);
2934 sWaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2938 npcCreature
->GetMotionMaster()->Initialize();
2939 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2941 npcCreature
->setDeathState(JUST_DIED
);
2942 npcCreature
->Respawn();
2945 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2950 // Create creature - npc that has the waypoint
2951 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2954 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2955 SetSentErrorMessage(true);
2959 // set in game textids not supported
2960 if( show
== "textid1" || show
== "textid2" || show
== "textid3" ||
2961 show
== "textid4" || show
== "textid5" )
2966 sWaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2968 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2971 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2972 npcCreature
->GetMotionMaster()->Initialize();
2973 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2975 npcCreature
->setDeathState(JUST_DIED
);
2976 npcCreature
->Respawn();
2979 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2985 * .wp show info | on | off
2987 * info -> User has selected a visual waypoint before
2989 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2990 * provided the GUID of the NPC and the number of
2993 * on -> User has selected an NPC; all visual waypoints for this
2994 * NPC are added to the world
2996 * on <GUID> -> User did not select an NPC - instead the GUID of the
2997 * NPC is provided. All visual waypoints for this NPC
2998 * are added from the world.
3000 * off -> User has selected an NPC; all visual waypoints for this
3001 * NPC are removed from the world.
3003 * on <GUID> -> User did not select an NPC - instead the GUID of the
3004 * NPC is provided. All visual waypoints for this NPC
3005 * are removed from the world.
3009 bool ChatHandler::HandleWpShowCommand(const char* args
)
3011 sLog
.outDebug("DEBUG: HandleWpShowCommand");
3016 // first arg: on, off, first, last
3017 char* show_str
= strtok((char*)args
, " ");
3022 // second arg: GUID (optional, if a creature is selected)
3023 char* guid_str
= strtok((char*)NULL
, " ");
3024 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
3029 // Did user provide a GUID
3030 // or did the user select a creature?
3031 // -> variable lowguid is filled with the GUID
3032 Creature
* target
= getSelectedCreature();
3033 // Did player provide a GUID?
3036 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
3038 // -> Player must have selected a creature
3042 SendSysMessage(LANG_SELECT_CREATURE
);
3043 SetSentErrorMessage(true);
3049 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
3051 // Warn if player also selected a creature
3052 // -> Creature selection is ignored <-
3055 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
3058 uint32 lowguid
= atoi((char*)guid_str
);
3060 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
3063 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
3064 SetSentErrorMessage(true);
3068 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
3072 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
3073 SetSentErrorMessage(true);
3078 uint32 lowguid
= target
->GetDBTableGUIDLow();
3080 std::string show
= show_str
;
3083 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
3085 // Show info for the selected waypoint
3088 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
3090 // Check if the user did specify a visual waypoint
3091 if( target
->GetEntry() != VISUAL_WAYPOINT
)
3093 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
3094 SetSentErrorMessage(true);
3098 //PSendSysMessage("wp on, GUID: %u", lowguid);
3100 //pCreature->GetPositionX();
3102 QueryResult
*result
=
3103 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
3104 target
->GetGUIDLow() );
3107 // Since we compare float values, we have to deal with
3108 // some difficulties.
3109 // Here we search for all waypoints that only differ in one from 1 thousand
3110 // (0.001) - There is no other way to compare C++ floats with mySQL floats
3111 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
3112 const char* maxDIFF
= "0.01";
3113 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
3115 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 )",
3116 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
3119 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
3120 SetSentErrorMessage(true);
3126 Field
*fields
= result
->Fetch();
3127 uint32 creGUID
= fields
[0].GetUInt32();
3128 uint32 point
= fields
[1].GetUInt32();
3129 int waittime
= fields
[2].GetUInt32();
3130 uint32 emote
= fields
[3].GetUInt32();
3131 uint32 spell
= fields
[4].GetUInt32();
3132 uint32 textid
[MAX_WAYPOINT_TEXT
];
3133 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
3134 textid
[i
] = fields
[5+i
].GetUInt32();
3135 uint32 model1
= fields
[10].GetUInt32();
3136 uint32 model2
= fields
[11].GetUInt32();
3138 // Get the creature for which we read the waypoint
3139 Creature
* wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3141 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
3142 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
3143 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
3144 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
3145 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
3146 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
3147 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
3148 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, i
+1, textid
[i
], (textid
[i
] ? GetMangosString(textid
[i
]) : ""));
3150 }while( result
->NextRow() );
3158 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
3160 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
3163 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3164 SetSentErrorMessage(true);
3167 // Delete all visuals for this NPC
3168 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
3171 bool hasError
= false;
3174 Field
*fields
= result2
->Fetch();
3175 uint32 wpguid
= fields
[0].GetUInt32();
3176 Creature
* pCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3180 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
3182 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
3186 pCreature
->DeleteFromDB();
3187 pCreature
->AddObjectToRemoveList();
3190 }while( result2
->NextRow() );
3194 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3195 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3196 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3202 Field
*fields
= result
->Fetch();
3203 uint32 point
= fields
[0].GetUInt32();
3204 float x
= fields
[1].GetFloat();
3205 float y
= fields
[2].GetFloat();
3206 float z
= fields
[3].GetFloat();
3208 uint32 id
= VISUAL_WAYPOINT
;
3210 Player
*chr
= m_session
->GetPlayer();
3211 Map
*map
= chr
->GetMap();
3212 float o
= chr
->GetOrientation();
3214 Creature
* wpCreature
= new Creature
;
3215 if (!wpCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3217 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3223 wpCreature
->Relocate(x
, y
, z
, o
);
3225 if(!wpCreature
->IsPositionValid())
3227 sLog
.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature
->GetGUIDLow(),wpCreature
->GetEntry(),wpCreature
->GetPositionX(),wpCreature
->GetPositionY());
3233 wpCreature
->SetVisibility(VISIBILITY_OFF
);
3234 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u", wpCreature
->GetGUIDLow());
3235 // set "wpguid" column to the visual waypoint
3236 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3238 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3239 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3240 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3241 map
->Add(wpCreature
);
3242 //wpCreature->GetMap()->Add(wpCreature);
3243 }while( result
->NextRow() );
3252 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3254 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3257 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3258 SetSentErrorMessage(true);
3262 Field
*fields
= result
->Fetch();
3263 float x
= fields
[0].GetFloat();
3264 float y
= fields
[1].GetFloat();
3265 float z
= fields
[2].GetFloat();
3266 uint32 id
= VISUAL_WAYPOINT
;
3268 Player
*chr
= m_session
->GetPlayer();
3269 float o
= chr
->GetOrientation();
3270 Map
*map
= chr
->GetMap();
3272 Creature
* pCreature
= new Creature
;
3273 if (!pCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3275 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3281 pCreature
->Relocate(x
, y
, z
, o
);
3283 if(!pCreature
->IsPositionValid())
3285 sLog
.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature
->GetGUIDLow(),pCreature
->GetEntry(),pCreature
->GetPositionX(),pCreature
->GetPositionY());
3291 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3292 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3293 map
->Add(pCreature
);
3294 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3303 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3305 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3308 Maxpoint
= (*result
)[0].GetUInt32();
3315 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3318 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3319 SetSentErrorMessage(true);
3322 Field
*fields
= result
->Fetch();
3323 float x
= fields
[0].GetFloat();
3324 float y
= fields
[1].GetFloat();
3325 float z
= fields
[2].GetFloat();
3326 uint32 id
= VISUAL_WAYPOINT
;
3328 Player
*chr
= m_session
->GetPlayer();
3329 float o
= chr
->GetOrientation();
3330 Map
*map
= chr
->GetMap();
3332 Creature
* pCreature
= new Creature
;
3333 if (!pCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3335 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3341 pCreature
->Relocate(x
, y
, z
, o
);
3343 if(!pCreature
->IsPositionValid())
3345 sLog
.outError("Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature
->GetGUIDLow(),pCreature
->GetEntry(),pCreature
->GetPositionX(),pCreature
->GetPositionY());
3351 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3352 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3353 map
->Add(pCreature
);
3354 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3362 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3365 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3366 SetSentErrorMessage(true);
3369 bool hasError
= false;
3372 Field
*fields
= result
->Fetch();
3373 uint32 guid
= fields
[0].GetUInt32();
3374 Creature
* pCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3377 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3379 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3383 pCreature
->DeleteFromDB();
3384 pCreature
->AddObjectToRemoveList();
3386 }while(result
->NextRow());
3387 // set "wpguid" column to "empty" - no visual waypoint spawned
3388 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3392 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3393 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3394 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3397 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3404 PSendSysMessage("DEBUG: wpshow - no valid command found");
3407 } // HandleWpShowCommand
3409 bool ChatHandler::HandleWpExportCommand(const char *args
)
3414 // Next arg is: <GUID> <ARGUMENT>
3416 // Did user provide a GUID
3417 // or did the user select a creature?
3418 // -> variable lowguid is filled with the GUID of the NPC
3420 Creature
* target
= getSelectedCreature();
3421 char* arg_str
= NULL
;
3424 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3425 lowguid
= target
->GetGUIDLow();
3428 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3431 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3434 Field
*fields
= result
->Fetch();
3435 lowguid
= fields
[0].GetUInt32();;
3439 arg_str
= strtok((char*)args
, " ");
3443 // user provided <GUID>
3444 char* guid_str
= strtok((char*)args
, " ");
3447 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3450 lowguid
= atoi((char*)guid_str
);
3452 arg_str
= strtok((char*)NULL
, " ");
3457 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3461 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3463 QueryResult
*result
= WorldDatabase
.PQuery(
3464 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3465 "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
);
3469 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3470 SetSentErrorMessage(true);
3474 std::ofstream outfile
;
3475 outfile
.open (arg_str
);
3479 Field
*fields
= result
->Fetch();
3481 outfile
<< "INSERT INTO creature_movement ";
3482 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3485 outfile
<< fields
[15].GetUInt32(); // id
3487 outfile
<< fields
[0].GetUInt32(); // point
3489 outfile
<< fields
[1].GetFloat(); // position_x
3491 outfile
<< fields
[2].GetFloat(); // position_y
3493 outfile
<< fields
[3].GetUInt32(); // position_z
3495 outfile
<< fields
[4].GetUInt32(); // orientation
3497 outfile
<< fields
[5].GetUInt32(); // model1
3499 outfile
<< fields
[6].GetUInt32(); // model2
3501 outfile
<< fields
[7].GetUInt16(); // waittime
3503 outfile
<< fields
[8].GetUInt32(); // emote
3505 outfile
<< fields
[9].GetUInt32(); // spell
3507 outfile
<< fields
[10].GetUInt32(); // textid1
3509 outfile
<< fields
[11].GetUInt32(); // textid2
3511 outfile
<< fields
[12].GetUInt32(); // textid3
3513 outfile
<< fields
[13].GetUInt32(); // textid4
3515 outfile
<< fields
[14].GetUInt32(); // textid5
3518 } while( result
->NextRow() );
3521 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3527 bool ChatHandler::HandleWpImportCommand(const char *args
)
3532 char* arg_str
= strtok((char*)args
, " ");
3537 std::ifstream
infile (arg_str
);
3538 if (infile
.is_open())
3540 while (! infile
.eof() )
3542 getline (infile
,line
);
3543 //cout << line << endl;
3544 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3549 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3555 bool ChatHandler::HandleCharacterRenameCommand(const char* args
)
3559 std::string target_name
;
3560 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
3565 // check online security
3566 if (HasLowerSecurity(target
, 0))
3569 PSendSysMessage(LANG_RENAME_PLAYER
, GetNameLink(target
).c_str());
3570 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3571 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3575 // check offline security
3576 if (HasLowerSecurity(NULL
, target_guid
))
3579 std::string oldNameLink
= playerLink(target_name
);
3581 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(target_guid
));
3582 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid
));
3588 // customize characters
3589 bool ChatHandler::HandleCharacterCustomizeCommand(const char* args
)
3593 std::string target_name
;
3594 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
3599 PSendSysMessage(LANG_CUSTOMIZE_PLAYER
, GetNameLink(target
).c_str());
3600 target
->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE
);
3601 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target
->GetGUIDLow());
3605 std::string oldNameLink
= playerLink(target_name
);
3607 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(target_guid
));
3608 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid
));
3614 bool ChatHandler::HandleCharacterReputationCommand(const char* args
)
3617 if(!extractPlayerTarget((char*)args
,&target
))
3620 LocaleConstant loc
= GetSessionDbcLocale();
3622 FactionStateList
const& targetFSL
= target
->GetReputationMgr().GetStateList();
3623 for(FactionStateList::const_iterator itr
= targetFSL
.begin(); itr
!= targetFSL
.end(); ++itr
)
3625 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
3626 char const* factionName
= factionEntry
? factionEntry
->name
[loc
] : "#Not found#";
3627 ReputationRank rank
= target
->GetReputationMgr().GetRank(factionEntry
);
3628 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
3629 std::ostringstream ss
;
3631 ss
<< itr
->second
.ID
<< " - |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << factionName
<< " " << localeNames
[loc
] << "]|h|r";
3633 ss
<< itr
->second
.ID
<< " - " << factionName
<< " " << localeNames
[loc
];
3635 ss
<< " " << rankName
<< " (" << target
->GetReputationMgr().GetReputation(factionEntry
) << ")";
3637 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
3638 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
3639 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
3640 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
3641 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
3642 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
3643 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
3644 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
3645 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
3646 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
3647 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
3648 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
3650 SendSysMessage(ss
.str().c_str());
3656 bool ChatHandler::HandleModifyStandStateCommand(const char* args
)
3661 uint32 anim_id
= atoi((char*)args
);
3662 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3667 bool ChatHandler::HandleHonorAddCommand(const char* args
)
3672 Player
*target
= getSelectedPlayer();
3675 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3676 SetSentErrorMessage(true);
3680 // check online security
3681 if (HasLowerSecurity(target
, 0))
3684 float amount
= (float)atof(args
);
3685 target
->RewardHonor(NULL
, 1, amount
);
3689 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3691 Unit
*target
= getSelectedUnit();
3694 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3695 SetSentErrorMessage(true);
3699 // check online security
3700 if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
3703 m_session
->GetPlayer()->RewardHonor(target
, 1);
3707 bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
3709 Player
*target
= getSelectedPlayer();
3712 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3713 SetSentErrorMessage(true);
3717 // check online security
3718 if (HasLowerSecurity(target
, 0))
3721 target
->UpdateHonorFields();
3725 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3730 std::string namepart
= args
;
3731 std::wstring wnamepart
;
3733 // converting string that we try to find to lower case
3734 if(!Utf8toWStr(namepart
,wnamepart
))
3737 wstrToLower(wnamepart
);
3741 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3742 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3744 for(uint32 id
= 0; id
< events
.size(); ++id
)
3746 GameEventData
const& eventData
= events
[id
];
3748 std::string descr
= eventData
.description
;
3752 if (Utf8FitTo(descr
, wnamepart
))
3754 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3757 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3759 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3766 SendSysMessage(LANG_NOEVENTFOUND
);
3771 bool ChatHandler::HandleEventListCommand(const char* args
)
3775 std::string arg
= args
;
3779 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3780 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3782 char const* active
= GetMangosString(LANG_ACTIVE
);
3783 char const* inactive
= GetMangosString(LANG_FACTION_INACTIVE
);
3784 char const* state
= "";
3786 for (uint32 event_id
= 0; event_id
< events
.size(); ++event_id
)
3788 if (activeEvents
.find(event_id
) == activeEvents
.end())
3797 GameEventData
const& eventData
= events
[event_id
];
3800 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
, event_id
, event_id
, eventData
.description
.c_str(), state
);
3802 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
, event_id
, eventData
.description
.c_str(), state
);
3808 SendSysMessage(LANG_NOEVENTFOUND
);
3813 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3818 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3819 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3823 uint32 event_id
= atoi(cId
);
3825 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3827 if(event_id
>=events
.size())
3829 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3830 SetSentErrorMessage(true);
3834 GameEventData
const& eventData
= events
[event_id
];
3835 if(!eventData
.isValid())
3837 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3838 SetSentErrorMessage(true);
3842 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3843 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3844 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3846 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3847 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3849 uint32 delay
= sGameEventMgr
.NextCheck(event_id
);
3850 time_t nextTime
= time(NULL
)+delay
;
3851 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3853 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3854 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3856 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3857 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3862 bool ChatHandler::HandleEventStartCommand(const char* args
)
3867 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3868 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3872 int32 event_id
= atoi(cId
);
3874 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3876 if(event_id
< 1 || event_id
>=(int32
)events
.size())
3878 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3879 SetSentErrorMessage(true);
3883 GameEventData
const& eventData
= events
[event_id
];
3884 if(!eventData
.isValid())
3886 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3887 SetSentErrorMessage(true);
3891 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3892 if(activeEvents
.find(event_id
) != activeEvents
.end())
3894 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3895 SetSentErrorMessage(true);
3899 PSendSysMessage(LANG_EVENT_STARTED
, event_id
, eventData
.description
.c_str());
3900 sGameEventMgr
.StartEvent(event_id
,true);
3904 bool ChatHandler::HandleEventStopCommand(const char* args
)
3909 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3910 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3914 int32 event_id
= atoi(cId
);
3916 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3918 if(event_id
< 1 || event_id
>=(int32
)events
.size())
3920 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3921 SetSentErrorMessage(true);
3925 GameEventData
const& eventData
= events
[event_id
];
3926 if(!eventData
.isValid())
3928 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3929 SetSentErrorMessage(true);
3933 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3935 if(activeEvents
.find(event_id
) == activeEvents
.end())
3937 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3938 SetSentErrorMessage(true);
3942 PSendSysMessage(LANG_EVENT_STOPPED
, event_id
, eventData
.description
.c_str());
3943 sGameEventMgr
.StopEvent(event_id
,true);
3947 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3950 if(!extractPlayerTarget((char*)args
,&target
))
3953 // check online security
3954 if (HasLowerSecurity(target
, 0))
3957 target
->CombatStop();
3958 target
->getHostileRefManager().deleteReferences();
3962 void ChatHandler::HandleLearnSkillRecipesHelper(Player
* player
,uint32 skill_id
)
3964 uint32 classmask
= player
->getClassMask();
3966 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3968 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3973 if( skillLine
->skillId
!= skill_id
)
3977 if(skillLine
->forward_spellid
)
3980 // skip racial skills
3981 if (skillLine
->racemask
!= 0)
3984 // skip wrong class skills
3985 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3988 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3989 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,player
,false))
3992 player
->learnSpell(skillLine
->spellId
,false);
3996 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3998 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
4000 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
4004 if ((skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
) &&
4005 skillInfo
->canLink
) // only prof. with recipes have
4007 HandleLearnSkillRecipesHelper(m_session
->GetPlayer(),skillInfo
->id
);
4011 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
4015 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
4017 // Learns all recipes of specified profession and sets skill to max
4018 // Example: .learn all_recipes enchanting
4020 Player
* target
= getSelectedPlayer();
4023 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
4030 std::wstring wnamepart
;
4032 if(!Utf8toWStr(args
,wnamepart
))
4035 // converting string that we try to find to lower case
4036 wstrToLower( wnamepart
);
4040 SkillLineEntry
const *targetSkillInfo
= NULL
;
4041 for (uint32 i
= 1; i
< sSkillLineStore
.GetNumRows(); ++i
)
4043 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
4047 if ((skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
4048 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
) ||
4049 !skillInfo
->canLink
) // only prof with recipes have set
4052 int loc
= GetSessionDbcLocale();
4053 name
= skillInfo
->name
[loc
];
4057 if (!Utf8FitTo(name
, wnamepart
))
4060 for(; loc
< MAX_LOCALE
; ++loc
)
4062 if(loc
==GetSessionDbcLocale())
4065 name
= skillInfo
->name
[loc
];
4069 if (Utf8FitTo(name
, wnamepart
))
4074 if(loc
< MAX_LOCALE
)
4076 targetSkillInfo
= skillInfo
;
4081 if(!targetSkillInfo
)
4084 HandleLearnSkillRecipesHelper(target
,targetSkillInfo
->id
);
4086 uint16 maxLevel
= target
->GetPureMaxSkillValue(targetSkillInfo
->id
);
4087 target
->SetSkill(targetSkillInfo
->id
, maxLevel
, maxLevel
);
4088 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
4092 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
4098 std::string ip
= strtok ((char*)args
, " ");
4099 char* limit_str
= strtok (NULL
, " ");
4100 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4102 loginDatabase
.escape_string (ip
);
4104 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
4106 return LookupPlayerSearchCommand (result
,limit
);
4109 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
4114 std::string account
= strtok ((char*)args
, " ");
4115 char* limit_str
= strtok (NULL
, " ");
4116 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4118 if (!AccountMgr::normalizeString (account
))
4121 loginDatabase
.escape_string (account
);
4123 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
4125 return LookupPlayerSearchCommand (result
,limit
);
4128 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
4134 std::string email
= strtok ((char*)args
, " ");
4135 char* limit_str
= strtok (NULL
, " ");
4136 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4138 loginDatabase
.escape_string (email
);
4140 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
4142 return LookupPlayerSearchCommand (result
,limit
);
4145 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
4149 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4150 SetSentErrorMessage(true);
4157 Field
* fields
= result
->Fetch();
4158 uint32 acc_id
= fields
[0].GetUInt32();
4159 std::string acc_name
= fields
[1].GetCppString();
4161 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4164 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4171 Field
* charfields
= chars
->Fetch();
4172 guid
= charfields
[0].GetUInt64();
4173 name
= charfields
[1].GetCppString();
4175 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4178 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4182 } while(result
->NextRow());
4186 if(i
==0) // empty accounts only
4188 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4189 SetSentErrorMessage(true);
4196 /// Triggering corpses expire check in world
4197 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4203 bool ChatHandler::HandleRepairitemsCommand(const char* args
)
4206 if(!extractPlayerTarget((char*)args
,&target
))
4209 // check online security
4210 if (HasLowerSecurity(target
, 0))
4214 target
->DurabilityRepairAll(false, 0, false);
4216 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, GetNameLink(target
).c_str());
4217 if(needReportToTarget(target
))
4218 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetNameLink().c_str());
4222 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4227 Player
*player
= getSelectedPlayer();
4231 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4232 SetSentErrorMessage(true);
4236 // check online security
4237 if (HasLowerSecurity(player
, 0))
4240 if (strncmp(args
, "on", 3) == 0)
4241 player
->SetMovement(MOVE_WATER_WALK
); // ON
4242 else if (strncmp(args
, "off", 4) == 0)
4243 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4246 SendSysMessage(LANG_USE_BOL
);
4250 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, GetNameLink(player
).c_str());
4251 if(needReportToTarget(player
))
4252 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetNameLink().c_str());
4256 bool ChatHandler::HandleLookupTitleCommand(const char* args
)
4261 // can be NULL in console call
4262 Player
* target
= getSelectedPlayer();
4264 // title name have single string arg for player name
4265 char const* targetName
= target
? target
->GetName() : "NAME";
4267 std::string namepart
= args
;
4268 std::wstring wnamepart
;
4270 if(!Utf8toWStr(namepart
,wnamepart
))
4273 // converting string that we try to find to lower case
4274 wstrToLower( wnamepart
);
4276 uint32 counter
= 0; // Counter for figure out that we found smth.
4278 // Search in CharTitles.dbc
4279 for (uint32 id
= 0; id
< sCharTitlesStore
.GetNumRows(); id
++)
4281 CharTitlesEntry
const *titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4284 int loc
= GetSessionDbcLocale();
4285 std::string name
= titleInfo
->name
[loc
];
4289 if (!Utf8FitTo(name
, wnamepart
))
4292 for(; loc
< MAX_LOCALE
; ++loc
)
4294 if(loc
==GetSessionDbcLocale())
4297 name
= titleInfo
->name
[loc
];
4301 if (Utf8FitTo(name
, wnamepart
))
4306 if(loc
< MAX_LOCALE
)
4308 char const* knownStr
= target
&& target
->HasTitle(titleInfo
) ? GetMangosString(LANG_KNOWN
) : "";
4310 char const* activeStr
= target
&& target
->GetUInt32Value(PLAYER_CHOSEN_TITLE
)==titleInfo
->bit_index
4311 ? GetMangosString(LANG_ACTIVE
)
4314 char titleNameStr
[80];
4315 snprintf(titleNameStr
,80,name
.c_str(),targetName
);
4317 // send title in "id (idx:idx) - [namedlink locale]" format
4319 PSendSysMessage(LANG_TITLE_LIST_CHAT
,id
,titleInfo
->bit_index
,id
,titleNameStr
,localeNames
[loc
],knownStr
,activeStr
);
4321 PSendSysMessage(LANG_TITLE_LIST_CONSOLE
,id
,titleInfo
->bit_index
,titleNameStr
,localeNames
[loc
],knownStr
,activeStr
);
4327 if (counter
== 0) // if counter == 0 then we found nth
4328 SendSysMessage(LANG_COMMAND_NOTITLEFOUND
);
4332 bool ChatHandler::HandleTitlesAddCommand(const char* args
)
4334 // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
4335 char* id_p
= extractKeyFromLink((char*)args
,"Htitle");
4339 int32 id
= atoi(id_p
);
4342 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4343 SetSentErrorMessage(true);
4347 Player
* target
= getSelectedPlayer();
4350 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4351 SetSentErrorMessage(true);
4355 // check online security
4356 if (HasLowerSecurity(target
, 0))
4359 CharTitlesEntry
const* titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4362 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4363 SetSentErrorMessage(true);
4367 std::string tNameLink
= GetNameLink(target
);
4369 char const* targetName
= target
->GetName();
4370 char titleNameStr
[80];
4371 snprintf(titleNameStr
,80,titleInfo
->name
[GetSessionDbcLocale()],targetName
);
4373 target
->SetTitle(titleInfo
);
4374 PSendSysMessage(LANG_TITLE_ADD_RES
, id
, titleNameStr
, tNameLink
.c_str());
4379 bool ChatHandler::HandleTitlesRemoveCommand(const char* args
)
4381 // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
4382 char* id_p
= extractKeyFromLink((char*)args
,"Htitle");
4386 int32 id
= atoi(id_p
);
4389 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4390 SetSentErrorMessage(true);
4394 Player
* target
= getSelectedPlayer();
4397 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4398 SetSentErrorMessage(true);
4402 // check online security
4403 if (HasLowerSecurity(target
, 0))
4406 CharTitlesEntry
const* titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4409 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4410 SetSentErrorMessage(true);
4414 target
->SetTitle(titleInfo
,true);
4416 std::string tNameLink
= GetNameLink(target
);
4418 char const* targetName
= target
->GetName();
4419 char titleNameStr
[80];
4420 snprintf(titleNameStr
,80,titleInfo
->name
[GetSessionDbcLocale()],targetName
);
4422 PSendSysMessage(LANG_TITLE_REMOVE_RES
, id
, titleNameStr
, tNameLink
.c_str());
4424 if (!target
->HasTitle(target
->GetInt32Value(PLAYER_CHOSEN_TITLE
)))
4426 target
->SetUInt32Value(PLAYER_CHOSEN_TITLE
,0);
4427 PSendSysMessage(LANG_CURRENT_TITLE_RESET
, tNameLink
.c_str());
4433 //Edit Player KnownTitles
4434 bool ChatHandler::HandleTitlesSetMaskCommand(const char* args
)
4441 sscanf((char*)args
, UI64FMTD
, &titles
);
4443 Player
*target
= getSelectedPlayer();
4446 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4447 SetSentErrorMessage(true);
4451 // check online security
4452 if (HasLowerSecurity(target
, 0))
4455 uint64 titles2
= titles
;
4457 for(uint32 i
= 1; i
< sCharTitlesStore
.GetNumRows(); ++i
)
4458 if(CharTitlesEntry
const* tEntry
= sCharTitlesStore
.LookupEntry(i
))
4459 titles2
&= ~(uint64(1) << tEntry
->bit_index
);
4461 titles
&= ~titles2
; // remove not existed titles
4463 target
->SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES
, titles
);
4464 SendSysMessage(LANG_DONE
);
4466 if (!target
->HasTitle(target
->GetInt32Value(PLAYER_CHOSEN_TITLE
)))
4468 target
->SetUInt32Value(PLAYER_CHOSEN_TITLE
,0);
4469 PSendSysMessage(LANG_CURRENT_TITLE_RESET
,GetNameLink(target
).c_str());
4475 bool ChatHandler::HandleCharacterTitlesCommand(const char* args
)
4478 if(!extractPlayerTarget((char*)args
,&target
))
4481 LocaleConstant loc
= GetSessionDbcLocale();
4482 char const* targetName
= target
->GetName();
4483 char const* knownStr
= GetMangosString(LANG_KNOWN
);
4485 // Search in CharTitles.dbc
4486 for (uint32 id
= 0; id
< sCharTitlesStore
.GetNumRows(); id
++)
4488 CharTitlesEntry
const *titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4489 if (titleInfo
&& target
->HasTitle(titleInfo
))
4491 std::string name
= titleInfo
->name
[loc
];
4495 char const* activeStr
= target
&& target
->GetUInt32Value(PLAYER_CHOSEN_TITLE
)==titleInfo
->bit_index
4496 ? GetMangosString(LANG_ACTIVE
)
4499 char titleNameStr
[80];
4500 snprintf(titleNameStr
,80,name
.c_str(),targetName
);
4502 // send title in "id (idx:idx) - [namedlink locale]" format
4504 PSendSysMessage(LANG_TITLE_LIST_CHAT
,id
,titleInfo
->bit_index
,id
,titleNameStr
,localeNames
[loc
],knownStr
,activeStr
);
4506 PSendSysMessage(LANG_TITLE_LIST_CONSOLE
,id
,titleInfo
->bit_index
,name
.c_str(),localeNames
[loc
],knownStr
,activeStr
);
4512 bool ChatHandler::HandleTitlesCurrentCommand(const char* args
)
4514 // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
4515 char* id_p
= extractKeyFromLink((char*)args
,"Htitle");
4519 int32 id
= atoi(id_p
);
4522 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4523 SetSentErrorMessage(true);
4527 Player
* target
= getSelectedPlayer();
4530 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4531 SetSentErrorMessage(true);
4535 // check online security
4536 if (HasLowerSecurity(target
, 0))
4539 CharTitlesEntry
const* titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4542 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4543 SetSentErrorMessage(true);
4547 std::string tNameLink
= GetNameLink(target
);
4549 target
->SetTitle(titleInfo
); // to be sure that title now known
4550 target
->SetUInt32Value(PLAYER_CHOSEN_TITLE
,titleInfo
->bit_index
);
4552 PSendSysMessage(LANG_TITLE_CURRENT_RES
, id
, titleInfo
->name
[GetSessionDbcLocale()], tNameLink
.c_str());