2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
21 #include "ObjectMgr.h"
24 #include "GameObject.h"
27 #include "ObjectAccessor.h"
28 #include "MapManager.h"
31 #include "GameEventMgr.h"
33 #include "PoolHandler.h"
34 #include "AccountMgr.h"
35 #include "GMTicketMgr.h"
36 #include "WaypointManager.h"
42 #include "GlobalEvents.h"
44 #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
46 static uint32 ReputationRankStrIndex
[MAX_REPUTATION_RANK
] =
48 LANG_REP_HATED
, LANG_REP_HOSTILE
, LANG_REP_UNFRIENDLY
, LANG_REP_NEUTRAL
,
49 LANG_REP_FRIENDLY
, LANG_REP_HONORED
, LANG_REP_REVERED
, LANG_REP_EXALTED
52 //mute player for some times
53 bool ChatHandler::HandleMuteCommand(const char* args
)
57 extractOptFirstArg((char*)args
,&nameStr
,&delayStr
);
63 std::string target_name
;
64 if(!extractPlayerTarget(nameStr
,&target
,&target_guid
,&target_name
))
67 uint32 account_id
= target
? target
->GetSession()->GetAccountId() : objmgr
.GetPlayerAccountIdByGUID(target_guid
);
69 // find only player from same account if any
72 if(WorldSession
* session
= sWorld
.FindSession(account_id
))
73 target
= session
->GetPlayer();
76 uint32 notspeaktime
= (uint32
) atoi(delayStr
);
78 // must have strong lesser security level
79 if(HasLowerSecurity (target
,target_guid
,true))
82 time_t mutetime
= time(NULL
) + notspeaktime
*60;
85 target
->GetSession()->m_muteTime
= mutetime
;
87 loginDatabase
.PExecute("UPDATE account SET mutetime = " UI64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
90 ChatHandler(target
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
92 std::string nameLink
= playerLink(target_name
);
94 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, nameLink
.c_str(), notspeaktime
);
99 bool ChatHandler::HandleUnmuteCommand(const char* args
)
103 std::string target_name
;
104 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
107 uint32 account_id
= target
? target
->GetSession()->GetAccountId() : objmgr
.GetPlayerAccountIdByGUID(target_guid
);
109 // find only player from same account if any
112 if(WorldSession
* session
= sWorld
.FindSession(account_id
))
113 target
= session
->GetPlayer();
116 // must have strong lesser security level
117 if(HasLowerSecurity (target
,target_guid
,true))
122 if(target
->CanSpeak())
124 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
125 SetSentErrorMessage(true);
129 target
->GetSession()->m_muteTime
= 0;
132 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
135 ChatHandler(target
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
137 std::string nameLink
= playerLink(target_name
);
139 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, nameLink
.c_str());
143 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
145 Player
* _player
= m_session
->GetPlayer();
150 char *atId
= strtok((char*)args
, " ");
154 int32 i_atId
= atoi(atId
);
159 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
162 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
163 SetSentErrorMessage(true);
167 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
169 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
170 SetSentErrorMessage(true);
174 // stop flight if need
175 if(_player
->isInFlight())
177 _player
->GetMotionMaster()->MovementExpired();
178 _player
->m_taxi
.ClearTaxiDestinations();
180 // save only in non-flight case
182 _player
->SaveRecallPosition();
184 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
188 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
190 Player
* _player
= m_session
->GetPlayer();
195 char *gyId
= strtok((char*)args
, " ");
199 int32 i_gyId
= atoi(gyId
);
204 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
207 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
208 SetSentErrorMessage(true);
212 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
214 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
215 SetSentErrorMessage(true);
219 // stop flight if need
220 if(_player
->isInFlight())
222 _player
->GetMotionMaster()->MovementExpired();
223 _player
->m_taxi
.ClearTaxiDestinations();
225 // save only in non-flight case
227 _player
->SaveRecallPosition();
229 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
233 /** \brief Teleport the GM to the specified creature
235 * .gocreature <GUID> --> TP using creature.guid
236 * .gocreature azuregos --> TP player to the mob with this name
237 * Warning: If there is more than one mob with this name
238 * you will be teleported to the first one that is found.
239 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
240 * Warning: If there is more than one mob with this "id"
241 * you will be teleported to the first one that is found.
243 //teleport to creature
244 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
248 Player
* _player
= m_session
->GetPlayer();
250 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
251 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
255 std::ostringstream whereClause
;
257 // User wants to teleport to the NPC's template entry
258 if( strcmp(pParam1
, "id") == 0 )
260 //sLog.outError("DEBUG: ID found");
262 // Get the "creature_template.entry"
263 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
264 char* tail
= strtok(NULL
,"");
267 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
271 int32 tEntry
= atoi(cId
);
272 //sLog.outError("DEBUG: ID value: %d", tEntry);
276 whereClause
<< "WHERE id = '" << tEntry
<< "'";
280 //sLog.outError("DEBUG: ID *not found*");
282 int32 guid
= atoi(pParam1
);
284 // Number is invalid - maybe the user specified the mob's name
287 std::string name
= pParam1
;
288 WorldDatabase
.escape_string(name
);
289 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
293 whereClause
<< "WHERE guid = '" << guid
<< "'";
296 //sLog.outError("DEBUG: %s", whereClause.c_str());
298 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
301 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
302 SetSentErrorMessage(true);
305 if( result
->GetRowCount() > 1 )
307 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
310 Field
*fields
= result
->Fetch();
311 float x
= fields
[0].GetFloat();
312 float y
= fields
[1].GetFloat();
313 float z
= fields
[2].GetFloat();
314 float ort
= fields
[3].GetFloat();
315 int mapid
= fields
[4].GetUInt16();
319 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
321 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
322 SetSentErrorMessage(true);
326 // stop flight if need
327 if(_player
->isInFlight())
329 _player
->GetMotionMaster()->MovementExpired();
330 _player
->m_taxi
.ClearTaxiDestinations();
332 // save only in non-flight case
334 _player
->SaveRecallPosition();
336 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
340 //teleport to gameobject
341 bool ChatHandler::HandleGoObjectCommand(const char* args
)
346 Player
* _player
= m_session
->GetPlayer();
348 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
349 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
353 int32 guid
= atoi(cId
);
361 if (GameObjectData
const* go_data
= objmgr
.GetGOData(guid
))
366 ort
= go_data
->orientation
;
367 mapid
= go_data
->mapid
;
371 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
372 SetSentErrorMessage(true);
376 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
378 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
379 SetSentErrorMessage(true);
383 // stop flight if need
384 if(_player
->isInFlight())
386 _player
->GetMotionMaster()->MovementExpired();
387 _player
->m_taxi
.ClearTaxiDestinations();
389 // save only in non-flight case
391 _player
->SaveRecallPosition();
393 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
397 bool ChatHandler::HandleGameObjectTargetCommand(const char* args
)
399 Player
* pl
= m_session
->GetPlayer();
401 GameEventMgr::ActiveEvents
const& activeEventsList
= gameeventmgr
.GetActiveEventList();
404 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
405 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject_entry");
409 uint32 id
= atol(cId
);
412 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",
413 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
416 std::string name
= cId
;
417 WorldDatabase
.escape_string(name
);
418 result
= WorldDatabase
.PQuery(
419 "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_ "
420 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
421 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
426 std::ostringstream eventFilter
;
427 eventFilter
<< " AND (event IS NULL ";
428 bool initString
= true;
430 for (GameEventMgr::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
434 eventFilter
<< "OR event IN (" <<*itr
;
438 eventFilter
<< "," << *itr
;
446 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
447 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
448 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
449 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
454 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
461 uint16 mapid
, pool_id
;
465 Field
*fields
= result
->Fetch();
466 lowguid
= fields
[0].GetUInt32();
467 id
= fields
[1].GetUInt32();
468 x
= fields
[2].GetFloat();
469 y
= fields
[3].GetFloat();
470 z
= fields
[4].GetFloat();
471 o
= fields
[5].GetFloat();
472 mapid
= fields
[6].GetUInt16();
473 pool_id
= poolhandler
.IsPartOfAPool(lowguid
, TYPEID_GAMEOBJECT
);
474 if (!pool_id
|| (pool_id
&& poolhandler
.IsSpawnedObject(pool_id
, lowguid
, TYPEID_GAMEOBJECT
)))
476 } while( result
->NextRow() && (!found
) );
482 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
486 GameObjectInfo
const* goI
= objmgr
.GetGameObjectInfo(id
);
490 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
494 GameObject
* target
= m_session
->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
496 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
500 int32 curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
501 if(curRespawnDelay
< 0)
504 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
505 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
507 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
512 //delete object by selection or guid
513 bool ChatHandler::HandleGameObjectDeleteCommand(const char* args
)
515 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
516 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
520 uint32 lowguid
= atoi(cId
);
524 GameObject
* obj
= NULL
;
527 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
528 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
532 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
533 SetSentErrorMessage(true);
537 uint64 owner_guid
= obj
->GetOwnerGUID();
540 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
541 if(!owner
|| !IS_PLAYER_GUID(owner_guid
))
543 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
544 SetSentErrorMessage(true);
548 owner
->RemoveGameObject(obj
,false);
551 obj
->SetRespawnTime(0); // not save respawn time
555 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
560 //turn selected object
561 bool ChatHandler::HandleGameObjectTurnCommand(const char* args
)
563 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
564 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
568 uint32 lowguid
= atoi(cId
);
572 GameObject
* obj
= NULL
;
575 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
576 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
580 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
581 SetSentErrorMessage(true);
585 char* po
= strtok(NULL
, " ");
594 Player
*chr
= m_session
->GetPlayer();
595 o
= chr
->GetOrientation();
598 Map
* map
= obj
->GetMap();
599 map
->Remove(obj
,false);
601 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
602 obj
->UpdateRotationFields();
609 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), obj
->GetGOInfo()->name
, obj
->GetGUIDLow(), o
);
614 //move selected object
615 bool ChatHandler::HandleGameObjectMoveCommand(const char* args
)
617 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
618 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
622 uint32 lowguid
= atoi(cId
);
626 GameObject
* obj
= NULL
;
629 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
630 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
634 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
635 SetSentErrorMessage(true);
639 char* px
= strtok(NULL
, " ");
640 char* py
= strtok(NULL
, " ");
641 char* pz
= strtok(NULL
, " ");
645 Player
*chr
= m_session
->GetPlayer();
647 Map
* map
= obj
->GetMap();
648 map
->Remove(obj
,false);
650 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
659 float x
= (float)atof(px
);
660 float y
= (float)atof(py
);
661 float z
= (float)atof(pz
);
663 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
665 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
666 SetSentErrorMessage(true);
670 Map
* map
= obj
->GetMap();
671 map
->Remove(obj
,false);
673 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
681 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow(), obj
->GetGOInfo()->name
, obj
->GetGUIDLow());
687 bool ChatHandler::HandleGameObjectAddCommand(const char* args
)
692 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
693 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject_entry");
697 uint32 id
= atol(cId
);
701 char* spawntimeSecs
= strtok(NULL
, " ");
703 const GameObjectInfo
*gInfo
= objmgr
.GetGameObjectInfo(id
);
707 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
708 SetSentErrorMessage(true);
712 if (gInfo
->displayId
&& !sGameObjectDisplayInfoStore
.LookupEntry(gInfo
->displayId
))
714 // report to DB errors log as in loading case
715 sLog
.outErrorDb("Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.",id
, gInfo
->type
, gInfo
->displayId
);
716 PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA
,id
);
717 SetSentErrorMessage(true);
721 Player
*chr
= m_session
->GetPlayer();
722 float x
= float(chr
->GetPositionX());
723 float y
= float(chr
->GetPositionY());
724 float z
= float(chr
->GetPositionZ());
725 float o
= float(chr
->GetOrientation());
726 Map
*map
= chr
->GetMap();
728 GameObject
* pGameObj
= new GameObject
;
729 uint32 db_lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
731 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
))
739 uint32 value
= atoi((char*)spawntimeSecs
);
740 pGameObj
->SetRespawnTime(value
);
741 //sLog.outDebug("*** spawntimeSecs: %d", value);
744 // fill the gameobject data and save to the db
745 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()),chr
->GetPhaseMaskForSpawn());
747 // this will generate a new guid if the object is in an instance
748 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
754 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), gInfo
->name
, db_lowGUID
, x
, y
, z
, o
);
758 // TODO: is it really necessary to add both the real and DB table guid here ?
759 objmgr
.AddGameobjectToGrid(db_lowGUID
, objmgr
.GetGOData(db_lowGUID
));
761 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,gInfo
->name
,db_lowGUID
,x
,y
,z
);
765 //set pahsemask for selected object
766 bool ChatHandler::HandleGameObjectPhaseCommand(const char* args
)
768 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
769 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
773 uint32 lowguid
= atoi(cId
);
777 GameObject
* obj
= NULL
;
780 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
781 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
785 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
786 SetSentErrorMessage(true);
790 char* phaseStr
= strtok (NULL
, " ");
791 uint32 phasemask
= phaseStr
? atoi(phaseStr
) : 0;
792 if ( phasemask
== 0 )
794 SendSysMessage(LANG_BAD_VALUE
);
795 SetSentErrorMessage(true);
799 obj
->SetPhaseMask(phasemask
,true);
804 bool ChatHandler::HandleGameObjectNearCommand(const char* args
)
806 float distance
= (!*args
) ? 10 : atol(args
);
809 Player
* pl
= m_session
->GetPlayer();
810 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
811 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
812 "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_",
813 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(),
814 pl
->GetMapId(),pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(),distance
*distance
);
820 Field
*fields
= result
->Fetch();
821 uint32 guid
= fields
[0].GetUInt32();
822 uint32 entry
= fields
[1].GetUInt32();
823 float x
= fields
[2].GetFloat();
824 float y
= fields
[3].GetFloat();
825 float z
= fields
[4].GetFloat();
826 int mapid
= fields
[5].GetUInt16();
828 GameObjectInfo
const * gInfo
= objmgr
.GetGameObjectInfo(entry
);
833 PSendSysMessage(LANG_GO_LIST_CHAT
, guid
, guid
, gInfo
->name
, x
, y
, z
, mapid
);
836 } while (result
->NextRow());
841 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE
,distance
,count
);
845 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
847 uint64 guid
= m_session
->GetPlayer()->GetSelection();
851 SendSysMessage(LANG_NO_SELECTION
);
852 SetSentErrorMessage(true);
856 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
860 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
865 // Can be NULL at console call
866 Player
*target
= getSelectedPlayer ();
868 std::string namepart
= args
;
869 std::wstring wnamepart
;
871 if (!Utf8toWStr (namepart
,wnamepart
))
874 // converting string that we try to find to lower case
875 wstrToLower (wnamepart
);
877 uint32 counter
= 0; // Counter for figure out that we found smth.
879 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
881 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
884 FactionState
const* repState
= target
? target
->GetReputationMgr().GetState(factionEntry
) : NULL
;
886 int loc
= GetSessionDbcLocale();
887 std::string name
= factionEntry
->name
[loc
];
891 if (!Utf8FitTo(name
, wnamepart
))
894 for(; loc
< MAX_LOCALE
; ++loc
)
896 if(loc
==GetSessionDbcLocale())
899 name
= factionEntry
->name
[loc
];
903 if (Utf8FitTo(name
, wnamepart
))
910 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
911 // or "id - [faction] [no reputation]" format
912 std::ostringstream ss
;
914 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
916 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
918 if (repState
) // and then target!=NULL also
920 ReputationRank rank
= target
->GetReputationMgr().GetRank(factionEntry
);
921 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
923 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputationMgr().GetReputation(factionEntry
) << ")";
925 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
926 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
927 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
928 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
929 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
930 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
931 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
932 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
933 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
934 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
935 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
936 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
939 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
941 SendSysMessage(ss
.str().c_str());
947 if (counter
== 0) // if counter == 0 then we found nth
948 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
952 bool ChatHandler::HandleModifyRepCommand(const char * args
)
954 if (!*args
) return false;
956 Player
* target
= NULL
;
957 target
= getSelectedPlayer();
961 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
962 SetSentErrorMessage(true);
966 // check online security
967 if (HasLowerSecurity(target
, 0))
970 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
974 uint32 factionId
= atoi(factionTxt
);
977 char *rankTxt
= strtok(NULL
, " ");
978 if (!factionTxt
|| !rankTxt
)
981 amount
= atoi(rankTxt
);
982 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
984 std::string rankStr
= rankTxt
;
985 std::wstring wrankStr
;
986 if(!Utf8toWStr(rankStr
,wrankStr
))
988 wstrToLower( wrankStr
);
992 for (; r
< MAX_REPUTATION_RANK
; ++r
)
994 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
999 if(!Utf8toWStr(rank
,wrank
))
1004 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
1006 char *deltaTxt
= strtok(NULL
, " ");
1009 int32 delta
= atoi(deltaTxt
);
1010 if ((delta
< 0) || (delta
> ReputationMgr::PointsInRank
[r
] -1))
1012 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (ReputationMgr::PointsInRank
[r
]-1));
1013 SetSentErrorMessage(true);
1020 amount
+= ReputationMgr::PointsInRank
[r
];
1022 if (r
>= MAX_REPUTATION_RANK
)
1024 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
1025 SetSentErrorMessage(true);
1030 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
1034 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
1035 SetSentErrorMessage(true);
1039 if (factionEntry
->reputationListID
< 0)
1041 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[GetSessionDbcLocale()], factionId
);
1042 SetSentErrorMessage(true);
1046 target
->GetReputationMgr().SetReputation(factionEntry
,amount
);
1047 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[GetSessionDbcLocale()], factionId
,
1048 GetNameLink(target
).c_str(), target
->GetReputationMgr().GetReputation(factionEntry
));
1052 //-----------------------Npc Commands-----------------------
1053 //add spawn of creature
1054 bool ChatHandler::HandleNpcAddCommand(const char* args
)
1058 char* charID
= extractKeyFromLink((char*)args
,"Hcreature_entry");
1062 char* team
= strtok(NULL
, " ");
1064 if (team
) { teamval
= atoi(team
); }
1065 if (teamval
< 0) { teamval
= 0; }
1067 uint32 id
= atoi(charID
);
1069 Player
*chr
= m_session
->GetPlayer();
1070 float x
= chr
->GetPositionX();
1071 float y
= chr
->GetPositionY();
1072 float z
= chr
->GetPositionZ();
1073 float o
= chr
->GetOrientation();
1074 Map
*map
= chr
->GetMap();
1076 Creature
* pCreature
= new Creature
;
1077 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, (uint32
)teamval
))
1083 pCreature
->Relocate(x
,y
,z
,o
);
1085 if(!pCreature
->IsPositionValid())
1087 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());
1092 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
1094 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
1096 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
1097 pCreature
->LoadFromDB(db_guid
, map
);
1099 map
->Add(pCreature
);
1100 objmgr
.AddCreatureToGrid(db_guid
, objmgr
.GetCreatureData(db_guid
));
1104 //add item in vendorlist
1105 bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args
)
1110 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1113 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1114 SetSentErrorMessage(true);
1118 uint32 itemId
= atol(pitem
);
1120 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1121 uint32 maxcount
= 0;
1123 maxcount
= atol(fmaxcount
);
1125 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1126 uint32 incrtime
= 0;
1128 incrtime
= atol(fincrtime
);
1130 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1131 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1133 Creature
* vendor
= getSelectedCreature();
1135 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1137 if(!objmgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1139 SetSentErrorMessage(true);
1143 objmgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1145 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1147 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1151 //del item from vendor list
1152 bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args
)
1157 Creature
* vendor
= getSelectedCreature();
1158 if (!vendor
|| !vendor
->isVendor())
1160 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1161 SetSentErrorMessage(true);
1165 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1168 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1169 SetSentErrorMessage(true);
1172 uint32 itemId
= atol(pitem
);
1174 if(!objmgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1176 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1177 SetSentErrorMessage(true);
1181 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1183 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1187 //add move for creature
1188 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1193 char* guid_str
= strtok((char*)args
, " ");
1194 char* wait_str
= strtok((char*)NULL
, " ");
1196 uint32 lowguid
= atoi((char*)guid_str
);
1198 Creature
* pCreature
= NULL
;
1200 /* FIXME: impossible without entry
1202 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1205 // attempt check creature existence by DB data
1208 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1211 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1212 SetSentErrorMessage(true);
1218 // obtain real GUID for DB operations
1219 lowguid
= pCreature
->GetDBTableGUIDLow();
1222 int wait
= wait_str
? atoi(wait_str
) : 0;
1227 Player
* player
= m_session
->GetPlayer();
1229 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1231 // update movement type
1232 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1235 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1236 pCreature
->GetMotionMaster()->Initialize();
1237 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1239 pCreature
->setDeathState(JUST_DIED
);
1240 pCreature
->Respawn();
1242 pCreature
->SaveToDB();
1245 SendSysMessage(LANG_WAYPOINT_ADDED
);
1250 //change level of creature or pet
1251 bool ChatHandler::HandleNpcChangeLevelCommand(const char* args
)
1256 uint8 lvl
= (uint8
) atoi((char*)args
);
1257 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1259 SendSysMessage(LANG_BAD_VALUE
);
1260 SetSentErrorMessage(true);
1264 Creature
* pCreature
= getSelectedCreature();
1267 SendSysMessage(LANG_SELECT_CREATURE
);
1268 SetSentErrorMessage(true);
1272 if(pCreature
->isPet())
1274 if(((Pet
*)pCreature
)->getPetType()==HUNTER_PET
)
1276 pCreature
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
, objmgr
.GetXPForLevel(lvl
)/4);
1277 pCreature
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
, 0);
1279 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1283 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1284 pCreature
->SetHealth( 100 + 30*lvl
);
1285 pCreature
->SetLevel( lvl
);
1286 pCreature
->SaveToDB();
1292 //set npcflag of creature
1293 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1298 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1300 Creature
* pCreature
= getSelectedCreature();
1304 SendSysMessage(LANG_SELECT_CREATURE
);
1305 SetSentErrorMessage(true);
1309 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1311 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1313 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1318 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
1320 Creature
* unit
= NULL
;
1324 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1325 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1329 uint32 lowguid
= atoi(cId
);
1333 if (CreatureData
const* cr_data
= objmgr
.GetCreatureData(lowguid
))
1334 unit
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
1337 unit
= getSelectedCreature();
1339 if(!unit
|| unit
->isPet() || unit
->isTotem() || unit
->isVehicle())
1341 SendSysMessage(LANG_SELECT_CREATURE
);
1342 SetSentErrorMessage(true);
1346 // Delete the creature
1348 unit
->DeleteFromDB();
1349 unit
->AddObjectToRemoveList();
1351 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
1356 //move selected creature
1357 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1361 Creature
* pCreature
= getSelectedCreature();
1365 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1366 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1370 lowguid
= atoi(cId
);
1372 /* FIXME: impossibel without entry
1374 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1377 // Attempting creature load from DB data
1380 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1383 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1384 SetSentErrorMessage(true);
1388 uint32 map_id
= data
->mapid
;
1390 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1392 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1393 SetSentErrorMessage(true);
1399 lowguid
= pCreature
->GetDBTableGUIDLow();
1404 lowguid
= pCreature
->GetDBTableGUIDLow();
1407 float x
= m_session
->GetPlayer()->GetPositionX();
1408 float y
= m_session
->GetPlayer()->GetPositionY();
1409 float z
= m_session
->GetPlayer()->GetPositionZ();
1410 float o
= m_session
->GetPlayer()->GetOrientation();
1414 if(CreatureData
const* data
= objmgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1416 const_cast<CreatureData
*>(data
)->posX
= x
;
1417 const_cast<CreatureData
*>(data
)->posY
= y
;
1418 const_cast<CreatureData
*>(data
)->posZ
= z
;
1419 const_cast<CreatureData
*>(data
)->orientation
= o
;
1421 pCreature
->GetMap()->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1422 pCreature
->GetMotionMaster()->Initialize();
1423 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1425 pCreature
->setDeathState(JUST_DIED
);
1426 pCreature
->Respawn();
1430 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1431 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1435 /**HandleNpcSetMoveTypeCommand
1436 * Set the movement type for an NPC.<br/>
1438 * Valid movement types are:
1440 * <li> stay - NPC wont move </li>
1441 * <li> random - NPC will move randomly according to the spawndist </li>
1442 * <li> way - NPC will move with given waypoints set </li>
1444 * additional parameter: NODEL - so no waypoints are deleted, if you
1445 * change the movement type
1447 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1453 // GUID (optional - you can also select the creature)
1454 // stay|random|way (determines the kind of movement)
1455 // NODEL (optional - tells the system NOT to delete any waypoints)
1456 // this is very handy if you want to do waypoints, that are
1457 // later switched on/off according to special events (like escort
1459 char* guid_str
= strtok((char*)args
, " ");
1460 char* type_str
= strtok((char*)NULL
, " ");
1461 char* dontdel_str
= strtok((char*)NULL
, " ");
1463 bool doNotDelete
= false;
1469 Creature
* pCreature
= NULL
;
1473 //sLog.outError("DEBUG: All 3 params are set");
1475 // All 3 params are set
1479 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1481 //sLog.outError("DEBUG: doNotDelete = true;");
1487 // Only 2 params - but maybe NODEL is set
1490 sLog
.outError("DEBUG: Only 2 params ");
1491 if( stricmp( type_str
, "NODEL" ) == 0 )
1493 //sLog.outError("DEBUG: type_str, NODEL ");
1500 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1502 type_str
= guid_str
;
1503 pCreature
= getSelectedCreature();
1504 if(!pCreature
|| pCreature
->isPet())
1506 lowguid
= pCreature
->GetDBTableGUIDLow();
1508 else // case .setmovetype #creature_guid $move_type (with selected creature)
1510 lowguid
= atoi((char*)guid_str
);
1512 /* impossible without entry
1514 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1517 // attempt check creature existence by DB data
1520 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1523 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1524 SetSentErrorMessage(true);
1530 lowguid
= pCreature
->GetDBTableGUIDLow();
1534 // now lowguid is low guid really existed creature
1535 // and pCreature point (maybe) to this creature or NULL
1537 MovementGeneratorType move_type
;
1539 std::string type
= type_str
;
1542 move_type
= IDLE_MOTION_TYPE
;
1543 else if(type
== "random")
1544 move_type
= RANDOM_MOTION_TYPE
;
1545 else if(type
== "way")
1546 move_type
= WAYPOINT_MOTION_TYPE
;
1550 // update movement type
1551 if(doNotDelete
== false)
1552 WaypointMgr
.DeletePath(lowguid
);
1556 pCreature
->SetDefaultMovementType(move_type
);
1557 pCreature
->GetMotionMaster()->Initialize();
1558 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1560 pCreature
->setDeathState(JUST_DIED
);
1561 pCreature
->Respawn();
1563 pCreature
->SaveToDB();
1565 if( doNotDelete
== false )
1567 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1571 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1577 //set model of creature
1578 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1583 uint32 displayId
= (uint32
) atoi((char*)args
);
1585 Creature
*pCreature
= getSelectedCreature();
1587 if(!pCreature
|| pCreature
->isPet())
1589 SendSysMessage(LANG_SELECT_CREATURE
);
1590 SetSentErrorMessage(true);
1594 pCreature
->SetDisplayId(displayId
);
1595 pCreature
->SetNativeDisplayId(displayId
);
1597 pCreature
->SaveToDB();
1601 //set faction of creature
1602 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1607 uint32 factionId
= (uint32
) atoi((char*)args
);
1609 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1611 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1612 SetSentErrorMessage(true);
1616 Creature
* pCreature
= getSelectedCreature();
1620 SendSysMessage(LANG_SELECT_CREATURE
);
1621 SetSentErrorMessage(true);
1625 pCreature
->setFaction(factionId
);
1627 // faction is set in creature_template - not inside creature
1630 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1632 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1633 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1637 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1641 //set spawn dist of creature
1642 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
1647 float option
= atof((char*)args
);
1650 SendSysMessage(LANG_BAD_VALUE
);
1654 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
1656 mtype
= RANDOM_MOTION_TYPE
;
1658 Creature
*pCreature
= getSelectedCreature();
1659 uint32 u_guidlow
= 0;
1662 u_guidlow
= pCreature
->GetDBTableGUIDLow();
1666 pCreature
->SetRespawnRadius((float)option
);
1667 pCreature
->SetDefaultMovementType(mtype
);
1668 pCreature
->GetMotionMaster()->Initialize();
1669 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1671 pCreature
->setDeathState(JUST_DIED
);
1672 pCreature
->Respawn();
1675 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
1676 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
1679 //spawn time handling
1680 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
1685 char* stime
= strtok((char*)args
, " ");
1690 int i_stime
= atoi((char*)stime
);
1694 SendSysMessage(LANG_BAD_VALUE
);
1695 SetSentErrorMessage(true);
1699 Creature
*pCreature
= getSelectedCreature();
1700 uint32 u_guidlow
= 0;
1703 u_guidlow
= pCreature
->GetDBTableGUIDLow();
1707 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
1708 pCreature
->SetRespawnDelay((uint32
)i_stime
);
1709 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
1713 //npc follow handling
1714 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
1716 Player
*player
= m_session
->GetPlayer();
1717 Creature
*creature
= getSelectedCreature();
1721 PSendSysMessage(LANG_SELECT_CREATURE
);
1722 SetSentErrorMessage(true);
1726 // Follow player - Using pet's default dist and angle
1727 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
1729 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
1732 //npc unfollow handling
1733 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
1735 Player
*player
= m_session
->GetPlayer();
1736 Creature
*creature
= getSelectedCreature();
1740 PSendSysMessage(LANG_SELECT_CREATURE
);
1741 SetSentErrorMessage(true);
1745 if (creature
->GetMotionMaster()->empty() ||
1746 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE
)
1748 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
1749 SetSentErrorMessage(true);
1753 TargetedMovementGenerator
<Creature
> const* mgen
1754 = static_cast<TargetedMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
1756 if(mgen
->GetTarget()!=player
)
1758 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
1759 SetSentErrorMessage(true);
1764 creature
->GetMotionMaster()->MovementExpired(true);
1766 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
1770 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
1772 Creature
*creatureTarget
= getSelectedCreature ();
1773 if (!creatureTarget
|| creatureTarget
->isPet ())
1775 PSendSysMessage (LANG_SELECT_CREATURE
);
1776 SetSentErrorMessage (true);
1780 Player
*player
= m_session
->GetPlayer ();
1782 if(player
->GetPetGUID ())
1784 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
1785 SetSentErrorMessage (true);
1789 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
1791 if (!cInfo
->isTameable (player
->CanTameExoticPets()))
1793 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
1794 SetSentErrorMessage (true);
1798 // Everything looks OK, create new pet
1799 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
1802 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
1803 SetSentErrorMessage (true);
1807 // place pet before player
1809 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
1810 pet
->Relocate (x
,y
,z
,M_PI
-player
->GetOrientation ());
1812 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
1813 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
1815 // calculate proper level
1816 uint32 level
= (creatureTarget
->getLevel() < (player
->getLevel() - 5)) ? (player
->getLevel() - 5) : creatureTarget
->getLevel();
1818 // prepare visual effect for levelup
1819 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
- 1);
1822 pet
->GetMap()->Add((Creature
*)pet
);
1824 // visual effect for levelup
1825 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
);
1827 // caster have pet now
1828 player
->SetPet(pet
);
1830 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
1831 player
->PetSpellInitialize();
1835 //npc phasemask handling
1836 //change phasemask of creature or pet
1837 bool ChatHandler::HandleNpcSetPhaseCommand(const char* args
)
1842 uint32 phasemask
= (uint32
) atoi((char*)args
);
1843 if ( phasemask
== 0 )
1845 SendSysMessage(LANG_BAD_VALUE
);
1846 SetSentErrorMessage(true);
1850 Creature
* pCreature
= getSelectedCreature();
1853 SendSysMessage(LANG_SELECT_CREATURE
);
1854 SetSentErrorMessage(true);
1858 pCreature
->SetPhaseMask(phasemask
,true);
1860 if(!pCreature
->isPet())
1861 pCreature
->SaveToDB();
1865 //npc deathstate handling
1866 bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args
)
1871 Creature
* pCreature
= getSelectedCreature();
1872 if(!pCreature
|| pCreature
->isPet())
1874 SendSysMessage(LANG_SELECT_CREATURE
);
1875 SetSentErrorMessage(true);
1879 if (strncmp(args
, "on", 3) == 0)
1880 pCreature
->SetDeadByDefault(true);
1881 else if (strncmp(args
, "off", 4) == 0)
1882 pCreature
->SetDeadByDefault(false);
1885 SendSysMessage(LANG_USE_BOL
);
1886 SetSentErrorMessage(true);
1890 pCreature
->SaveToDB();
1891 pCreature
->Respawn();
1896 //TODO: NpcCommands that need to be fixed :
1898 bool ChatHandler::HandleNpcNameCommand(const char* /*args*/)
1904 if(strlen((char*)args)>75)
1906 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
1910 for (uint8 i = 0; i < strlen(args); ++i)
1912 if(!isalpha(args[i]) && args[i]!=' ')
1914 SendSysMessage(LANG_CHARS_ONLY);
1920 guid = m_session->GetPlayer()->GetSelection();
1923 SendSysMessage(LANG_NO_SELECTION);
1927 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1931 SendSysMessage(LANG_SELECT_CREATURE);
1935 pCreature->SetName(args);
1936 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
1937 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1939 pCreature->SaveToDB();
1945 bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
1952 if(strlen((char*)args)>75)
1955 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
1959 for (uint8 i = 0; i < strlen(args); i++)
1961 if(!isalpha(args[i]) && args[i]!=' ')
1963 SendSysMessage(LANG_CHARS_ONLY);
1968 guid = m_session->GetPlayer()->GetSelection();
1971 SendSysMessage(LANG_NO_SELECTION);
1975 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1979 SendSysMessage(LANG_SELECT_CREATURE);
1983 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
1984 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1986 pCreature->SaveToDB();
1991 //move item to other slot
1992 bool ChatHandler::HandleItemMoveCommand(const char* args
)
1996 uint8 srcslot
, dstslot
;
1998 char* pParam1
= strtok((char*)args
, " ");
2002 char* pParam2
= strtok(NULL
, " ");
2006 srcslot
= (uint8
)atoi(pParam1
);
2007 dstslot
= (uint8
)atoi(pParam2
);
2009 if(srcslot
==dstslot
)
2012 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,srcslot
))
2015 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
))
2018 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
2019 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
2021 m_session
->GetPlayer()->SwapItem( src
, dst
);
2026 //demorph player or unit
2027 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
2029 Unit
*target
= getSelectedUnit();
2031 target
= m_session
->GetPlayer();
2034 // check online security
2035 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2043 //morph creature or player
2044 bool ChatHandler::HandleModifyMorphCommand(const char* args
)
2049 uint16 display_id
= (uint16
)atoi((char*)args
);
2051 Unit
*target
= getSelectedUnit();
2053 target
= m_session
->GetPlayer();
2055 // check online security
2056 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2059 target
->SetDisplayId(display_id
);
2065 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
2068 if(!extractPlayerTarget((char*)args
,&target
))
2071 if (m_session
&& target
==m_session
->GetPlayer())
2073 SendSysMessage(LANG_COMMAND_KICKSELF
);
2074 SetSentErrorMessage(true);
2078 // check online security
2079 if (HasLowerSecurity(target
, 0))
2082 // send before target pointer invalidate
2083 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,GetNameLink(target
).c_str());
2084 target
->GetSession()->KickPlayer();
2088 //set temporary phase mask for player
2089 bool ChatHandler::HandleModifyPhaseCommand(const char* args
)
2094 uint32 phasemask
= (uint32
)atoi((char*)args
);
2096 Unit
*target
= getSelectedUnit();
2098 target
= m_session
->GetPlayer();
2100 // check online security
2101 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2104 target
->SetPhaseMask(phasemask
,true);
2109 //show info of player
2110 bool ChatHandler::HandlePInfoCommand(const char* args
)
2114 std::string target_name
;
2115 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
2120 uint32 total_player_time
= 0;
2124 // get additional information from Player object
2127 // check online security
2128 if (HasLowerSecurity(target
, 0))
2131 accId
= target
->GetSession()->GetAccountId();
2132 money
= target
->GetMoney();
2133 total_player_time
= target
->GetTotalPlayedTime();
2134 level
= target
->getLevel();
2135 latency
= target
->GetSession()->GetLatency();
2137 // get additional information from DB
2140 // check offline security
2141 if (HasLowerSecurity(NULL
, target_guid
))
2145 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime, level, money, account FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid
));
2149 Field
*fields
= result
->Fetch();
2150 total_player_time
= fields
[0].GetUInt32();
2151 level
= fields
[1].GetUInt32();
2152 money
= fields
[2].GetUInt32();
2153 accId
= fields
[3].GetUInt32();
2157 std::string username
= GetMangosString(LANG_ERROR
);
2158 std::string last_ip
= GetMangosString(LANG_ERROR
);
2159 uint32 security
= 0;
2160 std::string last_login
= GetMangosString(LANG_ERROR
);
2162 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
2165 Field
* fields
= result
->Fetch();
2166 username
= fields
[0].GetCppString();
2167 security
= fields
[1].GetUInt32();
2169 if(!m_session
|| m_session
->GetSecurity() >= security
)
2171 last_ip
= fields
[2].GetCppString();
2172 last_login
= fields
[3].GetCppString();
2183 std::string nameLink
= playerLink(target_name
);
2185 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
);
2187 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
2188 uint32 gold
= money
/GOLD
;
2189 uint32 silv
= (money
% GOLD
) / SILVER
;
2190 uint32 copp
= (money
% GOLD
) % SILVER
;
2191 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
2197 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
2200 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
2201 name
= GetMangosString(LANG_UNKNOWN
);
2203 std::string nameLink
= playerLink(name
);
2205 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, nameLink
.c_str(),time
,text
);
2209 bool ChatHandler::HandleTicketCommand(const char* args
)
2211 char* px
= strtok((char*)args
, " ");
2218 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2219 SetSentErrorMessage(true);
2223 size_t count
= ticketmgr
.GetTicketCount();
2225 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
2227 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
2232 if(strncmp(px
,"on",3) == 0)
2236 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2237 SetSentErrorMessage(true);
2241 m_session
->GetPlayer()->SetAcceptTicket(true);
2242 SendSysMessage(LANG_COMMAND_TICKETON
);
2247 if(strncmp(px
,"off",4) == 0)
2251 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2252 SetSentErrorMessage(true);
2256 m_session
->GetPlayer()->SetAcceptTicket(false);
2257 SendSysMessage(LANG_COMMAND_TICKETOFF
);
2265 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
2269 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2270 SetSentErrorMessage(true);
2274 Field
* fields
= result
->Fetch();
2276 uint32 guid
= fields
[0].GetUInt32();
2277 char const* text
= fields
[1].GetString();
2278 char const* time
= fields
[2].GetString();
2280 ShowTicket(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
),text
,time
);
2286 if(!extractPlayerTarget(px
,NULL
,&target_guid
))
2289 // ticket $char_name
2290 GMTicket
* ticket
= ticketmgr
.GetGMTicket(GUID_LOPART(target_guid
));
2294 std::string time
= TimeToTimestampStr(ticket
->GetLastUpdate());
2296 ShowTicket(target_guid
, ticket
->GetText(), time
.c_str());
2302 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2304 char* px
= strtok((char*)args
, " ");
2309 if(strncmp(px
,"all",4) == 0)
2311 ticketmgr
.DeleteAll();
2312 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2316 int num
= (uint32
)atoi(px
);
2321 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2324 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2325 SetSentErrorMessage(true);
2328 Field
* fields
= result
->Fetch();
2329 uint32 guid
= fields
[0].GetUInt32();
2332 ticketmgr
.Delete(guid
);
2335 if(Player
* pl
= objmgr
.GetPlayer(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
)))
2337 pl
->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2338 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
, GetNameLink(pl
).c_str());
2341 PSendSysMessage(LANG_COMMAND_TICKETDEL
);
2348 std::string target_name
;
2349 if(!extractPlayerTarget(px
,&target
,&target_guid
,&target_name
))
2352 // delticket $char_name
2353 ticketmgr
.Delete(GUID_LOPART(target_guid
));
2355 // notify players about ticket deleting
2357 target
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2359 std::string nameLink
= playerLink(target_name
);
2361 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,nameLink
.c_str());
2366 * Add a waypoint to a creature.
2368 * The user can either select an npc or provide its GUID.
2370 * The user can even select a visual waypoint - then the new waypoint
2371 * is placed *after* the selected one - this makes insertion of new
2372 * waypoints possible.
2376 * -> adds a waypoint to the npc with the GUID 12345
2379 * -> adds a waypoint to the currently selected creature
2382 * @param args if the user did not provide a GUID, it is NULL
2384 * @return true - command did succeed, false - something went wrong
2386 bool ChatHandler::HandleWpAddCommand(const char* args
)
2388 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2391 char* guid_str
= NULL
;
2395 guid_str
= strtok((char*)args
, " ");
2400 Creature
* target
= getSelectedCreature();
2401 // Did player provide a GUID?
2404 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2407 // -> Player must have selected a creature
2409 if(!target
|| target
->isPet())
2411 SendSysMessage(LANG_SELECT_CREATURE
);
2412 SetSentErrorMessage(true);
2415 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2417 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2419 QueryResult
*result
=
2420 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2421 target
->GetGUIDLow() );
2424 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2425 // User selected a visual spawnpoint -> get the NPC
2427 // Since we compare float values, we have to deal with
2428 // some difficulties.
2429 // Here we search for all waypoints that only differ in one from 1 thousand
2430 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2431 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2432 const char* maxDIFF
= "0.01";
2433 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 )",
2434 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2437 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2438 SetSentErrorMessage(true);
2444 Field
*fields
= result
->Fetch();
2445 lowguid
= fields
[0].GetUInt32();
2446 point
= fields
[1].GetUInt32();
2447 }while( result
->NextRow() );
2450 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2453 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2454 SetSentErrorMessage(true);
2458 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2461 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2462 SetSentErrorMessage(true);
2468 lowguid
= target
->GetDBTableGUIDLow();
2473 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2476 // Warn if player also selected a creature
2477 // -> Creature selection is ignored <-
2480 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2482 lowguid
= atoi((char*)guid_str
);
2484 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2487 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2488 SetSentErrorMessage(true);
2492 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2493 if(!target
|| target
->isPet())
2495 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2496 SetSentErrorMessage(true);
2500 // lowguid -> GUID of the NPC
2501 // point -> number of the waypoint (if not 0)
2502 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2504 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2506 Player
* player
= m_session
->GetPlayer();
2507 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2509 // update movement type
2512 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2513 target
->GetMotionMaster()->Initialize();
2514 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2516 target
->setDeathState(JUST_DIED
);
2522 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2524 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2527 } // HandleWpAddCommand
2530 * .wp modify emote | spell | text | del | move | add
2532 * add -> add a WP after the selected visual waypoint
2533 * User must select a visual waypoint and then issue ".wp modify add"
2536 * User has selected a visual waypoint before.
2537 * <emoteID> is added to this waypoint. Everytime the
2538 * NPC comes to this waypoint, the emote is called.
2540 * emote <GUID> <WPNUM> <emoteID>
2541 * User has not selected visual waypoint before.
2542 * For the waypoint <WPNUM> for the NPC with <GUID>
2543 * an emote <emoteID> is added.
2544 * Everytime the NPC comes to this waypoint, the emote is called.
2547 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2549 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2551 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2556 // first arg: add del text emote spell waittime move
2557 char* show_str
= strtok((char*)args
, " ");
2563 std::string show
= show_str
;
2565 // Remember: "show" must also be the name of a column!
2566 if( (show
!= "emote") && (show
!= "spell") && (show
!= "textid1") && (show
!= "textid2")
2567 && (show
!= "textid3") && (show
!= "textid4") && (show
!= "textid5")
2568 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2569 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2574 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2576 // Did user provide a GUID
2577 // or did the user select a creature?
2578 // -> variable lowguid is filled with the GUID of the NPC
2582 Creature
* target
= getSelectedCreature();
2586 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2588 // Did the user select a visual spawnpoint?
2589 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2591 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2592 SetSentErrorMessage(true);
2596 wpGuid
= target
->GetGUIDLow();
2598 // The visual waypoint
2599 QueryResult
*result
=
2600 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2601 target
->GetGUIDLow() );
2604 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2605 SetSentErrorMessage(true);
2608 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2610 Field
*fields
= result
->Fetch();
2611 lowguid
= fields
[0].GetUInt32();
2612 point
= fields
[1].GetUInt32();
2615 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2620 // User did provide <GUID> <WPNUM>
2622 char* guid_str
= strtok((char*)NULL
, " ");
2625 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2628 lowguid
= atoi((char*)guid_str
);
2630 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2633 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2634 SetSentErrorMessage(true);
2638 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2640 char* point_str
= strtok((char*)NULL
, " ");
2643 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2646 point
= atoi((char*)point_str
);
2648 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2650 // Now we need the GUID of the visual waypoint
2651 // -> "del", "move", "add" command
2653 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2656 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2657 SetSentErrorMessage(true);
2661 Field
*fields
= result
->Fetch();
2662 wpGuid
= fields
[0].GetUInt32();
2668 char* arg_str
= NULL
;
2669 // Check for argument
2670 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2672 // Text is enclosed in "<>", all other arguments not
2673 if( show
.find("text") != std::string::npos
)
2674 arg_str
= strtok((char*)NULL
, "<>");
2676 arg_str
= strtok((char*)NULL
, " ");
2680 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2685 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2687 // wpGuid -> GUID of the waypoint creature
2688 // lowguid -> GUID of the NPC
2689 // point -> waypoint number
2691 // Special functions:
2692 // add - move - del -> no args commands
2693 // Add a waypoint after the selected visual
2694 if(show
== "add" && target
)
2696 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2698 // Get the creature for which we read the waypoint
2699 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2702 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2703 SetSentErrorMessage(true);
2707 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2711 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2712 SetSentErrorMessage(true);
2716 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2719 // Add the visual spawnpoint (DB only)
2720 // Adjust the waypoints
2721 // Respawn the owner of the waypoints
2722 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2724 Player
* chr
= m_session
->GetPlayer();
2725 Map
*map
= chr
->GetMap();
2729 npcCreature
->GetMotionMaster()->Initialize();
2730 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2732 npcCreature
->setDeathState(JUST_DIED
);
2733 npcCreature
->Respawn();
2737 // create the waypoint creature
2739 Creature
* wpCreature
= new Creature
;
2740 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
,0))
2742 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2747 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2749 if(!wpCreature
->IsPositionValid())
2751 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());
2756 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2757 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2758 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2759 map
->Add(wpCreature
);
2760 wpGuid
= wpCreature
->GetGUIDLow();
2764 WaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2769 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2773 if(show
== "del" && target
)
2775 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2777 // Get the creature for which we read the waypoint
2778 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2781 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2782 SetSentErrorMessage(true);
2786 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2789 Creature
* wpCreature
= NULL
;
2792 wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2793 wpCreature
->DeleteFromDB();
2794 wpCreature
->AddObjectToRemoveList();
2798 // Remove the visual spawnpoint
2799 // Adjust the waypoints
2800 // Respawn the owner of the waypoints
2802 WaypointMgr
.DeleteNode(lowguid
, point
);
2806 // Any waypoints left?
2807 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2810 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2814 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2817 npcCreature
->GetMotionMaster()->Initialize();
2818 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2820 npcCreature
->setDeathState(JUST_DIED
);
2821 npcCreature
->Respawn();
2823 npcCreature
->SaveToDB();
2826 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2830 if(show
== "move" && target
)
2832 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2834 Player
*chr
= m_session
->GetPlayer();
2835 Map
*map
= chr
->GetMap();
2837 // Get the creature for which we read the waypoint
2838 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2841 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2842 SetSentErrorMessage(true);
2846 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2849 Creature
* wpCreature
= NULL
;
2851 // Move the visual spawnpoint
2852 // Respawn the owner of the waypoints
2855 wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2856 wpCreature
->DeleteFromDB();
2857 wpCreature
->AddObjectToRemoveList();
2859 Creature
* wpCreature2
= new Creature
;
2860 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
, 0))
2862 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2867 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2869 if(!wpCreature2
->IsPositionValid())
2871 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());
2876 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2877 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2878 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2879 map
->Add(wpCreature2
);
2880 //npcCreature->GetMap()->Add(wpCreature2);
2883 WaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2887 npcCreature
->GetMotionMaster()->Initialize();
2888 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2890 npcCreature
->setDeathState(JUST_DIED
);
2891 npcCreature
->Respawn();
2894 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2899 // Create creature - npc that has the waypoint
2900 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2903 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2904 SetSentErrorMessage(true);
2908 // set in game textids not supported
2909 if( show
== "textid1" || show
== "textid2" || show
== "textid3" ||
2910 show
== "textid4" || show
== "textid5" )
2915 WaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2917 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2920 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2921 npcCreature
->GetMotionMaster()->Initialize();
2922 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2924 npcCreature
->setDeathState(JUST_DIED
);
2925 npcCreature
->Respawn();
2928 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2934 * .wp show info | on | off
2936 * info -> User has selected a visual waypoint before
2938 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2939 * provided the GUID of the NPC and the number of
2942 * on -> User has selected an NPC; all visual waypoints for this
2943 * NPC are added to the world
2945 * on <GUID> -> User did not select an NPC - instead the GUID of the
2946 * NPC is provided. All visual waypoints for this NPC
2947 * are added from the world.
2949 * off -> User has selected an NPC; all visual waypoints for this
2950 * NPC are removed from the world.
2952 * on <GUID> -> User did not select an NPC - instead the GUID of the
2953 * NPC is provided. All visual waypoints for this NPC
2954 * are removed from the world.
2958 bool ChatHandler::HandleWpShowCommand(const char* args
)
2960 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2965 // first arg: on, off, first, last
2966 char* show_str
= strtok((char*)args
, " ");
2971 // second arg: GUID (optional, if a creature is selected)
2972 char* guid_str
= strtok((char*)NULL
, " ");
2973 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2978 // Did user provide a GUID
2979 // or did the user select a creature?
2980 // -> variable lowguid is filled with the GUID
2981 Creature
* target
= getSelectedCreature();
2982 // Did player provide a GUID?
2985 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2987 // -> Player must have selected a creature
2991 SendSysMessage(LANG_SELECT_CREATURE
);
2992 SetSentErrorMessage(true);
2998 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
3000 // Warn if player also selected a creature
3001 // -> Creature selection is ignored <-
3004 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
3007 uint32 lowguid
= atoi((char*)guid_str
);
3009 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
3012 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
3013 SetSentErrorMessage(true);
3017 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
3021 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
3022 SetSentErrorMessage(true);
3027 uint32 lowguid
= target
->GetDBTableGUIDLow();
3029 std::string show
= show_str
;
3032 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
3034 // Show info for the selected waypoint
3037 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
3039 // Check if the user did specify a visual waypoint
3040 if( target
->GetEntry() != VISUAL_WAYPOINT
)
3042 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
3043 SetSentErrorMessage(true);
3047 //PSendSysMessage("wp on, GUID: %u", lowguid);
3049 //pCreature->GetPositionX();
3051 QueryResult
*result
=
3052 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
3053 target
->GetGUIDLow() );
3056 // Since we compare float values, we have to deal with
3057 // some difficulties.
3058 // Here we search for all waypoints that only differ in one from 1 thousand
3059 // (0.001) - There is no other way to compare C++ floats with mySQL floats
3060 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
3061 const char* maxDIFF
= "0.01";
3062 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
3064 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 )",
3065 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
3068 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
3069 SetSentErrorMessage(true);
3075 Field
*fields
= result
->Fetch();
3076 uint32 creGUID
= fields
[0].GetUInt32();
3077 uint32 point
= fields
[1].GetUInt32();
3078 int waittime
= fields
[2].GetUInt32();
3079 uint32 emote
= fields
[3].GetUInt32();
3080 uint32 spell
= fields
[4].GetUInt32();
3081 uint32 textid
[MAX_WAYPOINT_TEXT
];
3082 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
3083 textid
[i
] = fields
[5+i
].GetUInt32();
3084 uint32 model1
= fields
[10].GetUInt32();
3085 uint32 model2
= fields
[11].GetUInt32();
3087 // Get the creature for which we read the waypoint
3088 Creature
* wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3090 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
3091 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
3092 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
3093 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
3094 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
3095 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
3096 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
3097 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, i
+1, textid
[i
], (textid
[i
] ? GetMangosString(textid
[i
]) : ""));
3099 }while( result
->NextRow() );
3107 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
3109 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
3112 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3113 SetSentErrorMessage(true);
3116 // Delete all visuals for this NPC
3117 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
3120 bool hasError
= false;
3123 Field
*fields
= result2
->Fetch();
3124 uint32 wpguid
= fields
[0].GetUInt32();
3125 Creature
* pCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3129 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
3131 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
3135 pCreature
->DeleteFromDB();
3136 pCreature
->AddObjectToRemoveList();
3139 }while( result2
->NextRow() );
3143 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3144 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3145 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3151 Field
*fields
= result
->Fetch();
3152 uint32 point
= fields
[0].GetUInt32();
3153 float x
= fields
[1].GetFloat();
3154 float y
= fields
[2].GetFloat();
3155 float z
= fields
[3].GetFloat();
3157 uint32 id
= VISUAL_WAYPOINT
;
3159 Player
*chr
= m_session
->GetPlayer();
3160 Map
*map
= chr
->GetMap();
3161 float o
= chr
->GetOrientation();
3163 Creature
* wpCreature
= new Creature
;
3164 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3166 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3172 wpCreature
->Relocate(x
, y
, z
, o
);
3174 if(!wpCreature
->IsPositionValid())
3176 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());
3182 wpCreature
->SetVisibility(VISIBILITY_OFF
);
3183 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3184 // set "wpguid" column to the visual waypoint
3185 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3187 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3188 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3189 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3190 map
->Add(wpCreature
);
3191 //wpCreature->GetMap()->Add(wpCreature);
3192 }while( result
->NextRow() );
3201 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3203 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3206 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3207 SetSentErrorMessage(true);
3211 Field
*fields
= result
->Fetch();
3212 float x
= fields
[0].GetFloat();
3213 float y
= fields
[1].GetFloat();
3214 float z
= fields
[2].GetFloat();
3215 uint32 id
= VISUAL_WAYPOINT
;
3217 Player
*chr
= m_session
->GetPlayer();
3218 float o
= chr
->GetOrientation();
3219 Map
*map
= chr
->GetMap();
3221 Creature
* pCreature
= new Creature
;
3222 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3224 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3230 pCreature
->Relocate(x
, y
, z
, o
);
3232 if(!pCreature
->IsPositionValid())
3234 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());
3240 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3241 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3242 map
->Add(pCreature
);
3243 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3252 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3254 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3257 Maxpoint
= (*result
)[0].GetUInt32();
3264 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3267 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3268 SetSentErrorMessage(true);
3271 Field
*fields
= result
->Fetch();
3272 float x
= fields
[0].GetFloat();
3273 float y
= fields
[1].GetFloat();
3274 float z
= fields
[2].GetFloat();
3275 uint32 id
= VISUAL_WAYPOINT
;
3277 Player
*chr
= m_session
->GetPlayer();
3278 float o
= chr
->GetOrientation();
3279 Map
*map
= chr
->GetMap();
3281 Creature
* pCreature
= new Creature
;
3282 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3284 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3290 pCreature
->Relocate(x
, y
, z
, o
);
3292 if(!pCreature
->IsPositionValid())
3294 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());
3300 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3301 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3302 map
->Add(pCreature
);
3303 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3311 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3314 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3315 SetSentErrorMessage(true);
3318 bool hasError
= false;
3321 Field
*fields
= result
->Fetch();
3322 uint32 guid
= fields
[0].GetUInt32();
3323 Creature
* pCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3326 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3328 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3332 pCreature
->DeleteFromDB();
3333 pCreature
->AddObjectToRemoveList();
3335 }while(result
->NextRow());
3336 // set "wpguid" column to "empty" - no visual waypoint spawned
3337 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3341 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3342 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3343 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3346 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3353 PSendSysMessage("DEBUG: wpshow - no valid command found");
3356 } // HandleWpShowCommand
3358 bool ChatHandler::HandleWpExportCommand(const char *args
)
3363 // Next arg is: <GUID> <ARGUMENT>
3365 // Did user provide a GUID
3366 // or did the user select a creature?
3367 // -> variable lowguid is filled with the GUID of the NPC
3369 Creature
* target
= getSelectedCreature();
3370 char* arg_str
= NULL
;
3373 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3374 lowguid
= target
->GetGUIDLow();
3377 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3380 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3383 Field
*fields
= result
->Fetch();
3384 lowguid
= fields
[0].GetUInt32();;
3388 arg_str
= strtok((char*)args
, " ");
3392 // user provided <GUID>
3393 char* guid_str
= strtok((char*)args
, " ");
3396 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3399 lowguid
= atoi((char*)guid_str
);
3401 arg_str
= strtok((char*)NULL
, " ");
3406 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3410 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3412 QueryResult
*result
= WorldDatabase
.PQuery(
3413 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3414 "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
);
3418 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3419 SetSentErrorMessage(true);
3423 std::ofstream outfile
;
3424 outfile
.open (arg_str
);
3428 Field
*fields
= result
->Fetch();
3430 outfile
<< "INSERT INTO creature_movement ";
3431 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3434 outfile
<< fields
[15].GetUInt32(); // id
3436 outfile
<< fields
[0].GetUInt32(); // point
3438 outfile
<< fields
[1].GetFloat(); // position_x
3440 outfile
<< fields
[2].GetFloat(); // position_y
3442 outfile
<< fields
[3].GetUInt32(); // position_z
3444 outfile
<< fields
[4].GetUInt32(); // orientation
3446 outfile
<< fields
[5].GetUInt32(); // model1
3448 outfile
<< fields
[6].GetUInt32(); // model2
3450 outfile
<< fields
[7].GetUInt16(); // waittime
3452 outfile
<< fields
[8].GetUInt32(); // emote
3454 outfile
<< fields
[9].GetUInt32(); // spell
3456 outfile
<< fields
[10].GetUInt32(); // textid1
3458 outfile
<< fields
[11].GetUInt32(); // textid2
3460 outfile
<< fields
[12].GetUInt32(); // textid3
3462 outfile
<< fields
[13].GetUInt32(); // textid4
3464 outfile
<< fields
[14].GetUInt32(); // textid5
3467 } while( result
->NextRow() );
3470 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3476 bool ChatHandler::HandleWpImportCommand(const char *args
)
3481 char* arg_str
= strtok((char*)args
, " ");
3486 std::ifstream
infile (arg_str
);
3487 if (infile
.is_open())
3489 while (! infile
.eof() )
3491 getline (infile
,line
);
3492 //cout << line << endl;
3493 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3498 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3504 bool ChatHandler::HandleCharacterRenameCommand(const char* args
)
3508 std::string target_name
;
3509 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
3514 // check online security
3515 if (HasLowerSecurity(target
, 0))
3518 PSendSysMessage(LANG_RENAME_PLAYER
, GetNameLink(target
).c_str());
3519 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3520 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3524 // check offline security
3525 if (HasLowerSecurity(NULL
, target_guid
))
3528 std::string oldNameLink
= playerLink(target_name
);
3530 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(target_guid
));
3531 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid
));
3537 // customize characters
3538 bool ChatHandler::HandleCharacterCustomizeCommand(const char* args
)
3542 std::string target_name
;
3543 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
3548 PSendSysMessage(LANG_CUSTOMIZE_PLAYER
, GetNameLink(target
).c_str());
3549 target
->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE
);
3550 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target
->GetGUIDLow());
3554 std::string oldNameLink
= playerLink(target_name
);
3556 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(target_guid
));
3557 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid
));
3563 bool ChatHandler::HandleCharacterReputationCommand(const char* args
)
3566 if(!extractPlayerTarget((char*)args
,&target
))
3569 LocaleConstant loc
= GetSessionDbcLocale();
3571 FactionStateList
const& targetFSL
= target
->GetReputationMgr().GetStateList();
3572 for(FactionStateList::const_iterator itr
= targetFSL
.begin(); itr
!= targetFSL
.end(); ++itr
)
3574 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
3575 char const* factionName
= factionEntry
? factionEntry
->name
[loc
] : "#Not found#";
3576 ReputationRank rank
= target
->GetReputationMgr().GetRank(factionEntry
);
3577 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
3578 std::ostringstream ss
;
3580 ss
<< itr
->second
.ID
<< " - |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << factionName
<< " " << localeNames
[loc
] << "]|h|r";
3582 ss
<< itr
->second
.ID
<< " - " << factionName
<< " " << localeNames
[loc
];
3584 ss
<< " " << rankName
<< " (" << target
->GetReputationMgr().GetReputation(factionEntry
) << ")";
3586 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
3587 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
3588 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
3589 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
3590 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
3591 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
3592 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
3593 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
3594 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
3595 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
3596 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
3597 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
3599 SendSysMessage(ss
.str().c_str());
3605 bool ChatHandler::HandleModifyStandStateCommand(const char* args
)
3610 uint32 anim_id
= atoi((char*)args
);
3611 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3616 bool ChatHandler::HandleHonorAddCommand(const char* args
)
3621 Player
*target
= getSelectedPlayer();
3624 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3625 SetSentErrorMessage(true);
3629 // check online security
3630 if (HasLowerSecurity(target
, 0))
3633 uint32 amount
= (uint32
)atoi(args
);
3634 target
->RewardHonor(NULL
, 1, amount
);
3638 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3640 Unit
*target
= getSelectedUnit();
3643 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3644 SetSentErrorMessage(true);
3648 // check online security
3649 if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
3652 m_session
->GetPlayer()->RewardHonor(target
, 1);
3656 bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
3658 Player
*target
= getSelectedPlayer();
3661 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3662 SetSentErrorMessage(true);
3666 // check online security
3667 if (HasLowerSecurity(target
, 0))
3670 target
->UpdateHonorFields();
3674 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3679 std::string namepart
= args
;
3680 std::wstring wnamepart
;
3682 // converting string that we try to find to lower case
3683 if(!Utf8toWStr(namepart
,wnamepart
))
3686 wstrToLower(wnamepart
);
3690 GameEventMgr::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3691 GameEventMgr::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3693 for(uint32 id
= 0; id
< events
.size(); ++id
)
3695 GameEventData
const& eventData
= events
[id
];
3697 std::string descr
= eventData
.description
;
3701 if (Utf8FitTo(descr
, wnamepart
))
3703 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3706 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3708 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3715 SendSysMessage(LANG_NOEVENTFOUND
);
3720 bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
3724 GameEventMgr::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3725 GameEventMgr::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3727 char const* active
= GetMangosString(LANG_ACTIVE
);
3729 for(GameEventMgr::ActiveEvents::const_iterator itr
= activeEvents
.begin(); itr
!= activeEvents
.end(); ++itr
)
3731 uint32 event_id
= *itr
;
3732 GameEventData
const& eventData
= events
[event_id
];
3735 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,event_id
,event_id
,eventData
.description
.c_str(),active
);
3737 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,event_id
,eventData
.description
.c_str(),active
);
3743 SendSysMessage(LANG_NOEVENTFOUND
);
3748 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3753 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3754 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3758 uint32 event_id
= atoi(cId
);
3760 GameEventMgr::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3762 if(event_id
>=events
.size())
3764 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3765 SetSentErrorMessage(true);
3769 GameEventData
const& eventData
= events
[event_id
];
3770 if(!eventData
.isValid())
3772 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3773 SetSentErrorMessage(true);
3777 GameEventMgr::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3778 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3779 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3781 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3782 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3784 uint32 delay
= gameeventmgr
.NextCheck(event_id
);
3785 time_t nextTime
= time(NULL
)+delay
;
3786 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3788 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3789 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3791 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3792 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3797 bool ChatHandler::HandleEventStartCommand(const char* args
)
3802 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3803 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3807 int32 event_id
= atoi(cId
);
3809 GameEventMgr::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3811 if(event_id
< 1 || event_id
>=events
.size())
3813 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3814 SetSentErrorMessage(true);
3818 GameEventData
const& eventData
= events
[event_id
];
3819 if(!eventData
.isValid())
3821 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3822 SetSentErrorMessage(true);
3826 GameEventMgr::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3827 if(activeEvents
.find(event_id
) != activeEvents
.end())
3829 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3830 SetSentErrorMessage(true);
3834 gameeventmgr
.StartEvent(event_id
,true);
3838 bool ChatHandler::HandleEventStopCommand(const char* args
)
3843 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3844 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3848 int32 event_id
= atoi(cId
);
3850 GameEventMgr::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3852 if(event_id
< 1 || event_id
>=events
.size())
3854 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3855 SetSentErrorMessage(true);
3859 GameEventData
const& eventData
= events
[event_id
];
3860 if(!eventData
.isValid())
3862 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3863 SetSentErrorMessage(true);
3867 GameEventMgr::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3869 if(activeEvents
.find(event_id
) == activeEvents
.end())
3871 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3872 SetSentErrorMessage(true);
3876 gameeventmgr
.StopEvent(event_id
,true);
3880 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3883 if(!extractPlayerTarget((char*)args
,&target
))
3886 // check online security
3887 if (HasLowerSecurity(target
, 0))
3890 target
->CombatStop();
3891 target
->getHostilRefManager().deleteReferences();
3895 void ChatHandler::HandleLearnSkillRecipesHelper(Player
* player
,uint32 skill_id
)
3897 uint32 classmask
= player
->getClassMask();
3899 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3901 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3906 if( skillLine
->skillId
!= skill_id
)
3910 if(skillLine
->forward_spellid
)
3913 // skip racial skills
3914 if (skillLine
->racemask
!= 0)
3917 // skip wrong class skills
3918 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3921 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3922 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,player
,false))
3925 player
->learnSpell(skillLine
->spellId
,false);
3929 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3931 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3933 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3935 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3939 if ((skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
) &&
3940 skillInfo
->canLink
) // only prof. with recipes have
3942 HandleLearnSkillRecipesHelper(m_session
->GetPlayer(),skillInfo
->id
);
3946 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
3950 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
3952 // Learns all recipes of specified profession and sets skill to max
3953 // Example: .learn all_recipes enchanting
3955 Player
* target
= getSelectedPlayer();
3958 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3965 std::wstring wnamepart
;
3967 if(!Utf8toWStr(args
,wnamepart
))
3970 // converting string that we try to find to lower case
3971 wstrToLower( wnamepart
);
3973 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3977 SkillLineEntry
const *targetSkillInfo
= NULL
;
3978 for (uint32 i
= 1; i
< sSkillLineStore
.GetNumRows(); ++i
)
3980 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3984 if ((skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
3985 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
) ||
3986 !skillInfo
->canLink
) // only prof with recipes have set
3989 int loc
= GetSessionDbcLocale();
3990 name
= skillInfo
->name
[loc
];
3994 if (!Utf8FitTo(name
, wnamepart
))
3997 for(; loc
< MAX_LOCALE
; ++loc
)
3999 if(loc
==GetSessionDbcLocale())
4002 name
= skillInfo
->name
[loc
];
4006 if (Utf8FitTo(name
, wnamepart
))
4011 if(loc
< MAX_LOCALE
)
4013 targetSkillInfo
= skillInfo
;
4018 if(!targetSkillInfo
)
4021 HandleLearnSkillRecipesHelper(target
,targetSkillInfo
->id
);
4023 uint16 maxLevel
= target
->GetPureMaxSkillValue(targetSkillInfo
->id
);
4024 target
->SetSkill(targetSkillInfo
->id
, maxLevel
, maxLevel
);
4025 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
4029 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
4035 std::string ip
= strtok ((char*)args
, " ");
4036 char* limit_str
= strtok (NULL
, " ");
4037 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4039 loginDatabase
.escape_string (ip
);
4041 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
4043 return LookupPlayerSearchCommand (result
,limit
);
4046 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
4051 std::string account
= strtok ((char*)args
, " ");
4052 char* limit_str
= strtok (NULL
, " ");
4053 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4055 if (!AccountMgr::normalizeString (account
))
4058 loginDatabase
.escape_string (account
);
4060 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
4062 return LookupPlayerSearchCommand (result
,limit
);
4065 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
4071 std::string email
= strtok ((char*)args
, " ");
4072 char* limit_str
= strtok (NULL
, " ");
4073 int32 limit
= limit_str
? atoi (limit_str
) : -1;
4075 loginDatabase
.escape_string (email
);
4077 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
4079 return LookupPlayerSearchCommand (result
,limit
);
4082 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
4086 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4087 SetSentErrorMessage(true);
4094 Field
* fields
= result
->Fetch();
4095 uint32 acc_id
= fields
[0].GetUInt32();
4096 std::string acc_name
= fields
[1].GetCppString();
4098 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4101 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4108 Field
* charfields
= chars
->Fetch();
4109 guid
= charfields
[0].GetUInt64();
4110 name
= charfields
[1].GetCppString();
4112 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4115 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4119 } while(result
->NextRow());
4123 if(i
==0) // empty accounts only
4125 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4126 SetSentErrorMessage(true);
4133 /// Triggering corpses expire check in world
4134 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4140 bool ChatHandler::HandleRepairitemsCommand(const char* args
)
4143 if(!extractPlayerTarget((char*)args
,&target
))
4146 // check online security
4147 if (HasLowerSecurity(target
, 0))
4151 target
->DurabilityRepairAll(false, 0, false);
4153 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, GetNameLink(target
).c_str());
4154 if(needReportToTarget(target
))
4155 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetNameLink().c_str());
4159 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4164 Player
*player
= getSelectedPlayer();
4168 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4169 SetSentErrorMessage(true);
4173 // check online security
4174 if (HasLowerSecurity(player
, 0))
4177 if (strncmp(args
, "on", 3) == 0)
4178 player
->SetMovement(MOVE_WATER_WALK
); // ON
4179 else if (strncmp(args
, "off", 4) == 0)
4180 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4183 SendSysMessage(LANG_USE_BOL
);
4187 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, GetNameLink(player
).c_str());
4188 if(needReportToTarget(player
))
4189 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetNameLink().c_str());