2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
21 #include "DBCStores.h"
22 #include "ObjectMgr.h"
23 #include "ObjectGuid.h"
26 #include "GameObject.h"
29 #include "ObjectAccessor.h"
30 #include "MapManager.h"
33 #include "GameEventMgr.h"
35 #include "PoolManager.h"
36 #include "AccountMgr.h"
37 #include "GMTicketMgr.h"
38 #include "WaypointManager.h"
45 #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
47 static uint32 ReputationRankStrIndex
[MAX_REPUTATION_RANK
] =
49 LANG_REP_HATED
, LANG_REP_HOSTILE
, LANG_REP_UNFRIENDLY
, LANG_REP_NEUTRAL
,
50 LANG_REP_FRIENDLY
, LANG_REP_HONORED
, LANG_REP_REVERED
, LANG_REP_EXALTED
53 //mute player for some times
54 bool ChatHandler::HandleMuteCommand(const char* args
)
58 extractOptFirstArg((char*)args
,&nameStr
,&delayStr
);
64 std::string target_name
;
65 if(!extractPlayerTarget(nameStr
,&target
,&target_guid
,&target_name
))
68 uint32 account_id
= target
? target
->GetSession()->GetAccountId() : sObjectMgr
.GetPlayerAccountIdByGUID(target_guid
);
70 // find only player from same account if any
73 if(WorldSession
* session
= sWorld
.FindSession(account_id
))
74 target
= session
->GetPlayer();
77 uint32 notspeaktime
= (uint32
) atoi(delayStr
);
79 // must have strong lesser security level
80 if(HasLowerSecurity (target
,target_guid
,true))
83 time_t mutetime
= time(NULL
) + notspeaktime
*60;
86 target
->GetSession()->m_muteTime
= mutetime
;
88 loginDatabase
.PExecute("UPDATE account SET mutetime = " UI64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
91 ChatHandler(target
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
93 std::string nameLink
= playerLink(target_name
);
95 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, nameLink
.c_str(), notspeaktime
);
100 bool ChatHandler::HandleUnmuteCommand(const char* args
)
104 std::string target_name
;
105 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
108 uint32 account_id
= target
? target
->GetSession()->GetAccountId() : sObjectMgr
.GetPlayerAccountIdByGUID(target_guid
);
110 // find only player from same account if any
113 if(WorldSession
* session
= sWorld
.FindSession(account_id
))
114 target
= session
->GetPlayer();
117 // must have strong lesser security level
118 if(HasLowerSecurity (target
,target_guid
,true))
123 if(target
->CanSpeak())
125 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
126 SetSentErrorMessage(true);
130 target
->GetSession()->m_muteTime
= 0;
133 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
136 ChatHandler(target
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
138 std::string nameLink
= playerLink(target_name
);
140 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, nameLink
.c_str());
144 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
146 Player
* _player
= m_session
->GetPlayer();
151 char *atId
= strtok((char*)args
, " ");
155 int32 i_atId
= atoi(atId
);
160 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
163 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
164 SetSentErrorMessage(true);
168 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
170 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
171 SetSentErrorMessage(true);
175 // stop flight if need
176 if(_player
->isInFlight())
178 _player
->GetMotionMaster()->MovementExpired();
179 _player
->m_taxi
.ClearTaxiDestinations();
181 // save only in non-flight case
183 _player
->SaveRecallPosition();
185 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
189 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
191 Player
* _player
= m_session
->GetPlayer();
196 char *gyId
= strtok((char*)args
, " ");
200 int32 i_gyId
= atoi(gyId
);
205 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
208 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
209 SetSentErrorMessage(true);
213 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
215 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
216 SetSentErrorMessage(true);
220 // stop flight if need
221 if(_player
->isInFlight())
223 _player
->GetMotionMaster()->MovementExpired();
224 _player
->m_taxi
.ClearTaxiDestinations();
226 // save only in non-flight case
228 _player
->SaveRecallPosition();
230 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
234 /** \brief Teleport the GM to the specified creature
236 * .gocreature <GUID> --> TP using creature.guid
237 * .gocreature azuregos --> TP player to the mob with this name
238 * Warning: If there is more than one mob with this name
239 * you will be teleported to the first one that is found.
240 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
241 * Warning: If there is more than one mob with this "id"
242 * you will be teleported to the first one that is found.
244 //teleport to creature
245 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
249 Player
* _player
= m_session
->GetPlayer();
251 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
252 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
256 std::ostringstream whereClause
;
258 // User wants to teleport to the NPC's template entry
259 if( strcmp(pParam1
, "id") == 0 )
261 //sLog.outError("DEBUG: ID found");
263 // Get the "creature_template.entry"
264 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
265 char* tail
= strtok(NULL
,"");
268 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
272 int32 tEntry
= atoi(cId
);
273 //sLog.outError("DEBUG: ID value: %d", tEntry);
277 whereClause
<< "WHERE id = '" << tEntry
<< "'";
281 //sLog.outError("DEBUG: ID *not found*");
283 int32 guid
= atoi(pParam1
);
285 // Number is invalid - maybe the user specified the mob's name
288 std::string name
= pParam1
;
289 WorldDatabase
.escape_string(name
);
290 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
294 whereClause
<< "WHERE guid = '" << guid
<< "'";
297 //sLog.outError("DEBUG: %s", whereClause.c_str());
299 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
302 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
303 SetSentErrorMessage(true);
306 if( result
->GetRowCount() > 1 )
308 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
311 Field
*fields
= result
->Fetch();
312 float x
= fields
[0].GetFloat();
313 float y
= fields
[1].GetFloat();
314 float z
= fields
[2].GetFloat();
315 float ort
= fields
[3].GetFloat();
316 int mapid
= fields
[4].GetUInt16();
320 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
322 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
323 SetSentErrorMessage(true);
327 // stop flight if need
328 if(_player
->isInFlight())
330 _player
->GetMotionMaster()->MovementExpired();
331 _player
->m_taxi
.ClearTaxiDestinations();
333 // save only in non-flight case
335 _player
->SaveRecallPosition();
337 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
341 //teleport to gameobject
342 bool ChatHandler::HandleGoObjectCommand(const char* args
)
347 Player
* _player
= m_session
->GetPlayer();
349 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
350 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
354 int32 guid
= atoi(cId
);
362 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(guid
))
367 ort
= go_data
->orientation
;
368 mapid
= go_data
->mapid
;
372 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
373 SetSentErrorMessage(true);
377 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
379 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
380 SetSentErrorMessage(true);
384 // stop flight if need
385 if(_player
->isInFlight())
387 _player
->GetMotionMaster()->MovementExpired();
388 _player
->m_taxi
.ClearTaxiDestinations();
390 // save only in non-flight case
392 _player
->SaveRecallPosition();
394 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
398 bool ChatHandler::HandleGameObjectTargetCommand(const char* args
)
400 Player
* pl
= m_session
->GetPlayer();
402 GameEventMgr::ActiveEvents
const& activeEventsList
= sGameEventMgr
.GetActiveEventList();
405 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
406 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject_entry");
410 uint32 id
= atol(cId
);
413 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",
414 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
417 std::string name
= cId
;
418 WorldDatabase
.escape_string(name
);
419 result
= WorldDatabase
.PQuery(
420 "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_ "
421 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
422 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
427 std::ostringstream eventFilter
;
428 eventFilter
<< " AND (event IS NULL ";
429 bool initString
= true;
431 for (GameEventMgr::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
435 eventFilter
<< "OR event IN (" <<*itr
;
439 eventFilter
<< "," << *itr
;
447 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
448 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
449 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
450 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
455 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
462 uint16 mapid
, pool_id
;
466 Field
*fields
= result
->Fetch();
467 lowguid
= fields
[0].GetUInt32();
468 id
= fields
[1].GetUInt32();
469 x
= fields
[2].GetFloat();
470 y
= fields
[3].GetFloat();
471 z
= fields
[4].GetFloat();
472 o
= fields
[5].GetFloat();
473 mapid
= fields
[6].GetUInt16();
474 pool_id
= sPoolMgr
.IsPartOfAPool
<GameObject
>(lowguid
);
475 if (!pool_id
|| sPoolMgr
.IsSpawnedObject
<GameObject
>(lowguid
))
477 } while( result
->NextRow() && (!found
) );
483 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
487 GameObjectInfo
const* goI
= ObjectMgr::GetGameObjectInfo(id
);
491 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
495 GameObject
* target
= m_session
->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
497 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
501 time_t curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
502 if(curRespawnDelay
< 0)
505 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
506 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
508 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
513 //delete object by selection or guid
514 bool ChatHandler::HandleGameObjectDeleteCommand(const char* args
)
516 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
517 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
521 uint32 lowguid
= atoi(cId
);
525 GameObject
* obj
= NULL
;
528 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
529 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
533 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
534 SetSentErrorMessage(true);
538 uint64 owner_guid
= obj
->GetOwnerGUID();
541 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
542 if(!owner
|| !IS_PLAYER_GUID(owner_guid
))
544 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
545 SetSentErrorMessage(true);
549 owner
->RemoveGameObject(obj
,false);
552 obj
->SetRespawnTime(0); // not save respawn time
556 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
561 //turn selected object
562 bool ChatHandler::HandleGameObjectTurnCommand(const char* args
)
564 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
565 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
569 uint32 lowguid
= atoi(cId
);
573 GameObject
* obj
= NULL
;
576 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
577 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
581 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
582 SetSentErrorMessage(true);
586 char* po
= strtok(NULL
, " ");
595 Player
*chr
= m_session
->GetPlayer();
596 o
= chr
->GetOrientation();
599 Map
* map
= obj
->GetMap();
600 map
->Remove(obj
,false);
602 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
603 obj
->UpdateRotationFields();
610 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), obj
->GetGOInfo()->name
, obj
->GetGUIDLow());
615 //move selected object
616 bool ChatHandler::HandleGameObjectMoveCommand(const char* args
)
618 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
619 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
623 uint32 lowguid
= atoi(cId
);
627 GameObject
* obj
= NULL
;
630 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
631 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
635 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
636 SetSentErrorMessage(true);
640 char* px
= strtok(NULL
, " ");
641 char* py
= strtok(NULL
, " ");
642 char* pz
= strtok(NULL
, " ");
646 Player
*chr
= m_session
->GetPlayer();
648 Map
* map
= obj
->GetMap();
649 map
->Remove(obj
,false);
651 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
660 float x
= (float)atof(px
);
661 float y
= (float)atof(py
);
662 float z
= (float)atof(pz
);
664 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
666 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
667 SetSentErrorMessage(true);
671 Map
* map
= obj
->GetMap();
672 map
->Remove(obj
,false);
674 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
682 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow(), obj
->GetGOInfo()->name
, obj
->GetGUIDLow());
688 bool ChatHandler::HandleGameObjectAddCommand(const char* args
)
693 // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
694 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject_entry");
698 uint32 id
= atol(cId
);
702 char* spawntimeSecs
= strtok(NULL
, " ");
704 const GameObjectInfo
*gInfo
= ObjectMgr::GetGameObjectInfo(id
);
708 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
709 SetSentErrorMessage(true);
713 if (gInfo
->displayId
&& !sGameObjectDisplayInfoStore
.LookupEntry(gInfo
->displayId
))
715 // report to DB errors log as in loading case
716 sLog
.outErrorDb("Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.",id
, gInfo
->type
, gInfo
->displayId
);
717 PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA
,id
);
718 SetSentErrorMessage(true);
722 Player
*chr
= m_session
->GetPlayer();
723 float x
= float(chr
->GetPositionX());
724 float y
= float(chr
->GetPositionY());
725 float z
= float(chr
->GetPositionZ());
726 float o
= float(chr
->GetOrientation());
727 Map
*map
= chr
->GetMap();
729 GameObject
* pGameObj
= new GameObject
;
730 uint32 db_lowGUID
= sObjectMgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
732 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
))
740 uint32 value
= atoi((char*)spawntimeSecs
);
741 pGameObj
->SetRespawnTime(value
);
742 //DEBUG_LOG("*** spawntimeSecs: %d", value);
745 // fill the gameobject data and save to the db
746 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()),chr
->GetPhaseMaskForSpawn());
748 // this will generate a new guid if the object is in an instance
749 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
755 DEBUG_LOG(GetMangosString(LANG_GAMEOBJECT_CURRENT
), gInfo
->name
, db_lowGUID
, x
, y
, z
, o
);
759 // TODO: is it really necessary to add both the real and DB table guid here ?
760 sObjectMgr
.AddGameobjectToGrid(db_lowGUID
, sObjectMgr
.GetGOData(db_lowGUID
));
762 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,gInfo
->name
,db_lowGUID
,x
,y
,z
);
766 //set pahsemask for selected object
767 bool ChatHandler::HandleGameObjectPhaseCommand(const char* args
)
769 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
770 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
774 uint32 lowguid
= atoi(cId
);
778 GameObject
* obj
= NULL
;
781 if (GameObjectData
const* go_data
= sObjectMgr
.GetGOData(lowguid
))
782 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
786 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
787 SetSentErrorMessage(true);
791 char* phaseStr
= strtok (NULL
, " ");
792 uint32 phasemask
= phaseStr
? atoi(phaseStr
) : 0;
793 if ( phasemask
== 0 )
795 SendSysMessage(LANG_BAD_VALUE
);
796 SetSentErrorMessage(true);
800 obj
->SetPhaseMask(phasemask
,true);
805 bool ChatHandler::HandleGameObjectNearCommand(const char* args
)
807 float distance
= (!*args
) ? 10.0f
: (float)atof(args
);
810 Player
* pl
= m_session
->GetPlayer();
811 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid, id, position_x, position_y, position_z, map, "
812 "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
813 "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_",
814 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(),
815 pl
->GetMapId(),pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(),distance
*distance
);
821 Field
*fields
= result
->Fetch();
822 uint32 guid
= fields
[0].GetUInt32();
823 uint32 entry
= fields
[1].GetUInt32();
824 float x
= fields
[2].GetFloat();
825 float y
= fields
[3].GetFloat();
826 float z
= fields
[4].GetFloat();
827 int mapid
= fields
[5].GetUInt16();
829 GameObjectInfo
const * gInfo
= ObjectMgr::GetGameObjectInfo(entry
);
834 PSendSysMessage(LANG_GO_MIXED_LIST_CHAT
, guid
, entry
, guid
, gInfo
->name
, x
, y
, z
, mapid
);
837 } while (result
->NextRow());
842 PSendSysMessage(LANG_COMMAND_NEAROBJMESSAGE
,distance
,count
);
846 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
848 uint64 guid
= m_session
->GetPlayer()->GetSelection();
852 SendSysMessage(LANG_NO_SELECTION
);
853 SetSentErrorMessage(true);
857 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
861 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
866 // Can be NULL at console call
867 Player
*target
= getSelectedPlayer ();
869 std::string namepart
= args
;
870 std::wstring wnamepart
;
872 if (!Utf8toWStr (namepart
,wnamepart
))
875 // converting string that we try to find to lower case
876 wstrToLower (wnamepart
);
878 uint32 counter
= 0; // Counter for figure out that we found smth.
880 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
882 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
885 FactionState
const* repState
= target
? target
->GetReputationMgr().GetState(factionEntry
) : NULL
;
887 int loc
= GetSessionDbcLocale();
888 std::string name
= factionEntry
->name
[loc
];
892 if (!Utf8FitTo(name
, wnamepart
))
895 for(; loc
< MAX_LOCALE
; ++loc
)
897 if(loc
==GetSessionDbcLocale())
900 name
= factionEntry
->name
[loc
];
904 if (Utf8FitTo(name
, wnamepart
))
911 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
912 // or "id - [faction] [no reputation]" format
913 std::ostringstream ss
;
915 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
917 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
919 if (repState
) // and then target!=NULL also
921 ReputationRank rank
= target
->GetReputationMgr().GetRank(factionEntry
);
922 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
924 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputationMgr().GetReputation(factionEntry
) << ")";
926 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
927 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
928 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
929 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
930 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
931 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
932 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
933 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
934 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
935 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
936 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
937 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
940 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
942 SendSysMessage(ss
.str().c_str());
948 if (counter
== 0) // if counter == 0 then we found nth
949 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
953 bool ChatHandler::HandleModifyRepCommand(const char * args
)
955 if (!*args
) return false;
957 Player
* target
= NULL
;
958 target
= getSelectedPlayer();
962 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
963 SetSentErrorMessage(true);
967 // check online security
968 if (HasLowerSecurity(target
, 0))
971 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
975 uint32 factionId
= atoi(factionTxt
);
978 char *rankTxt
= strtok(NULL
, " ");
979 if (!factionTxt
|| !rankTxt
)
982 amount
= atoi(rankTxt
);
983 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
985 std::string rankStr
= rankTxt
;
986 std::wstring wrankStr
;
987 if(!Utf8toWStr(rankStr
,wrankStr
))
989 wstrToLower( wrankStr
);
993 for (; r
< MAX_REPUTATION_RANK
; ++r
)
995 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
1000 if(!Utf8toWStr(rank
,wrank
))
1005 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
1007 char *deltaTxt
= strtok(NULL
, " ");
1010 int32 delta
= atoi(deltaTxt
);
1011 if ((delta
< 0) || (delta
> ReputationMgr::PointsInRank
[r
] -1))
1013 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (ReputationMgr::PointsInRank
[r
]-1));
1014 SetSentErrorMessage(true);
1021 amount
+= ReputationMgr::PointsInRank
[r
];
1023 if (r
>= MAX_REPUTATION_RANK
)
1025 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
1026 SetSentErrorMessage(true);
1031 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
1035 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
1036 SetSentErrorMessage(true);
1040 if (factionEntry
->reputationListID
< 0)
1042 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[GetSessionDbcLocale()], factionId
);
1043 SetSentErrorMessage(true);
1047 target
->GetReputationMgr().SetReputation(factionEntry
,amount
);
1048 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[GetSessionDbcLocale()], factionId
,
1049 GetNameLink(target
).c_str(), target
->GetReputationMgr().GetReputation(factionEntry
));
1053 //-----------------------Npc Commands-----------------------
1054 //add spawn of creature
1055 bool ChatHandler::HandleNpcAddCommand(const char* args
)
1059 char* charID
= extractKeyFromLink((char*)args
,"Hcreature_entry");
1063 char* team
= strtok(NULL
, " ");
1065 if (team
) { teamval
= atoi(team
); }
1066 if (teamval
< 0) { teamval
= 0; }
1068 uint32 id
= atoi(charID
);
1070 Player
*chr
= m_session
->GetPlayer();
1071 float x
= chr
->GetPositionX();
1072 float y
= chr
->GetPositionY();
1073 float z
= chr
->GetPositionZ();
1074 float o
= chr
->GetOrientation();
1075 Map
*map
= chr
->GetMap();
1077 Creature
* pCreature
= new Creature
;
1078 if (!pCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, (uint32
)teamval
))
1084 pCreature
->Relocate(x
,y
,z
,o
);
1086 if(!pCreature
->IsPositionValid())
1088 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());
1093 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
1095 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
1097 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
1098 pCreature
->LoadFromDB(db_guid
, map
);
1100 map
->Add(pCreature
);
1101 sObjectMgr
.AddCreatureToGrid(db_guid
, sObjectMgr
.GetCreatureData(db_guid
));
1105 //add item in vendorlist
1106 bool ChatHandler::HandleNpcAddVendorItemCommand(const char* args
)
1111 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1114 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1115 SetSentErrorMessage(true);
1119 uint32 itemId
= atol(pitem
);
1121 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1122 uint32 maxcount
= 0;
1124 maxcount
= atol(fmaxcount
);
1126 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1127 uint32 incrtime
= 0;
1129 incrtime
= atol(fincrtime
);
1131 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1132 int32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1134 Creature
* vendor
= getSelectedCreature();
1136 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1138 if(!sObjectMgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1140 SetSentErrorMessage(true);
1144 sObjectMgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1146 ItemPrototype
const* pProto
= ObjectMgr::GetItemPrototype(itemId
);
1148 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1152 //del item from vendor list
1153 bool ChatHandler::HandleNpcDelVendorItemCommand(const char* args
)
1158 Creature
* vendor
= getSelectedCreature();
1159 if (!vendor
|| !vendor
->isVendor())
1161 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1162 SetSentErrorMessage(true);
1166 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1169 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1170 SetSentErrorMessage(true);
1173 uint32 itemId
= atol(pitem
);
1175 if(!sObjectMgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1177 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1178 SetSentErrorMessage(true);
1182 ItemPrototype
const* pProto
= ObjectMgr::GetItemPrototype(itemId
);
1184 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1188 //add move for creature
1189 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1194 char* guid_str
= strtok((char*)args
, " ");
1195 char* wait_str
= strtok((char*)NULL
, " ");
1197 uint32 lowguid
= atoi((char*)guid_str
);
1199 Creature
* pCreature
= NULL
;
1201 /* FIXME: impossible without entry
1203 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1206 // attempt check creature existence by DB data
1209 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
1212 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1213 SetSentErrorMessage(true);
1219 // obtain real GUID for DB operations
1220 lowguid
= pCreature
->GetDBTableGUIDLow();
1223 int wait
= wait_str
? atoi(wait_str
) : 0;
1228 Player
* player
= m_session
->GetPlayer();
1230 sWaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1232 // update movement type
1233 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1236 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1237 pCreature
->GetMotionMaster()->Initialize();
1238 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1240 pCreature
->setDeathState(JUST_DIED
);
1241 pCreature
->Respawn();
1243 pCreature
->SaveToDB();
1246 SendSysMessage(LANG_WAYPOINT_ADDED
);
1251 //change level of creature or pet
1252 bool ChatHandler::HandleNpcChangeLevelCommand(const char* args
)
1257 uint8 lvl
= (uint8
) atoi((char*)args
);
1258 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL
) + 3)
1260 SendSysMessage(LANG_BAD_VALUE
);
1261 SetSentErrorMessage(true);
1265 Creature
* pCreature
= getSelectedCreature();
1268 SendSysMessage(LANG_SELECT_CREATURE
);
1269 SetSentErrorMessage(true);
1273 if(pCreature
->isPet())
1275 if(((Pet
*)pCreature
)->getPetType()==HUNTER_PET
)
1277 pCreature
->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP
, sObjectMgr
.GetXPForPetLevel(lvl
));
1278 pCreature
->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE
, 0);
1280 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1284 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1285 pCreature
->SetHealth( 100 + 30*lvl
);
1286 pCreature
->SetLevel( lvl
);
1287 pCreature
->SaveToDB();
1293 //set npcflag of creature
1294 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1299 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1301 Creature
* pCreature
= getSelectedCreature();
1305 SendSysMessage(LANG_SELECT_CREATURE
);
1306 SetSentErrorMessage(true);
1310 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1312 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1314 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1319 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
1321 Creature
* unit
= NULL
;
1325 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1326 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1330 uint32 lowguid
= atoi(cId
);
1334 if (CreatureData
const* cr_data
= sObjectMgr
.GetCreatureData(lowguid
))
1335 unit
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
1338 unit
= getSelectedCreature();
1340 if(!unit
|| unit
->isPet() || unit
->isTotem() || unit
->isVehicle())
1342 SendSysMessage(LANG_SELECT_CREATURE
);
1343 SetSentErrorMessage(true);
1347 // Delete the creature
1349 unit
->DeleteFromDB();
1350 unit
->AddObjectToRemoveList();
1352 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
1357 //move selected creature
1358 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1362 Creature
* pCreature
= getSelectedCreature();
1366 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1367 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1371 lowguid
= atoi(cId
);
1373 /* FIXME: impossibel without entry
1375 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1378 // Attempting creature load from DB data
1381 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
1384 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1385 SetSentErrorMessage(true);
1389 uint32 map_id
= data
->mapid
;
1391 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1393 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1394 SetSentErrorMessage(true);
1400 lowguid
= pCreature
->GetDBTableGUIDLow();
1405 lowguid
= pCreature
->GetDBTableGUIDLow();
1408 float x
= m_session
->GetPlayer()->GetPositionX();
1409 float y
= m_session
->GetPlayer()->GetPositionY();
1410 float z
= m_session
->GetPlayer()->GetPositionZ();
1411 float o
= m_session
->GetPlayer()->GetOrientation();
1415 if(CreatureData
const* data
= sObjectMgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1417 const_cast<CreatureData
*>(data
)->posX
= x
;
1418 const_cast<CreatureData
*>(data
)->posY
= y
;
1419 const_cast<CreatureData
*>(data
)->posZ
= z
;
1420 const_cast<CreatureData
*>(data
)->orientation
= o
;
1422 pCreature
->GetMap()->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1423 pCreature
->GetMotionMaster()->Initialize();
1424 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1426 pCreature
->setDeathState(JUST_DIED
);
1427 pCreature
->Respawn();
1431 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1432 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1436 /**HandleNpcSetMoveTypeCommand
1437 * Set the movement type for an NPC.<br/>
1439 * Valid movement types are:
1441 * <li> stay - NPC wont move </li>
1442 * <li> random - NPC will move randomly according to the spawndist </li>
1443 * <li> way - NPC will move with given waypoints set </li>
1445 * additional parameter: NODEL - so no waypoints are deleted, if you
1446 * change the movement type
1448 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1454 // GUID (optional - you can also select the creature)
1455 // stay|random|way (determines the kind of movement)
1456 // NODEL (optional - tells the system NOT to delete any waypoints)
1457 // this is very handy if you want to do waypoints, that are
1458 // later switched on/off according to special events (like escort
1460 char* guid_str
= strtok((char*)args
, " ");
1461 char* type_str
= strtok((char*)NULL
, " ");
1462 char* dontdel_str
= strtok((char*)NULL
, " ");
1464 bool doNotDelete
= false;
1470 Creature
* pCreature
= NULL
;
1474 //sLog.outError("DEBUG: All 3 params are set");
1476 // All 3 params are set
1480 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1482 //sLog.outError("DEBUG: doNotDelete = true;");
1488 // Only 2 params - but maybe NODEL is set
1491 sLog
.outError("DEBUG: Only 2 params ");
1492 if( stricmp( type_str
, "NODEL" ) == 0 )
1494 //sLog.outError("DEBUG: type_str, NODEL ");
1501 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1503 type_str
= guid_str
;
1504 pCreature
= getSelectedCreature();
1505 if(!pCreature
|| pCreature
->isPet())
1507 lowguid
= pCreature
->GetDBTableGUIDLow();
1509 else // case .setmovetype #creature_guid $move_type (with selected creature)
1511 lowguid
= atoi((char*)guid_str
);
1513 /* impossible without entry
1515 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1518 // attempt check creature existence by DB data
1521 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
1524 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1525 SetSentErrorMessage(true);
1531 lowguid
= pCreature
->GetDBTableGUIDLow();
1535 // now lowguid is low guid really existed creature
1536 // and pCreature point (maybe) to this creature or NULL
1538 MovementGeneratorType move_type
;
1540 std::string type
= type_str
;
1543 move_type
= IDLE_MOTION_TYPE
;
1544 else if(type
== "random")
1545 move_type
= RANDOM_MOTION_TYPE
;
1546 else if(type
== "way")
1547 move_type
= WAYPOINT_MOTION_TYPE
;
1551 // update movement type
1552 if(doNotDelete
== false)
1553 sWaypointMgr
.DeletePath(lowguid
);
1557 pCreature
->SetDefaultMovementType(move_type
);
1558 pCreature
->GetMotionMaster()->Initialize();
1559 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1561 pCreature
->setDeathState(JUST_DIED
);
1562 pCreature
->Respawn();
1564 pCreature
->SaveToDB();
1566 if( doNotDelete
== false )
1568 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1572 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1578 //set model of creature
1579 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1584 uint32 displayId
= (uint32
) atoi((char*)args
);
1586 Creature
*pCreature
= getSelectedCreature();
1588 if(!pCreature
|| pCreature
->isPet())
1590 SendSysMessage(LANG_SELECT_CREATURE
);
1591 SetSentErrorMessage(true);
1595 pCreature
->SetDisplayId(displayId
);
1596 pCreature
->SetNativeDisplayId(displayId
);
1598 pCreature
->SaveToDB();
1602 //set faction of creature
1603 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1608 uint32 factionId
= (uint32
) atoi((char*)args
);
1610 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1612 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1613 SetSentErrorMessage(true);
1617 Creature
* pCreature
= getSelectedCreature();
1621 SendSysMessage(LANG_SELECT_CREATURE
);
1622 SetSentErrorMessage(true);
1626 pCreature
->setFaction(factionId
);
1628 // faction is set in creature_template - not inside creature
1631 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1633 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1634 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1638 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1642 //set spawn dist of creature
1643 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
1648 float option
= (float)atof((char*)args
);
1651 SendSysMessage(LANG_BAD_VALUE
);
1655 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
1657 mtype
= RANDOM_MOTION_TYPE
;
1659 Creature
*pCreature
= getSelectedCreature();
1660 uint32 u_guidlow
= 0;
1663 u_guidlow
= pCreature
->GetDBTableGUIDLow();
1667 pCreature
->SetRespawnRadius((float)option
);
1668 pCreature
->SetDefaultMovementType(mtype
);
1669 pCreature
->GetMotionMaster()->Initialize();
1670 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1672 pCreature
->setDeathState(JUST_DIED
);
1673 pCreature
->Respawn();
1676 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
1677 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
1680 //spawn time handling
1681 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
1686 char* stime
= strtok((char*)args
, " ");
1691 int i_stime
= atoi((char*)stime
);
1695 SendSysMessage(LANG_BAD_VALUE
);
1696 SetSentErrorMessage(true);
1700 Creature
*pCreature
= getSelectedCreature();
1701 uint32 u_guidlow
= 0;
1704 u_guidlow
= pCreature
->GetDBTableGUIDLow();
1708 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
1709 pCreature
->SetRespawnDelay((uint32
)i_stime
);
1710 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
1714 //npc follow handling
1715 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
1717 Player
*player
= m_session
->GetPlayer();
1718 Creature
*creature
= getSelectedCreature();
1722 PSendSysMessage(LANG_SELECT_CREATURE
);
1723 SetSentErrorMessage(true);
1727 // Follow player - Using pet's default dist and angle
1728 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
1730 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
1733 //npc unfollow handling
1734 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
1736 Player
*player
= m_session
->GetPlayer();
1737 Creature
*creature
= getSelectedCreature();
1741 PSendSysMessage(LANG_SELECT_CREATURE
);
1742 SetSentErrorMessage(true);
1746 if (creature
->GetMotionMaster()->empty() ||
1747 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=FOLLOW_MOTION_TYPE
)
1749 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
1750 SetSentErrorMessage(true);
1754 FollowMovementGenerator
<Creature
> const* mgen
1755 = static_cast<FollowMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
1757 if(mgen
->GetTarget()!=player
)
1759 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
1760 SetSentErrorMessage(true);
1765 creature
->GetMotionMaster()->MovementExpired(true);
1767 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
1771 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
1773 Creature
*creatureTarget
= getSelectedCreature ();
1774 if (!creatureTarget
|| creatureTarget
->isPet ())
1776 PSendSysMessage (LANG_SELECT_CREATURE
);
1777 SetSentErrorMessage (true);
1781 Player
*player
= m_session
->GetPlayer ();
1783 if(player
->GetPetGUID ())
1785 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
1786 SetSentErrorMessage (true);
1790 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
1792 if (!cInfo
->isTameable (player
->CanTameExoticPets()))
1794 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
1795 SetSentErrorMessage (true);
1799 // Everything looks OK, create new pet
1800 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
1803 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
1804 SetSentErrorMessage (true);
1808 // place pet before player
1810 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
1811 pet
->Relocate (x
,y
,z
,M_PI_F
-player
->GetOrientation ());
1813 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
1814 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
1816 // calculate proper level
1817 uint32 level
= (creatureTarget
->getLevel() < (player
->getLevel() - 5)) ? (player
->getLevel() - 5) : creatureTarget
->getLevel();
1819 // prepare visual effect for levelup
1820 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
- 1);
1823 pet
->GetMap()->Add((Creature
*)pet
);
1825 // visual effect for levelup
1826 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
);
1828 // caster have pet now
1829 player
->SetPet(pet
);
1831 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
1832 player
->PetSpellInitialize();
1836 //npc phasemask handling
1837 //change phasemask of creature or pet
1838 bool ChatHandler::HandleNpcSetPhaseCommand(const char* args
)
1843 uint32 phasemask
= (uint32
) atoi((char*)args
);
1844 if ( phasemask
== 0 )
1846 SendSysMessage(LANG_BAD_VALUE
);
1847 SetSentErrorMessage(true);
1851 Creature
* pCreature
= getSelectedCreature();
1854 SendSysMessage(LANG_SELECT_CREATURE
);
1855 SetSentErrorMessage(true);
1859 pCreature
->SetPhaseMask(phasemask
,true);
1861 if(!pCreature
->isPet())
1862 pCreature
->SaveToDB();
1866 //npc deathstate handling
1867 bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args
)
1872 Creature
* pCreature
= getSelectedCreature();
1873 if(!pCreature
|| pCreature
->isPet())
1875 SendSysMessage(LANG_SELECT_CREATURE
);
1876 SetSentErrorMessage(true);
1880 if (strncmp(args
, "on", 3) == 0)
1881 pCreature
->SetDeadByDefault(true);
1882 else if (strncmp(args
, "off", 4) == 0)
1883 pCreature
->SetDeadByDefault(false);
1886 SendSysMessage(LANG_USE_BOL
);
1887 SetSentErrorMessage(true);
1891 pCreature
->SaveToDB();
1892 pCreature
->Respawn();
1897 //TODO: NpcCommands that need to be fixed :
1899 bool ChatHandler::HandleNpcNameCommand(const char* /*args*/)
1905 if(strlen((char*)args)>75)
1907 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
1911 for (uint8 i = 0; i < strlen(args); ++i)
1913 if(!isalpha(args[i]) && args[i]!=' ')
1915 SendSysMessage(LANG_CHARS_ONLY);
1921 guid = m_session->GetPlayer()->GetSelection();
1924 SendSysMessage(LANG_NO_SELECTION);
1928 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1932 SendSysMessage(LANG_SELECT_CREATURE);
1936 pCreature->SetName(args);
1937 uint32 idname = sObjectMgr.AddCreatureTemplate(pCreature->GetName());
1938 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1940 pCreature->SaveToDB();
1946 bool ChatHandler::HandleNpcSubNameCommand(const char* /*args*/)
1953 if(strlen((char*)args)>75)
1956 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
1960 for (uint8 i = 0; i < strlen(args); i++)
1962 if(!isalpha(args[i]) && args[i]!=' ')
1964 SendSysMessage(LANG_CHARS_ONLY);
1969 guid = m_session->GetPlayer()->GetSelection();
1972 SendSysMessage(LANG_NO_SELECTION);
1976 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
1980 SendSysMessage(LANG_SELECT_CREATURE);
1984 uint32 idname = sObjectMgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
1985 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
1987 pCreature->SaveToDB();
1992 //move item to other slot
1993 bool ChatHandler::HandleItemMoveCommand(const char* args
)
1997 uint8 srcslot
, dstslot
;
1999 char* pParam1
= strtok((char*)args
, " ");
2003 char* pParam2
= strtok(NULL
, " ");
2007 srcslot
= (uint8
)atoi(pParam1
);
2008 dstslot
= (uint8
)atoi(pParam2
);
2010 if(srcslot
==dstslot
)
2013 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
, srcslot
, true))
2016 // can be autostore pos
2017 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
, false))
2020 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
2021 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
2023 m_session
->GetPlayer()->SwapItem( src
, dst
);
2028 //demorph player or unit
2029 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
2031 Unit
*target
= getSelectedUnit();
2033 target
= m_session
->GetPlayer();
2036 // check online security
2037 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2045 //morph creature or player
2046 bool ChatHandler::HandleModifyMorphCommand(const char* args
)
2051 uint16 display_id
= (uint16
)atoi((char*)args
);
2053 Unit
*target
= getSelectedUnit();
2055 target
= m_session
->GetPlayer();
2057 // check online security
2058 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2061 target
->SetDisplayId(display_id
);
2067 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
2070 if(!extractPlayerTarget((char*)args
,&target
))
2073 if (m_session
&& target
==m_session
->GetPlayer())
2075 SendSysMessage(LANG_COMMAND_KICKSELF
);
2076 SetSentErrorMessage(true);
2080 // check online security
2081 if (HasLowerSecurity(target
, 0))
2084 // send before target pointer invalidate
2085 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,GetNameLink(target
).c_str());
2086 target
->GetSession()->KickPlayer();
2090 //set temporary phase mask for player
2091 bool ChatHandler::HandleModifyPhaseCommand(const char* args
)
2096 uint32 phasemask
= (uint32
)atoi((char*)args
);
2098 Unit
*target
= getSelectedUnit();
2100 target
= m_session
->GetPlayer();
2102 // check online security
2103 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
2106 target
->SetPhaseMask(phasemask
,true);
2111 //show info of player
2112 bool ChatHandler::HandlePInfoCommand(const char* args
)
2116 std::string target_name
;
2117 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
2122 uint32 total_player_time
= 0;
2126 // get additional information from Player object
2129 // check online security
2130 if (HasLowerSecurity(target
, 0))
2133 accId
= target
->GetSession()->GetAccountId();
2134 money
= target
->GetMoney();
2135 total_player_time
= target
->GetTotalPlayedTime();
2136 level
= target
->getLevel();
2137 latency
= target
->GetSession()->GetLatency();
2139 // get additional information from DB
2142 // check offline security
2143 if (HasLowerSecurity(NULL
, target_guid
))
2147 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime, level, money, account FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid
));
2151 Field
*fields
= result
->Fetch();
2152 total_player_time
= fields
[0].GetUInt32();
2153 level
= fields
[1].GetUInt32();
2154 money
= fields
[2].GetUInt32();
2155 accId
= fields
[3].GetUInt32();
2159 std::string username
= GetMangosString(LANG_ERROR
);
2160 std::string last_ip
= GetMangosString(LANG_ERROR
);
2161 AccountTypes security
= SEC_PLAYER
;
2162 std::string last_login
= GetMangosString(LANG_ERROR
);
2164 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
2167 Field
* fields
= result
->Fetch();
2168 username
= fields
[0].GetCppString();
2169 security
= (AccountTypes
)fields
[1].GetUInt32();
2171 if(GetAccessLevel() >= security
)
2173 last_ip
= fields
[2].GetCppString();
2174 last_login
= fields
[3].GetCppString();
2185 std::string nameLink
= playerLink(target_name
);
2187 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
);
2189 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
2190 uint32 gold
= money
/GOLD
;
2191 uint32 silv
= (money
% GOLD
) / SILVER
;
2192 uint32 copp
= (money
% GOLD
) % SILVER
;
2193 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
2199 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
2202 if(!sObjectMgr
.GetPlayerNameByGUID(guid
,name
))
2203 name
= GetMangosString(LANG_UNKNOWN
);
2205 std::string nameLink
= playerLink(name
);
2207 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, nameLink
.c_str(),time
,text
);
2211 bool ChatHandler::HandleTicketCommand(const char* args
)
2213 char* px
= strtok((char*)args
, " ");
2220 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2221 SetSentErrorMessage(true);
2225 size_t count
= sTicketMgr
.GetTicketCount();
2227 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
2229 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
2234 if(strncmp(px
,"on",3) == 0)
2238 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2239 SetSentErrorMessage(true);
2243 m_session
->GetPlayer()->SetAcceptTicket(true);
2244 SendSysMessage(LANG_COMMAND_TICKETON
);
2249 if(strncmp(px
,"off",4) == 0)
2253 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2254 SetSentErrorMessage(true);
2258 m_session
->GetPlayer()->SetAcceptTicket(false);
2259 SendSysMessage(LANG_COMMAND_TICKETOFF
);
2264 if(strncmp(px
,"respond",8) == 0)
2266 char *name
= strtok(NULL
, " ");
2270 SendSysMessage(LANG_CMD_SYNTAX
);
2271 SetSentErrorMessage(true);
2275 std::string plName
= name
;
2276 uint64 guid
= sObjectMgr
.GetPlayerGUIDByName(plName
);
2280 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2281 SetSentErrorMessage(true);
2285 GMTicket
* ticket
= sTicketMgr
.GetGMTicket(GUID_LOPART(guid
));
2289 PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST
, GUID_LOPART(guid
));
2290 SetSentErrorMessage(true);
2294 char* response
= strtok(NULL
, "");
2298 SendSysMessage(LANG_CMD_SYNTAX
);
2299 SetSentErrorMessage(true);
2303 ticket
->SetResponseText(response
);
2305 if(Player
* pl
= sObjectMgr
.GetPlayer(guid
))
2306 pl
->GetSession()->SendGMResponse(ticket
);
2315 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
2319 PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST
, num
);
2320 SetSentErrorMessage(true);
2324 Field
* fields
= result
->Fetch();
2326 uint32 guid
= fields
[0].GetUInt32();
2327 char const* text
= fields
[1].GetString();
2328 char const* time
= fields
[2].GetString();
2330 ShowTicket(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
),text
,time
);
2336 if(!extractPlayerTarget(px
,NULL
,&target_guid
))
2339 // ticket $char_name
2340 GMTicket
* ticket
= sTicketMgr
.GetGMTicket(GUID_LOPART(target_guid
));
2344 std::string time
= TimeToTimestampStr(ticket
->GetLastUpdate());
2346 ShowTicket(target_guid
, ticket
->GetText(), time
.c_str());
2352 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2354 char* px
= strtok((char*)args
, " ");
2359 if(strncmp(px
,"all",4) == 0)
2361 sTicketMgr
.DeleteAll();
2362 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2366 int num
= (uint32
)atoi(px
);
2371 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2374 PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST
, num
);
2375 SetSentErrorMessage(true);
2378 Field
* fields
= result
->Fetch();
2379 uint32 guid
= fields
[0].GetUInt32();
2382 sTicketMgr
.Delete(guid
);
2385 if(Player
* pl
= sObjectMgr
.GetPlayer(ObjectGuid(HIGHGUID_PLAYER
, guid
)))
2387 pl
->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2388 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
, GetNameLink(pl
).c_str());
2391 PSendSysMessage(LANG_COMMAND_TICKETDEL
);
2398 std::string target_name
;
2399 if(!extractPlayerTarget(px
,&target
,&target_guid
,&target_name
))
2402 // delticket $char_name
2403 sTicketMgr
.Delete(GUID_LOPART(target_guid
));
2405 // notify players about ticket deleting
2407 target
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2409 std::string nameLink
= playerLink(target_name
);
2411 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,nameLink
.c_str());
2416 * Add a waypoint to a creature.
2418 * The user can either select an npc or provide its GUID.
2420 * The user can even select a visual waypoint - then the new waypoint
2421 * is placed *after* the selected one - this makes insertion of new
2422 * waypoints possible.
2426 * -> adds a waypoint to the npc with the GUID 12345
2429 * -> adds a waypoint to the currently selected creature
2432 * @param args if the user did not provide a GUID, it is NULL
2434 * @return true - command did succeed, false - something went wrong
2436 bool ChatHandler::HandleWpAddCommand(const char* args
)
2438 DEBUG_LOG("DEBUG: HandleWpAddCommand");
2441 char* guid_str
= NULL
;
2445 guid_str
= strtok((char*)args
, " ");
2450 Creature
* target
= getSelectedCreature();
2451 // Did player provide a GUID?
2454 DEBUG_LOG("DEBUG: HandleWpAddCommand - No GUID provided");
2457 // -> Player must have selected a creature
2459 if(!target
|| target
->isPet())
2461 SendSysMessage(LANG_SELECT_CREATURE
);
2462 SetSentErrorMessage(true);
2465 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2467 DEBUG_LOG("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2469 QueryResult
*result
=
2470 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2471 target
->GetGUIDLow() );
2474 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2475 // User selected a visual spawnpoint -> get the NPC
2477 // Since we compare float values, we have to deal with
2478 // some difficulties.
2479 // Here we search for all waypoints that only differ in one from 1 thousand
2480 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2481 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2482 const char* maxDIFF
= "0.01";
2483 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 )",
2484 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2487 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2488 SetSentErrorMessage(true);
2494 Field
*fields
= result
->Fetch();
2495 lowguid
= fields
[0].GetUInt32();
2496 point
= fields
[1].GetUInt32();
2497 }while( result
->NextRow() );
2500 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2503 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2504 SetSentErrorMessage(true);
2508 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2511 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2512 SetSentErrorMessage(true);
2518 lowguid
= target
->GetDBTableGUIDLow();
2523 DEBUG_LOG("DEBUG: HandleWpAddCommand - GUID provided");
2526 // Warn if player also selected a creature
2527 // -> Creature selection is ignored <-
2530 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2532 lowguid
= atoi((char*)guid_str
);
2534 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2537 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2538 SetSentErrorMessage(true);
2542 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2543 if(!target
|| target
->isPet())
2545 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2546 SetSentErrorMessage(true);
2550 // lowguid -> GUID of the NPC
2551 // point -> number of the waypoint (if not 0)
2552 DEBUG_LOG("DEBUG: HandleWpAddCommand - danach");
2554 DEBUG_LOG("DEBUG: HandleWpAddCommand - point == 0");
2556 Player
* player
= m_session
->GetPlayer();
2557 sWaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2559 // update movement type
2562 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2563 target
->GetMotionMaster()->Initialize();
2564 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2566 target
->setDeathState(JUST_DIED
);
2572 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2574 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2577 } // HandleWpAddCommand
2580 * .wp modify emote | spell | text | del | move | add
2582 * add -> add a WP after the selected visual waypoint
2583 * User must select a visual waypoint and then issue ".wp modify add"
2586 * User has selected a visual waypoint before.
2587 * <emoteID> is added to this waypoint. Everytime the
2588 * NPC comes to this waypoint, the emote is called.
2590 * emote <GUID> <WPNUM> <emoteID>
2591 * User has not selected visual waypoint before.
2592 * For the waypoint <WPNUM> for the NPC with <GUID>
2593 * an emote <emoteID> is added.
2594 * Everytime the NPC comes to this waypoint, the emote is called.
2597 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2599 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2601 DEBUG_LOG("DEBUG: HandleWpModifyCommand");
2606 // first arg: add del text emote spell waittime move
2607 char* show_str
= strtok((char*)args
, " ");
2613 std::string show
= show_str
;
2615 // Remember: "show" must also be the name of a column!
2616 if( (show
!= "emote") && (show
!= "spell") && (show
!= "textid1") && (show
!= "textid2")
2617 && (show
!= "textid3") && (show
!= "textid4") && (show
!= "textid5")
2618 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2619 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2624 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2626 // Did user provide a GUID
2627 // or did the user select a creature?
2628 // -> variable lowguid is filled with the GUID of the NPC
2632 Creature
* target
= getSelectedCreature();
2636 DEBUG_LOG("DEBUG: HandleWpModifyCommand - User did select an NPC");
2638 // Did the user select a visual spawnpoint?
2639 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2641 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2642 SetSentErrorMessage(true);
2646 wpGuid
= target
->GetGUIDLow();
2648 // The visual waypoint
2649 QueryResult
*result
=
2650 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2651 target
->GetGUIDLow() );
2654 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2655 SetSentErrorMessage(true);
2658 DEBUG_LOG("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2660 Field
*fields
= result
->Fetch();
2661 lowguid
= fields
[0].GetUInt32();
2662 point
= fields
[1].GetUInt32();
2665 DEBUG_LOG("DEBUG: HandleWpModifyCommand - Cleanup memory");
2670 // User did provide <GUID> <WPNUM>
2672 char* guid_str
= strtok((char*)NULL
, " ");
2675 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2678 lowguid
= atoi((char*)guid_str
);
2680 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2683 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2684 SetSentErrorMessage(true);
2688 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2690 char* point_str
= strtok((char*)NULL
, " ");
2693 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2696 point
= atoi((char*)point_str
);
2698 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2700 // Now we need the GUID of the visual waypoint
2701 // -> "del", "move", "add" command
2703 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2706 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2707 SetSentErrorMessage(true);
2711 Field
*fields
= result
->Fetch();
2712 wpGuid
= fields
[0].GetUInt32();
2718 char* arg_str
= NULL
;
2719 // Check for argument
2720 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2722 // Text is enclosed in "<>", all other arguments not
2723 if( show
.find("text") != std::string::npos
)
2724 arg_str
= strtok((char*)NULL
, "<>");
2726 arg_str
= strtok((char*)NULL
, " ");
2730 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2735 DEBUG_LOG("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2737 // wpGuid -> GUID of the waypoint creature
2738 // lowguid -> GUID of the NPC
2739 // point -> waypoint number
2741 // Special functions:
2742 // add - move - del -> no args commands
2743 // Add a waypoint after the selected visual
2744 if(show
== "add" && target
)
2746 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2748 // Get the creature for which we read the waypoint
2749 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2752 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2753 SetSentErrorMessage(true);
2757 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2761 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2762 SetSentErrorMessage(true);
2766 DEBUG_LOG("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2769 // Add the visual spawnpoint (DB only)
2770 // Adjust the waypoints
2771 // Respawn the owner of the waypoints
2772 DEBUG_LOG("DEBUG: HandleWpModifyCommand - add");
2774 Player
* chr
= m_session
->GetPlayer();
2775 Map
*map
= chr
->GetMap();
2779 npcCreature
->GetMotionMaster()->Initialize();
2780 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2782 npcCreature
->setDeathState(JUST_DIED
);
2783 npcCreature
->Respawn();
2787 // create the waypoint creature
2789 Creature
* wpCreature
= new Creature
;
2790 if (!wpCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
,0))
2792 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2797 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2799 if(!wpCreature
->IsPositionValid())
2801 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());
2806 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2807 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2808 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2809 map
->Add(wpCreature
);
2810 wpGuid
= wpCreature
->GetGUIDLow();
2814 sWaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2819 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2823 if(show
== "del" && target
)
2825 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2827 // Get the creature for which we read the waypoint
2828 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2831 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2832 SetSentErrorMessage(true);
2836 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2839 Creature
* wpCreature
= NULL
;
2842 wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2843 wpCreature
->DeleteFromDB();
2844 wpCreature
->AddObjectToRemoveList();
2848 // Remove the visual spawnpoint
2849 // Adjust the waypoints
2850 // Respawn the owner of the waypoints
2852 sWaypointMgr
.DeleteNode(lowguid
, point
);
2856 // Any waypoints left?
2857 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2860 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2864 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2867 npcCreature
->GetMotionMaster()->Initialize();
2868 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2870 npcCreature
->setDeathState(JUST_DIED
);
2871 npcCreature
->Respawn();
2873 npcCreature
->SaveToDB();
2876 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2880 if(show
== "move" && target
)
2882 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2884 Player
*chr
= m_session
->GetPlayer();
2885 Map
*map
= chr
->GetMap();
2887 // Get the creature for which we read the waypoint
2888 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2891 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2892 SetSentErrorMessage(true);
2896 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2899 Creature
* wpCreature
= NULL
;
2901 // Move the visual spawnpoint
2902 // Respawn the owner of the waypoints
2905 wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2906 wpCreature
->DeleteFromDB();
2907 wpCreature
->AddObjectToRemoveList();
2909 Creature
* wpCreature2
= new Creature
;
2910 if (!wpCreature2
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
, 0))
2912 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2917 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2919 if(!wpCreature2
->IsPositionValid())
2921 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());
2926 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2927 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2928 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2929 map
->Add(wpCreature2
);
2930 //npcCreature->GetMap()->Add(wpCreature2);
2933 sWaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2937 npcCreature
->GetMotionMaster()->Initialize();
2938 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2940 npcCreature
->setDeathState(JUST_DIED
);
2941 npcCreature
->Respawn();
2944 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2949 // Create creature - npc that has the waypoint
2950 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
2953 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2954 SetSentErrorMessage(true);
2958 // set in game textids not supported
2959 if( show
== "textid1" || show
== "textid2" || show
== "textid3" ||
2960 show
== "textid4" || show
== "textid5" )
2965 sWaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2967 Creature
* npcCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2970 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2971 npcCreature
->GetMotionMaster()->Initialize();
2972 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2974 npcCreature
->setDeathState(JUST_DIED
);
2975 npcCreature
->Respawn();
2978 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2984 * .wp show info | on | off
2986 * info -> User has selected a visual waypoint before
2988 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2989 * provided the GUID of the NPC and the number of
2992 * on -> User has selected an NPC; all visual waypoints for this
2993 * NPC are added to the world
2995 * on <GUID> -> User did not select an NPC - instead the GUID of the
2996 * NPC is provided. All visual waypoints for this NPC
2997 * are added from the world.
2999 * off -> User has selected an NPC; all visual waypoints for this
3000 * NPC are removed from the world.
3002 * on <GUID> -> User did not select an NPC - instead the GUID of the
3003 * NPC is provided. All visual waypoints for this NPC
3004 * are removed from the world.
3008 bool ChatHandler::HandleWpShowCommand(const char* args
)
3010 DEBUG_LOG("DEBUG: HandleWpShowCommand");
3015 // first arg: on, off, first, last
3016 char* show_str
= strtok((char*)args
, " ");
3021 // second arg: GUID (optional, if a creature is selected)
3022 char* guid_str
= strtok((char*)NULL
, " ");
3023 DEBUG_LOG("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
3028 // Did user provide a GUID
3029 // or did the user select a creature?
3030 // -> variable lowguid is filled with the GUID
3031 Creature
* target
= getSelectedCreature();
3032 // Did player provide a GUID?
3035 DEBUG_LOG("DEBUG: HandleWpShowCommand: !guid_str");
3037 // -> Player must have selected a creature
3041 SendSysMessage(LANG_SELECT_CREATURE
);
3042 SetSentErrorMessage(true);
3048 DEBUG_LOG("DEBUG: HandleWpShowCommand: GUID provided");
3050 // Warn if player also selected a creature
3051 // -> Creature selection is ignored <-
3054 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
3057 uint32 lowguid
= atoi((char*)guid_str
);
3059 CreatureData
const* data
= sObjectMgr
.GetCreatureData(lowguid
);
3062 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
3063 SetSentErrorMessage(true);
3067 target
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
3071 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
3072 SetSentErrorMessage(true);
3077 uint32 lowguid
= target
->GetDBTableGUIDLow();
3079 std::string show
= show_str
;
3082 DEBUG_LOG("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
3084 // Show info for the selected waypoint
3087 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
3089 // Check if the user did specify a visual waypoint
3090 if( target
->GetEntry() != VISUAL_WAYPOINT
)
3092 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
3093 SetSentErrorMessage(true);
3097 //PSendSysMessage("wp on, GUID: %u", lowguid);
3099 //pCreature->GetPositionX();
3101 QueryResult
*result
=
3102 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
3103 target
->GetGUIDLow() );
3106 // Since we compare float values, we have to deal with
3107 // some difficulties.
3108 // Here we search for all waypoints that only differ in one from 1 thousand
3109 // (0.001) - There is no other way to compare C++ floats with mySQL floats
3110 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
3111 const char* maxDIFF
= "0.01";
3112 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
3114 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 )",
3115 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
3118 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
3119 SetSentErrorMessage(true);
3125 Field
*fields
= result
->Fetch();
3126 uint32 creGUID
= fields
[0].GetUInt32();
3127 uint32 point
= fields
[1].GetUInt32();
3128 int waittime
= fields
[2].GetUInt32();
3129 uint32 emote
= fields
[3].GetUInt32();
3130 uint32 spell
= fields
[4].GetUInt32();
3131 uint32 textid
[MAX_WAYPOINT_TEXT
];
3132 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
3133 textid
[i
] = fields
[5+i
].GetUInt32();
3134 uint32 model1
= fields
[10].GetUInt32();
3135 uint32 model2
= fields
[11].GetUInt32();
3137 // Get the creature for which we read the waypoint
3138 Creature
* wpCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3140 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
3141 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
3142 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
3143 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
3144 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
3145 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
3146 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
3147 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, i
+1, textid
[i
], (textid
[i
] ? GetMangosString(textid
[i
]) : ""));
3149 }while( result
->NextRow() );
3157 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
3159 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
3162 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3163 SetSentErrorMessage(true);
3166 // Delete all visuals for this NPC
3167 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
3170 bool hasError
= false;
3173 Field
*fields
= result2
->Fetch();
3174 uint32 wpguid
= fields
[0].GetUInt32();
3175 Creature
* pCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3179 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
3181 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
3185 pCreature
->DeleteFromDB();
3186 pCreature
->AddObjectToRemoveList();
3189 }while( result2
->NextRow() );
3193 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3194 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3195 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3201 Field
*fields
= result
->Fetch();
3202 uint32 point
= fields
[0].GetUInt32();
3203 float x
= fields
[1].GetFloat();
3204 float y
= fields
[2].GetFloat();
3205 float z
= fields
[3].GetFloat();
3207 uint32 id
= VISUAL_WAYPOINT
;
3209 Player
*chr
= m_session
->GetPlayer();
3210 Map
*map
= chr
->GetMap();
3211 float o
= chr
->GetOrientation();
3213 Creature
* wpCreature
= new Creature
;
3214 if (!wpCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3216 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3222 wpCreature
->Relocate(x
, y
, z
, o
);
3224 if(!wpCreature
->IsPositionValid())
3226 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());
3232 wpCreature
->SetVisibility(VISIBILITY_OFF
);
3233 DEBUG_LOG("DEBUG: UPDATE creature_movement SET wpguid = '%u", wpCreature
->GetGUIDLow());
3234 // set "wpguid" column to the visual waypoint
3235 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3237 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3238 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3239 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3240 map
->Add(wpCreature
);
3241 //wpCreature->GetMap()->Add(wpCreature);
3242 }while( result
->NextRow() );
3251 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3253 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3256 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3257 SetSentErrorMessage(true);
3261 Field
*fields
= result
->Fetch();
3262 float x
= fields
[0].GetFloat();
3263 float y
= fields
[1].GetFloat();
3264 float z
= fields
[2].GetFloat();
3265 uint32 id
= VISUAL_WAYPOINT
;
3267 Player
*chr
= m_session
->GetPlayer();
3268 float o
= chr
->GetOrientation();
3269 Map
*map
= chr
->GetMap();
3271 Creature
* pCreature
= new Creature
;
3272 if (!pCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3274 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3280 pCreature
->Relocate(x
, y
, z
, o
);
3282 if(!pCreature
->IsPositionValid())
3284 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());
3290 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3291 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3292 map
->Add(pCreature
);
3293 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3302 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3304 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3307 Maxpoint
= (*result
)[0].GetUInt32();
3314 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3317 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3318 SetSentErrorMessage(true);
3321 Field
*fields
= result
->Fetch();
3322 float x
= fields
[0].GetFloat();
3323 float y
= fields
[1].GetFloat();
3324 float z
= fields
[2].GetFloat();
3325 uint32 id
= VISUAL_WAYPOINT
;
3327 Player
*chr
= m_session
->GetPlayer();
3328 float o
= chr
->GetOrientation();
3329 Map
*map
= chr
->GetMap();
3331 Creature
* pCreature
= new Creature
;
3332 if (!pCreature
->Create(sObjectMgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3334 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3340 pCreature
->Relocate(x
, y
, z
, o
);
3342 if(!pCreature
->IsPositionValid())
3344 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());
3350 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3351 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3352 map
->Add(pCreature
);
3353 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3361 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3364 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3365 SetSentErrorMessage(true);
3368 bool hasError
= false;
3371 Field
*fields
= result
->Fetch();
3372 uint32 guid
= fields
[0].GetUInt32();
3373 Creature
* pCreature
= m_session
->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3376 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3378 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3382 pCreature
->DeleteFromDB();
3383 pCreature
->AddObjectToRemoveList();
3385 }while(result
->NextRow());
3386 // set "wpguid" column to "empty" - no visual waypoint spawned
3387 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3391 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3392 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3393 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3396 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3403 PSendSysMessage("DEBUG: wpshow - no valid command found");
3406 } // HandleWpShowCommand
3408 bool ChatHandler::HandleWpExportCommand(const char *args
)
3413 // Next arg is: <GUID> <ARGUMENT>
3415 // Did user provide a GUID
3416 // or did the user select a creature?
3417 // -> variable lowguid is filled with the GUID of the NPC
3419 Creature
* target
= getSelectedCreature();
3420 char* arg_str
= NULL
;
3423 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3424 lowguid
= target
->GetGUIDLow();
3427 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3430 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3433 Field
*fields
= result
->Fetch();
3434 lowguid
= fields
[0].GetUInt32();;
3438 arg_str
= strtok((char*)args
, " ");
3442 // user provided <GUID>
3443 char* guid_str
= strtok((char*)args
, " ");
3446 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3449 lowguid
= atoi((char*)guid_str
);
3451 arg_str
= strtok((char*)NULL
, " ");
3456 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3460 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3462 QueryResult
*result
= WorldDatabase
.PQuery(
3463 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3464 "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
);
3468 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3469 SetSentErrorMessage(true);
3473 std::ofstream outfile
;
3474 outfile
.open (arg_str
);
3478 Field
*fields
= result
->Fetch();
3480 outfile
<< "INSERT INTO creature_movement ";
3481 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3484 outfile
<< fields
[15].GetUInt32(); // id
3486 outfile
<< fields
[0].GetUInt32(); // point
3488 outfile
<< fields
[1].GetFloat(); // position_x
3490 outfile
<< fields
[2].GetFloat(); // position_y
3492 outfile
<< fields
[3].GetUInt32(); // position_z
3494 outfile
<< fields
[4].GetUInt32(); // orientation
3496 outfile
<< fields
[5].GetUInt32(); // model1
3498 outfile
<< fields
[6].GetUInt32(); // model2
3500 outfile
<< fields
[7].GetUInt16(); // waittime
3502 outfile
<< fields
[8].GetUInt32(); // emote
3504 outfile
<< fields
[9].GetUInt32(); // spell
3506 outfile
<< fields
[10].GetUInt32(); // textid1
3508 outfile
<< fields
[11].GetUInt32(); // textid2
3510 outfile
<< fields
[12].GetUInt32(); // textid3
3512 outfile
<< fields
[13].GetUInt32(); // textid4
3514 outfile
<< fields
[14].GetUInt32(); // textid5
3517 } while( result
->NextRow() );
3520 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3526 bool ChatHandler::HandleWpImportCommand(const char *args
)
3531 char* arg_str
= strtok((char*)args
, " ");
3536 std::ifstream
infile (arg_str
);
3537 if (infile
.is_open())
3539 while (! infile
.eof() )
3541 getline (infile
,line
);
3542 //cout << line << endl;
3543 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3548 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3554 bool ChatHandler::HandleCharacterRenameCommand(const char* args
)
3558 std::string target_name
;
3559 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
3564 // check online security
3565 if (HasLowerSecurity(target
, 0))
3568 PSendSysMessage(LANG_RENAME_PLAYER
, GetNameLink(target
).c_str());
3569 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3570 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3574 // check offline security
3575 if (HasLowerSecurity(NULL
, target_guid
))
3578 std::string oldNameLink
= playerLink(target_name
);
3580 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(target_guid
));
3581 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid
));
3587 // customize characters
3588 bool ChatHandler::HandleCharacterCustomizeCommand(const char* args
)
3592 std::string target_name
;
3593 if(!extractPlayerTarget((char*)args
,&target
,&target_guid
,&target_name
))
3598 PSendSysMessage(LANG_CUSTOMIZE_PLAYER
, GetNameLink(target
).c_str());
3599 target
->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE
);
3600 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target
->GetGUIDLow());
3604 std::string oldNameLink
= playerLink(target_name
);
3606 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(target_guid
));
3607 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid
));
3613 bool ChatHandler::HandleCharacterReputationCommand(const char* args
)
3616 if(!extractPlayerTarget((char*)args
,&target
))
3619 LocaleConstant loc
= GetSessionDbcLocale();
3621 FactionStateList
const& targetFSL
= target
->GetReputationMgr().GetStateList();
3622 for(FactionStateList::const_iterator itr
= targetFSL
.begin(); itr
!= targetFSL
.end(); ++itr
)
3624 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
3625 char const* factionName
= factionEntry
? factionEntry
->name
[loc
] : "#Not found#";
3626 ReputationRank rank
= target
->GetReputationMgr().GetRank(factionEntry
);
3627 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
3628 std::ostringstream ss
;
3630 ss
<< itr
->second
.ID
<< " - |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << factionName
<< " " << localeNames
[loc
] << "]|h|r";
3632 ss
<< itr
->second
.ID
<< " - " << factionName
<< " " << localeNames
[loc
];
3634 ss
<< " " << rankName
<< " (" << target
->GetReputationMgr().GetReputation(factionEntry
) << ")";
3636 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
3637 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
3638 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
3639 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
3640 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
3641 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
3642 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
3643 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
3644 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
3645 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
3646 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
3647 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
3649 SendSysMessage(ss
.str().c_str());
3655 bool ChatHandler::HandleModifyStandStateCommand(const char* args
)
3660 uint32 anim_id
= atoi((char*)args
);
3662 if (!sEmotesStore
.LookupEntry(anim_id
))
3665 m_session
->GetPlayer()->HandleEmoteState(anim_id
);
3670 bool ChatHandler::HandleHonorAddCommand(const char* args
)
3675 Player
*target
= getSelectedPlayer();
3678 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3679 SetSentErrorMessage(true);
3683 // check online security
3684 if (HasLowerSecurity(target
, 0))
3687 float amount
= (float)atof(args
);
3688 target
->RewardHonor(NULL
, 1, amount
);
3692 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3694 Unit
*target
= getSelectedUnit();
3697 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3698 SetSentErrorMessage(true);
3702 // check online security
3703 if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
3706 m_session
->GetPlayer()->RewardHonor(target
, 1);
3710 bool ChatHandler::HandleHonorUpdateCommand(const char* /*args*/)
3712 Player
*target
= getSelectedPlayer();
3715 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3716 SetSentErrorMessage(true);
3720 // check online security
3721 if (HasLowerSecurity(target
, 0))
3724 target
->UpdateHonorFields();
3728 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3733 std::string namepart
= args
;
3734 std::wstring wnamepart
;
3736 // converting string that we try to find to lower case
3737 if(!Utf8toWStr(namepart
,wnamepart
))
3740 wstrToLower(wnamepart
);
3744 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3745 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3747 for(uint32 id
= 0; id
< events
.size(); ++id
)
3749 GameEventData
const& eventData
= events
[id
];
3751 std::string descr
= eventData
.description
;
3755 if (Utf8FitTo(descr
, wnamepart
))
3757 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3760 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3762 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3769 SendSysMessage(LANG_NOEVENTFOUND
);
3774 bool ChatHandler::HandleEventListCommand(const char* args
)
3778 std::string arg
= args
;
3782 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3783 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3785 char const* active
= GetMangosString(LANG_ACTIVE
);
3786 char const* inactive
= GetMangosString(LANG_FACTION_INACTIVE
);
3787 char const* state
= "";
3789 for (uint32 event_id
= 0; event_id
< events
.size(); ++event_id
)
3791 if (activeEvents
.find(event_id
) == activeEvents
.end())
3800 GameEventData
const& eventData
= events
[event_id
];
3803 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
, event_id
, event_id
, eventData
.description
.c_str(), state
);
3805 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
, event_id
, eventData
.description
.c_str(), state
);
3811 SendSysMessage(LANG_NOEVENTFOUND
);
3816 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3821 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3822 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3826 uint32 event_id
= atoi(cId
);
3828 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3830 if(event_id
>=events
.size())
3832 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3833 SetSentErrorMessage(true);
3837 GameEventData
const& eventData
= events
[event_id
];
3838 if(!eventData
.isValid())
3840 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3841 SetSentErrorMessage(true);
3845 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3846 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3847 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3849 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3850 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3852 uint32 delay
= sGameEventMgr
.NextCheck(event_id
);
3853 time_t nextTime
= time(NULL
)+delay
;
3854 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3856 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3857 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3859 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3860 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3865 bool ChatHandler::HandleEventStartCommand(const char* args
)
3870 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3871 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3875 int32 event_id
= atoi(cId
);
3877 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3879 if(event_id
< 1 || event_id
>=(int32
)events
.size())
3881 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3882 SetSentErrorMessage(true);
3886 GameEventData
const& eventData
= events
[event_id
];
3887 if(!eventData
.isValid())
3889 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3890 SetSentErrorMessage(true);
3894 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3895 if(activeEvents
.find(event_id
) != activeEvents
.end())
3897 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3898 SetSentErrorMessage(true);
3902 PSendSysMessage(LANG_EVENT_STARTED
, event_id
, eventData
.description
.c_str());
3903 sGameEventMgr
.StartEvent(event_id
,true);
3907 bool ChatHandler::HandleEventStopCommand(const char* args
)
3912 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3913 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3917 int32 event_id
= atoi(cId
);
3919 GameEventMgr::GameEventDataMap
const& events
= sGameEventMgr
.GetEventMap();
3921 if(event_id
< 1 || event_id
>=(int32
)events
.size())
3923 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3924 SetSentErrorMessage(true);
3928 GameEventData
const& eventData
= events
[event_id
];
3929 if(!eventData
.isValid())
3931 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3932 SetSentErrorMessage(true);
3936 GameEventMgr::ActiveEvents
const& activeEvents
= sGameEventMgr
.GetActiveEventList();
3938 if(activeEvents
.find(event_id
) == activeEvents
.end())
3940 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3941 SetSentErrorMessage(true);
3945 PSendSysMessage(LANG_EVENT_STOPPED
, event_id
, eventData
.description
.c_str());
3946 sGameEventMgr
.StopEvent(event_id
,true);
3950 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3953 if(!extractPlayerTarget((char*)args
,&target
))
3956 // check online security
3957 if (HasLowerSecurity(target
, 0))
3960 target
->CombatStop();
3961 target
->getHostileRefManager().deleteReferences();
3965 void ChatHandler::HandleLearnSkillRecipesHelper(Player
* player
,uint32 skill_id
)
3967 uint32 classmask
= player
->getClassMask();
3969 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3971 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3976 if( skillLine
->skillId
!= skill_id
)
3980 if(skillLine
->forward_spellid
)
3983 // skip racial skills
3984 if (skillLine
->racemask
!= 0)
3987 // skip wrong class skills
3988 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3991 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3992 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,player
,false))
3995 player
->learnSpell(skillLine
->spellId
, false);
3999 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
4001 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
4003 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
4007 if ((skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
) &&
4008 skillInfo
->canLink
) // only prof. with recipes have
4010 HandleLearnSkillRecipesHelper(m_session
->GetPlayer(),skillInfo
->id
);
4014 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
4018 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
4020 // Learns all recipes of specified profession and sets skill to max
4021 // Example: .learn all_recipes enchanting
4023 Player
* target
= getSelectedPlayer();
4026 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
4033 std::wstring wnamepart
;
4035 if(!Utf8toWStr(args
,wnamepart
))
4038 // converting string that we try to find to lower case
4039 wstrToLower( wnamepart
);
4043 SkillLineEntry
const *targetSkillInfo
= NULL
;
4044 for (uint32 i
= 1; i
< sSkillLineStore
.GetNumRows(); ++i
)
4046 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
4050 if ((skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
4051 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
) ||
4052 !skillInfo
->canLink
) // only prof with recipes have set
4055 int loc
= GetSessionDbcLocale();
4056 name
= skillInfo
->name
[loc
];
4060 if (!Utf8FitTo(name
, wnamepart
))
4063 for(; loc
< MAX_LOCALE
; ++loc
)
4065 if(loc
==GetSessionDbcLocale())
4068 name
= skillInfo
->name
[loc
];
4072 if (Utf8FitTo(name
, wnamepart
))
4077 if(loc
< MAX_LOCALE
)
4079 targetSkillInfo
= skillInfo
;
4084 if(!targetSkillInfo
)
4087 HandleLearnSkillRecipesHelper(target
,targetSkillInfo
->id
);
4089 uint16 maxLevel
= target
->GetPureMaxSkillValue(targetSkillInfo
->id
);
4090 target
->SetSkill(targetSkillInfo
->id
, maxLevel
, maxLevel
);
4091 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
4095 bool ChatHandler::HandleLookupAccountEmailCommand(const char* args
)
4101 std::string email
= strtok ((char*)args
, " ");
4102 char* limit_str
= strtok (NULL
, " ");
4103 uint32 limit
= limit_str
? atoi (limit_str
) : 100;
4105 loginDatabase
.escape_string (email
);
4107 QueryResult
*result
= loginDatabase
.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE email "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'"), email
.c_str ());
4109 return ShowAccountListHelper(result
,&limit
);
4112 bool ChatHandler::HandleLookupAccountIpCommand(const char* args
)
4118 std::string ip
= strtok ((char*)args
, " ");
4119 char* limit_str
= strtok (NULL
, " ");
4120 uint32 limit
= limit_str
? atoi (limit_str
) : 100;
4122 loginDatabase
.escape_string (ip
);
4125 QueryResult
*result
= loginDatabase
.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE last_ip "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'"), ip
.c_str ());
4127 return ShowAccountListHelper(result
,&limit
);
4130 bool ChatHandler::HandleLookupAccountNameCommand(const char* args
)
4135 std::string account
= strtok ((char*)args
, " ");
4136 char* limit_str
= strtok (NULL
, " ");
4137 uint32 limit
= limit_str
? atoi (limit_str
) : 100;
4139 if (!AccountMgr::normalizeString (account
))
4142 loginDatabase
.escape_string (account
);
4144 QueryResult
*result
= loginDatabase
.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE username "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'"), account
.c_str ());
4146 return ShowAccountListHelper(result
,&limit
);
4149 bool ChatHandler::ShowAccountListHelper(QueryResult
* result
, uint32
* limit
, bool title
, bool error
)
4154 SendSysMessage(LANG_ACCOUNT_LIST_EMPTY
);
4158 ///- Display the list of account/characters online
4159 if (!m_session
&& title
) // not output header for online case
4161 SendSysMessage(LANG_ACCOUNT_LIST_BAR
);
4162 SendSysMessage(LANG_ACCOUNT_LIST_HEADER
);
4163 SendSysMessage(LANG_ACCOUNT_LIST_BAR
);
4166 ///- Circle through accounts
4177 Field
*fields
= result
->Fetch();
4178 uint32 account
= fields
[0].GetUInt32();
4180 WorldSession
* session
= sWorld
.FindSession(account
);
4181 Player
* player
= session
? session
->GetPlayer() : NULL
;
4182 char const* char_name
= player
? player
->GetName() : " - ";
4185 PSendSysMessage(LANG_ACCOUNT_LIST_LINE_CHAT
,
4186 account
,fields
[1].GetString(),char_name
,fields
[2].GetString(),fields
[3].GetUInt32(),fields
[4].GetUInt32());
4188 PSendSysMessage(LANG_ACCOUNT_LIST_LINE_CONSOLE
,
4189 account
,fields
[1].GetString(),char_name
,fields
[2].GetString(),fields
[3].GetUInt32(),fields
[4].GetUInt32());
4191 }while(result
->NextRow());
4195 if (!m_session
) // not output header for online case
4196 SendSysMessage(LANG_ACCOUNT_LIST_BAR
);
4201 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
4207 std::string ip
= strtok ((char*)args
, " ");
4208 char* limit_str
= strtok (NULL
, " ");
4209 uint32 limit
= limit_str
? atoi (limit_str
) : 100;
4211 loginDatabase
.escape_string (ip
);
4213 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'"), ip
.c_str ());
4215 return LookupPlayerSearchCommand (result
,&limit
);
4218 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
4223 std::string account
= strtok ((char*)args
, " ");
4224 char* limit_str
= strtok (NULL
, " ");
4225 uint32 limit
= limit_str
? atoi (limit_str
) : 100;
4227 if (!AccountMgr::normalizeString (account
))
4230 loginDatabase
.escape_string (account
);
4232 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'"), account
.c_str ());
4234 return LookupPlayerSearchCommand (result
,&limit
);
4237 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
4243 std::string email
= strtok ((char*)args
, " ");
4244 char* limit_str
= strtok (NULL
, " ");
4245 uint32 limit
= limit_str
? atoi (limit_str
) : 100;
4247 loginDatabase
.escape_string (email
);
4249 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'"), email
.c_str ());
4251 return LookupPlayerSearchCommand (result
,&limit
);
4254 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, uint32
* limit
)
4258 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4259 SetSentErrorMessage(true);
4263 uint32 limit_original
= limit
? *limit
: 100;
4265 uint32 limit_local
= limit_original
;
4268 limit
= &limit_local
;
4272 if (limit
&& *limit
== 0)
4275 Field
* fields
= result
->Fetch();
4276 uint32 acc_id
= fields
[0].GetUInt32();
4277 std::string acc_name
= fields
[1].GetCppString();
4279 ///- Get the characters for account id
4280 QueryResult
*chars
= CharacterDatabase
.PQuery( "SELECT guid, name, race, class, level FROM characters WHERE account = %u", acc_id
);
4283 if (chars
->GetRowCount())
4285 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4286 ShowPlayerListHelper(chars
,limit
,true,false);
4291 } while(result
->NextRow());
4295 if (*limit
==limit_original
) // empty accounts only
4297 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4298 SetSentErrorMessage(true);
4305 /// Triggering corpses expire check in world
4306 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4308 sObjectAccessor
.RemoveOldCorpses();
4312 bool ChatHandler::HandleRepairitemsCommand(const char* args
)
4315 if(!extractPlayerTarget((char*)args
,&target
))
4318 // check online security
4319 if (HasLowerSecurity(target
, 0))
4323 target
->DurabilityRepairAll(false, 0, false);
4325 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, GetNameLink(target
).c_str());
4326 if(needReportToTarget(target
))
4327 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetNameLink().c_str());
4331 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4336 Player
*player
= getSelectedPlayer();
4340 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4341 SetSentErrorMessage(true);
4345 // check online security
4346 if (HasLowerSecurity(player
, 0))
4349 if (strncmp(args
, "on", 3) == 0)
4350 player
->SetMovement(MOVE_WATER_WALK
); // ON
4351 else if (strncmp(args
, "off", 4) == 0)
4352 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4355 SendSysMessage(LANG_USE_BOL
);
4359 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, GetNameLink(player
).c_str());
4360 if(needReportToTarget(player
))
4361 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetNameLink().c_str());
4365 bool ChatHandler::HandleLookupTitleCommand(const char* args
)
4370 // can be NULL in console call
4371 Player
* target
= getSelectedPlayer();
4373 // title name have single string arg for player name
4374 char const* targetName
= target
? target
->GetName() : "NAME";
4376 std::string namepart
= args
;
4377 std::wstring wnamepart
;
4379 if(!Utf8toWStr(namepart
,wnamepart
))
4382 // converting string that we try to find to lower case
4383 wstrToLower( wnamepart
);
4385 uint32 counter
= 0; // Counter for figure out that we found smth.
4387 // Search in CharTitles.dbc
4388 for (uint32 id
= 0; id
< sCharTitlesStore
.GetNumRows(); id
++)
4390 CharTitlesEntry
const *titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4393 int loc
= GetSessionDbcLocale();
4394 std::string name
= titleInfo
->name
[loc
];
4398 if (!Utf8FitTo(name
, wnamepart
))
4401 for(; loc
< MAX_LOCALE
; ++loc
)
4403 if(loc
==GetSessionDbcLocale())
4406 name
= titleInfo
->name
[loc
];
4410 if (Utf8FitTo(name
, wnamepart
))
4415 if(loc
< MAX_LOCALE
)
4417 char const* knownStr
= target
&& target
->HasTitle(titleInfo
) ? GetMangosString(LANG_KNOWN
) : "";
4419 char const* activeStr
= target
&& target
->GetUInt32Value(PLAYER_CHOSEN_TITLE
)==titleInfo
->bit_index
4420 ? GetMangosString(LANG_ACTIVE
)
4423 char titleNameStr
[80];
4424 snprintf(titleNameStr
,80,name
.c_str(),targetName
);
4426 // send title in "id (idx:idx) - [namedlink locale]" format
4428 PSendSysMessage(LANG_TITLE_LIST_CHAT
,id
,titleInfo
->bit_index
,id
,titleNameStr
,localeNames
[loc
],knownStr
,activeStr
);
4430 PSendSysMessage(LANG_TITLE_LIST_CONSOLE
,id
,titleInfo
->bit_index
,titleNameStr
,localeNames
[loc
],knownStr
,activeStr
);
4436 if (counter
== 0) // if counter == 0 then we found nth
4437 SendSysMessage(LANG_COMMAND_NOTITLEFOUND
);
4441 bool ChatHandler::HandleTitlesAddCommand(const char* args
)
4443 // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
4444 char* id_p
= extractKeyFromLink((char*)args
,"Htitle");
4448 int32 id
= atoi(id_p
);
4451 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4452 SetSentErrorMessage(true);
4456 Player
* target
= getSelectedPlayer();
4459 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4460 SetSentErrorMessage(true);
4464 // check online security
4465 if (HasLowerSecurity(target
, 0))
4468 CharTitlesEntry
const* titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4471 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4472 SetSentErrorMessage(true);
4476 std::string tNameLink
= GetNameLink(target
);
4478 char const* targetName
= target
->GetName();
4479 char titleNameStr
[80];
4480 snprintf(titleNameStr
,80,titleInfo
->name
[GetSessionDbcLocale()],targetName
);
4482 target
->SetTitle(titleInfo
);
4483 PSendSysMessage(LANG_TITLE_ADD_RES
, id
, titleNameStr
, tNameLink
.c_str());
4488 bool ChatHandler::HandleTitlesRemoveCommand(const char* args
)
4490 // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
4491 char* id_p
= extractKeyFromLink((char*)args
,"Htitle");
4495 int32 id
= atoi(id_p
);
4498 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4499 SetSentErrorMessage(true);
4503 Player
* target
= getSelectedPlayer();
4506 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4507 SetSentErrorMessage(true);
4511 // check online security
4512 if (HasLowerSecurity(target
, 0))
4515 CharTitlesEntry
const* titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4518 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4519 SetSentErrorMessage(true);
4523 target
->SetTitle(titleInfo
,true);
4525 std::string tNameLink
= GetNameLink(target
);
4527 char const* targetName
= target
->GetName();
4528 char titleNameStr
[80];
4529 snprintf(titleNameStr
,80,titleInfo
->name
[GetSessionDbcLocale()],targetName
);
4531 PSendSysMessage(LANG_TITLE_REMOVE_RES
, id
, titleNameStr
, tNameLink
.c_str());
4533 if (!target
->HasTitle(target
->GetInt32Value(PLAYER_CHOSEN_TITLE
)))
4535 target
->SetUInt32Value(PLAYER_CHOSEN_TITLE
,0);
4536 PSendSysMessage(LANG_CURRENT_TITLE_RESET
, tNameLink
.c_str());
4542 //Edit Player KnownTitles
4543 bool ChatHandler::HandleTitlesSetMaskCommand(const char* args
)
4550 sscanf((char*)args
, UI64FMTD
, &titles
);
4552 Player
*target
= getSelectedPlayer();
4555 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4556 SetSentErrorMessage(true);
4560 // check online security
4561 if (HasLowerSecurity(target
, 0))
4564 uint64 titles2
= titles
;
4566 for(uint32 i
= 1; i
< sCharTitlesStore
.GetNumRows(); ++i
)
4567 if(CharTitlesEntry
const* tEntry
= sCharTitlesStore
.LookupEntry(i
))
4568 titles2
&= ~(uint64(1) << tEntry
->bit_index
);
4570 titles
&= ~titles2
; // remove not existed titles
4572 target
->SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES
, titles
);
4573 SendSysMessage(LANG_DONE
);
4575 if (!target
->HasTitle(target
->GetInt32Value(PLAYER_CHOSEN_TITLE
)))
4577 target
->SetUInt32Value(PLAYER_CHOSEN_TITLE
,0);
4578 PSendSysMessage(LANG_CURRENT_TITLE_RESET
,GetNameLink(target
).c_str());
4584 bool ChatHandler::HandleCharacterTitlesCommand(const char* args
)
4587 if(!extractPlayerTarget((char*)args
,&target
))
4590 LocaleConstant loc
= GetSessionDbcLocale();
4591 char const* targetName
= target
->GetName();
4592 char const* knownStr
= GetMangosString(LANG_KNOWN
);
4594 // Search in CharTitles.dbc
4595 for (uint32 id
= 0; id
< sCharTitlesStore
.GetNumRows(); id
++)
4597 CharTitlesEntry
const *titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4598 if (titleInfo
&& target
->HasTitle(titleInfo
))
4600 std::string name
= titleInfo
->name
[loc
];
4604 char const* activeStr
= target
&& target
->GetUInt32Value(PLAYER_CHOSEN_TITLE
)==titleInfo
->bit_index
4605 ? GetMangosString(LANG_ACTIVE
)
4608 char titleNameStr
[80];
4609 snprintf(titleNameStr
,80,name
.c_str(),targetName
);
4611 // send title in "id (idx:idx) - [namedlink locale]" format
4613 PSendSysMessage(LANG_TITLE_LIST_CHAT
,id
,titleInfo
->bit_index
,id
,titleNameStr
,localeNames
[loc
],knownStr
,activeStr
);
4615 PSendSysMessage(LANG_TITLE_LIST_CONSOLE
,id
,titleInfo
->bit_index
,name
.c_str(),localeNames
[loc
],knownStr
,activeStr
);
4621 bool ChatHandler::HandleTitlesCurrentCommand(const char* args
)
4623 // number or [name] Shift-click form |color|Htitle:title_id|h[name]|h|r
4624 char* id_p
= extractKeyFromLink((char*)args
,"Htitle");
4628 int32 id
= atoi(id_p
);
4631 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4632 SetSentErrorMessage(true);
4636 Player
* target
= getSelectedPlayer();
4639 SendSysMessage(LANG_NO_CHAR_SELECTED
);
4640 SetSentErrorMessage(true);
4644 // check online security
4645 if (HasLowerSecurity(target
, 0))
4648 CharTitlesEntry
const* titleInfo
= sCharTitlesStore
.LookupEntry(id
);
4651 PSendSysMessage(LANG_INVALID_TITLE_ID
, id
);
4652 SetSentErrorMessage(true);
4656 std::string tNameLink
= GetNameLink(target
);
4658 target
->SetTitle(titleInfo
); // to be sure that title now known
4659 target
->SetUInt32Value(PLAYER_CHOSEN_TITLE
,titleInfo
->bit_index
);
4661 PSendSysMessage(LANG_TITLE_CURRENT_RES
, id
, titleInfo
->name
[GetSessionDbcLocale()], tNameLink
.c_str());