2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
24 #include "ObjectMgr.h"
27 #include "GameObject.h"
30 #include "ObjectAccessor.h"
31 #include "MapManager.h"
34 #include "WaypointMovementGenerator.h"
35 #include "GameEvent.h"
40 //mute player for some times
41 bool ChatHandler::HandleMuteCommand(const char* args
)
46 char *charname
= strtok((char*)args
, " ");
50 std::string cname
= charname
;
52 char *timetonotspeak
= strtok(NULL
, " ");
56 uint32 notspeaktime
= (uint32
) atoi(timetonotspeak
);
58 normalizePlayerName(cname
);
59 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
62 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
66 Player
*chr
= objmgr
.GetPlayer(guid
);
69 uint32 account_id
= 0;
74 account_id
= chr
->GetSession()->GetAccountId();
75 security
= chr
->GetSession()->GetSecurity();
79 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
80 security
= objmgr
.GetSecurityByAccount(account_id
);
83 if(security
>= m_session
->GetSecurity())
85 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
89 time_t mutetime
= time(NULL
) + notspeaktime
*60;
92 chr
->GetSession()->m_muteTime
= mutetime
;
94 loginDatabase
.PExecute("UPDATE `account` SET `mutetime` = " I64FMTD
" WHERE `id` = '%u'",uint64(mutetime
), account_id
);
97 PSendSysMessage(chr
->GetSession(), LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
99 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, cname
.c_str(), notspeaktime
);
105 bool ChatHandler::HandleUnmuteCommand(const char* args
)
110 char *charname
= strtok((char*)args
, " ");
114 std::string cname
= charname
;
116 normalizePlayerName(cname
);
117 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
120 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
124 Player
*chr
= objmgr
.GetPlayer(guid
);
127 uint32 account_id
= 0;
132 account_id
= chr
->GetSession()->GetAccountId();
133 security
= chr
->GetSession()->GetSecurity();
137 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
138 security
= objmgr
.GetSecurityByAccount(account_id
);
141 if(security
>= m_session
->GetSecurity())
143 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
151 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
155 chr
->GetSession()->m_muteTime
= 0;
158 loginDatabase
.PExecute("UPDATE `account` SET `mutetime` = '0' WHERE `id` = '%u'", account_id
);
161 PSendSysMessage(chr
->GetSession(), LANG_YOUR_CHAT_ENABLED
);
163 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, cname
.c_str());
167 bool ChatHandler::HandleTargetObjectCommand(const char* args
)
169 Player
* pl
= m_session
->GetPlayer();
171 char eventFilter
[200];
172 char eventFilter2
[200];
173 const GameEvent::ActiveEvents
*ActiveEventsList
= gameeventmgr
.GetActiveEventList();
174 GameEvent::ActiveEvents::const_iterator itr
;
175 bool initString
= false;
176 strcpy(eventFilter
, " AND (`event` IS NULL OR ");
177 strcpy(eventFilter2
, " AND (`event` IS NULL OR (");
178 for (itr
= ActiveEventsList
->begin(); itr
!= ActiveEventsList
->end(); ++itr
)
182 strcat(eventFilter
, " OR ");
183 strcat(eventFilter2
, " AND ");
185 sprintf(eventFilter
, "%s`event`=%u", eventFilter
, *itr
);
186 sprintf(eventFilter2
, "%s`event`<>-%u", eventFilter2
, *itr
);
191 strcat(eventFilter
,")");
192 strcat(eventFilter2
,"))");
196 strcpy(eventFilter
,"");
197 strcpy(eventFilter2
,"");
201 int32 id
= atoi((char*)args
);
203 result
= sDatabase
.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",
204 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
207 std::string name
= args
;
208 sDatabase
.escape_string(name
);
209 result
= sDatabase
.PQuery(
210 "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` "
211 "FROM `gameobject`,`gameobject_template` WHERE `gameobject_template`.`entry` = `gameobject`.`id` AND `map` = %i AND `name` LIKE '%%%s%%' ORDER BY `order` ASC LIMIT 1",
212 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
216 result
= sDatabase
.PQuery("SELECT `gameobject`.`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` LEFT OUTER JOIN `game_event_gameobject` on `gameobject`.`guid`=`game_event_gameobject`.`guid` WHERE `map` = %i%s%s ORDER BY `order` ASC LIMIT 1", m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
,eventFilter2
);
220 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
224 Field
*fields
= result
->Fetch();
225 uint32 guid
= fields
[0].GetUInt32();
226 uint32 id
= fields
[1].GetUInt32();
227 float x
= fields
[2].GetFloat();
228 float y
= fields
[3].GetFloat();
229 float z
= fields
[4].GetFloat();
230 float o
= fields
[5].GetFloat();
231 int mapid
= fields
[6].GetUInt16();
234 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
238 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
242 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, goI
->name
, guid
, id
, x
, y
, z
, mapid
, o
);
247 //teleport to gameobject
248 bool ChatHandler::HandleGoObjectCommand(const char* args
)
253 Player
* _player
= m_session
->GetPlayer();
255 if(_player
->isInFlight())
257 SendSysMessage(LANG_YOU_IN_FLIGHT
);
261 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
262 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
266 int32 guid
= atoi(cId
);
270 QueryResult
*result
= sDatabase
.PQuery("SELECT `position_x`,`position_y`,`position_z`,`orientation`,`map` FROM `gameobject` WHERE `guid` = '%i'",guid
);
273 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
277 Field
*fields
= result
->Fetch();
278 float x
= fields
[0].GetFloat();
279 float y
= fields
[1].GetFloat();
280 float z
= fields
[2].GetFloat();
281 float ort
= fields
[3].GetFloat();
282 int mapid
= fields
[4].GetUInt16();
285 if(!MapManager::IsValidMapCoord(mapid
,x
,y
))
287 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
291 _player
->SetRecallPosition(_player
->GetMapId(),_player
->GetPositionX(),_player
->GetPositionY(),_player
->GetPositionZ(),_player
->GetOrientation());
293 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
297 /** \brief Teleport the GM to the specified creature
299 * .gocreature <GUID> --> TP using creature.guid
300 * .gocreature azuregos --> TP player to the mob with this name
301 * Warning: If there is more than one mob with this name
302 * you will be teleported to the first one that is found.
303 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
304 * Warning: If there is more than one mob with this "id"
305 * you will be teleported to the first one that is found.
307 //teleport to creature
308 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
313 Player
* _player
= m_session
->GetPlayer();
315 if(_player
->isInFlight())
317 SendSysMessage(LANG_YOU_IN_FLIGHT
);
321 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
322 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
326 std::ostringstream whereClause
;
328 // User wants to teleport to the NPC's template entry
329 if( strcmp(pParam1
, "id") == 0 )
331 //sLog.outError("DEBUG: ID found");
333 // Get the "creature_template.entry"
334 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
335 char* tail
= strtok(NULL
,"");
338 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
342 int32 tEntry
= atoi(cId
);
343 //sLog.outError("DEBUG: ID value: %d", tEntry);
347 whereClause
<< "WHERE `id` = '" << tEntry
<< "'";
351 //sLog.outError("DEBUG: ID *not found*");
353 int32 guid
= atoi(pParam1
);
355 // Number is invalid - maybe the user specified the mob's name
358 std::string name
= pParam1
;
359 sDatabase
.escape_string(name
);
360 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name like '" << name
<< "'";
364 whereClause
<< "WHERE `guid` = '" << guid
<< "'";
367 //sLog.outError("DEBUG: %s", whereClause.c_str());
369 QueryResult
*result
= sDatabase
.PQuery("SELECT `position_x`,`position_y`,`position_z`,`orientation`,`map` FROM `creature` %s", whereClause
.str().c_str() );
372 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
375 if( result
->GetRowCount() > 1 )
377 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
380 Field
*fields
= result
->Fetch();
381 float x
= fields
[0].GetFloat();
382 float y
= fields
[1].GetFloat();
383 float z
= fields
[2].GetFloat();
384 float ort
= fields
[3].GetFloat();
385 int mapid
= fields
[4].GetUInt16();
389 if(!MapManager::IsValidMapCoord(mapid
,x
,y
))
391 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
395 _player
->SetRecallPosition(_player
->GetMapId(),_player
->GetPositionX(),_player
->GetPositionY(),_player
->GetPositionZ(),_player
->GetOrientation());
397 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
401 bool ChatHandler::HandleGUIDCommand(const char* args
)
403 uint64 guid
= m_session
->GetPlayer()->GetSelection();
407 SendSysMessage(LANG_NO_SELECTION
);
411 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
415 bool ChatHandler::HandleNameCommand(const char* args
)
421 if(strlen((char*)args)>75)
423 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
427 for (uint8 i = 0; i < strlen(args); i++)
429 if(!isalpha(args[i]) && args[i]!=' ')
431 SendSysMessage(LANG_CHARS_ONLY);
437 guid = m_session->GetPlayer()->GetSelection();
440 SendSysMessage(LANG_NO_SELECTION);
444 Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), guid);
448 SendSysMessage(LANG_SELECT_CREATURE);
452 pCreature->SetName(args);
453 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
454 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
456 pCreature->SaveToDB();
462 bool ChatHandler::HandleSubNameCommand(const char* args
)
469 if(strlen((char*)args)>75)
472 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
476 for (uint8 i = 0; i < strlen(args); i++)
478 if(!isalpha(args[i]) && args[i]!=' ')
480 SendSysMessage(LANG_CHARS_ONLY);
485 guid = m_session->GetPlayer()->GetSelection();
488 SendSysMessage(LANG_NO_SELECTION);
492 Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), guid);
496 SendSysMessage(LANG_SELECT_CREATURE);
500 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
501 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
503 pCreature->SaveToDB();
508 //move item to other slot
509 bool ChatHandler::HandleItemMoveCommand(const char* args
)
513 uint8 srcslot
, dstslot
;
515 char* pParam1
= strtok((char*)args
, " ");
519 char* pParam2
= strtok(NULL
, " ");
523 srcslot
= (uint8
)atoi(pParam1
);
524 dstslot
= (uint8
)atoi(pParam2
);
526 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
527 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
532 m_session
->GetPlayer()->SwapItem( src
, dst
);
537 //add spawn of creature
538 bool ChatHandler::HandleAddSpwCommand(const char* args
)
542 char* charID
= strtok((char*)args
, " ");
546 uint32 id
= atoi(charID
);
548 Player
*chr
= m_session
->GetPlayer();
549 float x
= chr
->GetPositionX();
550 float y
= chr
->GetPositionY();
551 float z
= chr
->GetPositionZ();
552 float o
= chr
->GetOrientation();
554 Creature
* pCreature
= new Creature(chr
);
555 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), chr
->GetMapId(), x
, y
, z
, o
, id
))
561 pCreature
->SaveToDB();
563 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
564 pCreature
->LoadFromDB(pCreature
->GetGUIDLow(), chr
->GetInstanceId());
566 MapManager::Instance().GetMap(pCreature
->GetMapId(), pCreature
)->Add(pCreature
);
571 bool ChatHandler::HandleDeleteCommand(const char* args
)
573 Creature
*unit
= getSelectedCreature();
574 if(!unit
|| unit
->isPet() || unit
->isTotem())
576 SendSysMessage(LANG_SELECT_CREATURE
);
580 unit
->CombatStop(true);
582 unit
->DeleteFromDB();
584 unit
->CleanupsBeforeDelete();
585 ObjectAccessor::Instance().AddObjectToRemoveList(unit
);
587 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
592 //delete object by selection or guid
593 bool ChatHandler::HandleDelObjectCommand(const char* args
)
595 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
596 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
600 uint32 lowguid
= atoi(cId
);
604 GameObject
* obj
= ObjectAccessor::Instance().GetGameObject(*m_session
->GetPlayer(), MAKE_GUID(lowguid
, HIGHGUID_GAMEOBJECT
));
608 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
612 uint64 owner_guid
= obj
->GetOwnerGUID();
615 Unit
* owner
= ObjectAccessor::Instance().GetUnit(*m_session
->GetPlayer(),owner_guid
);
616 if(!owner
&& GUID_HIPART(owner_guid
)!=HIGHGUID_PLAYER
)
618 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
622 owner
->RemoveGameObject(obj
,false);
625 obj
->SetRespawnTime(0); // not save respawn time
629 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
634 //turn selected object
635 bool ChatHandler::HandleTurnObjectCommand(const char* args
)
637 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
638 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
642 uint32 lowguid
= atoi(cId
);
644 GameObject
* obj
= ObjectAccessor::Instance().GetGameObject(*m_session
->GetPlayer(), MAKE_GUID(lowguid
, HIGHGUID_GAMEOBJECT
));
648 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
652 char* po
= strtok(NULL
, " ");
661 Player
*chr
= m_session
->GetPlayer();
662 o
= chr
->GetOrientation();
665 float rot2
= sin(o
/2);
666 float rot3
= cos(o
/2);
668 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
670 obj
->SetFloatValue(GAMEOBJECT_FACING
, o
);
671 obj
->SetFloatValue(GAMEOBJECT_ROTATION
+2, rot2
);
672 obj
->SetFloatValue(GAMEOBJECT_ROTATION
+3, rot3
);
677 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), o
);
682 //move selected creature
683 bool ChatHandler::HandleMoveCreatureCommand(const char* args
)
685 if(!*args
) return false;
688 Creature
* pCreature
= getSelectedCreature();
692 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
693 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
697 uint32 lowguid
= atoi(cId
);
700 pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
702 // Attempting creature load from DB
705 QueryResult
*result
= sDatabase
.PQuery( "SELECT `guid`,`map` FROM `creature` WHERE `guid` = '%u'",lowguid
);
708 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
712 Field
* fields
= result
->Fetch();
713 lowguid
= fields
[0].GetUInt32();
715 uint32 map_id
= fields
[1].GetUInt32();
718 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
720 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
726 lowguid
= pCreature
->GetDBTableGUIDLow();
731 lowguid
= pCreature
->GetDBTableGUIDLow();
734 x
= m_session
->GetPlayer()->GetPositionX();
735 y
= m_session
->GetPlayer()->GetPositionY();
736 z
= m_session
->GetPlayer()->GetPositionZ();
737 o
= m_session
->GetPlayer()->GetOrientation();
740 pCreature
->SetRespawnCoord(x
, y
, z
);
741 MapManager::Instance().GetMap(pCreature
->GetMapId(),pCreature
)->CreatureRelocation(pCreature
,x
, y
, z
,o
);
742 (*pCreature
)->Initialize();
743 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
745 pCreature
->setDeathState(JUST_DIED
);
746 pCreature
->RemoveCorpse();
747 pCreature
->Respawn();
751 sDatabase
.PExecuteLog("UPDATE `creature` SET `spawn_position_x` = '%f', `spawn_position_y` = '%f', `spawn_position_z` = '%f', `spawn_orientation` = '%f',`position_x` = '%f', `position_y` = '%f', `position_z` = '%f', `orientation` = '%f' WHERE `guid` = '%u'", x
, y
, z
, o
, x
, y
, z
, o
, lowguid
);
752 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
756 //move selected object
757 bool ChatHandler::HandleMoveObjectCommand(const char* args
)
759 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
760 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
764 uint32 lowguid
= atoi(cId
);
766 GameObject
* obj
= ObjectAccessor::Instance().GetGameObject(*m_session
->GetPlayer(), MAKE_GUID(lowguid
, HIGHGUID_GAMEOBJECT
));
770 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
774 char* px
= strtok(NULL
, " ");
775 char* py
= strtok(NULL
, " ");
776 char* pz
= strtok(NULL
, " ");
780 Player
*chr
= m_session
->GetPlayer();
782 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
783 map
->Remove(obj
,false);
785 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
786 obj
->SetFloatValue(GAMEOBJECT_POS_X
, chr
->GetPositionX());
787 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, chr
->GetPositionY());
788 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, chr
->GetPositionZ());
797 float x
= (float)atof(px
);
798 float y
= (float)atof(py
);
799 float z
= (float)atof(pz
);
801 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
))
803 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
807 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
808 map
->Remove(obj
,false);
810 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
811 obj
->SetFloatValue(GAMEOBJECT_POS_X
, x
);
812 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, y
);
813 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, z
);
821 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow());
826 //demorph player or unit
827 bool ChatHandler::HandleDeMorphCommand(const char* args
)
829 Unit
*target
= getSelectedUnit();
831 target
= m_session
->GetPlayer();
838 //add item in vendorlist
839 bool ChatHandler::HandleAddVendorItemCommand(const char* args
)
844 Creature
* vendor
= getSelectedCreature();
845 if (!vendor
|| !vendor
->isVendor())
847 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
851 char* pitem
= strtok((char*)args
, " ");
852 uint32 itemId
= atol(pitem
);
855 SendSysMessage(LANG_COMMAND_ADDVENDORITEMSEND
);
859 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
862 maxcount
= atol(fmaxcount
);
864 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
867 incrtime
= atol(fincrtime
);
869 ItemPrototype
const *pProto
= objmgr
.GetItemPrototype(itemId
);
872 PSendSysMessage(LANG_ITEM_NOT_FOUND
, itemId
);
876 // load vendor items if not yet
879 if(vendor
->FindItem(itemId
))
881 PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST
,itemId
);
885 if (vendor
->GetItemCount() >= MAX_VENDOR_ITEMS
)
887 SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS
);
891 // add to DB and to current ingame vendor
892 sDatabase
.PExecuteLog("INSERT INTO `npc_vendor` (`entry`,`item`,`maxcount`,`incrtime`) VALUES('%u','%u','%u','%u')",vendor
->GetEntry(), itemId
, maxcount
,incrtime
);
893 vendor
->AddItem(itemId
,maxcount
,incrtime
);
894 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
);
898 //del item from vendor list
899 bool ChatHandler::HandleDelVendorItemCommand(const char* args
)
904 Creature
* vendor
= getSelectedCreature();
905 if (!vendor
|| !vendor
->isVendor())
907 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
911 char* pitem
= strtok((char*)args
, " ");
912 uint32 itemId
= atol(pitem
);
914 ItemPrototype
const *pProto
= objmgr
.GetItemPrototype(itemId
);
917 PSendSysMessage(LANG_ITEM_NOT_FOUND
, itemId
);
921 // load vendor items if not yet
924 if (!vendor
->RemoveItem(itemId
))
926 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
930 sDatabase
.PExecuteLog("DELETE FROM `npc_vendor` WHERE `entry`='%u' AND `item`='%u'",vendor
->GetEntry(), itemId
);
931 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
935 //add move for creature
936 bool ChatHandler::HandleAddMoveCommand(const char* args
)
941 char* guid_str
= strtok((char*)args
, " ");
942 char* wait_str
= strtok((char*)NULL
, " ");
944 uint32 lowguid
= atoi((char*)guid_str
);
946 Creature
* pCreature
= NULL
;
949 pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
951 // attempt check creature existance by DB
954 QueryResult
*result
= sDatabase
.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",lowguid
);
957 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
964 // obtain real GUID for DB operations
965 lowguid
= pCreature
->GetDBTableGUIDLow();
968 int wait
= wait_str
? atoi(wait_str
) : 0;
975 QueryResult
*result
= sDatabase
.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
978 point
= (*result
)[0].GetUInt32()+1;
985 Player
* player
= m_session
->GetPlayer();
987 sDatabase
.PExecuteLog("INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`,`waittime`) VALUES ('%u','%u','%f', '%f', '%f','%u')",
988 lowguid
, point
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), wait
);
990 // update movement type
991 sDatabase
.PExecuteLog("UPDATE `creature` SET `MovementType` = '%u' WHERE `guid` = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
994 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
995 (*pCreature
)->Initialize();
996 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
998 pCreature
->setDeathState(JUST_DIED
);
999 pCreature
->RemoveCorpse();
1000 pCreature
->Respawn();
1004 SendSysMessage(LANG_WAYPOINT_ADDED
);
1010 * Set the movement type for an NPC.<br/>
1012 * Valid movement types are:
1014 * <li> stay - NPC wont move </li>
1015 * <li> random - NPC will move randomly according to the spawndist </li>
1016 * <li> way - NPC will move with given waypoints set </li>
1018 * additional parameter: NODEL - so no waypoints are deleted, if you
1019 * change the movement type
1021 bool ChatHandler::HandleSetMoveTypeCommand(const char* args
)
1027 // GUID (optional - you can also select the creature)
1028 // stay|random|way (determines the kind of movement)
1029 // NODEL (optional - tells the system NOT to delete any waypoints)
1030 // this is very handy if you want to do waypoints, that are
1031 // later switched on/off according to special events (like escort
1033 char* guid_str
= strtok((char*)args
, " ");
1034 char* type_str
= strtok((char*)NULL
, " ");
1035 char* dontdel_str
= strtok((char*)NULL
, " ");
1037 bool doNotDelete
= false;
1043 Creature
* pCreature
= NULL
;
1047 //sLog.outError("DEBUG: All 3 params are set");
1049 // All 3 params are set
1053 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1055 //sLog.outError("DEBUG: doNotDelete = true;");
1061 // Only 2 params - but maybe NODEL is set
1064 sLog
.outError("DEBUG: Only 2 params ");
1065 if( stricmp( type_str
, "NODEL" ) == 0 )
1067 //sLog.outError("DEBUG: type_str, NODEL ");
1074 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1076 type_str
= guid_str
;
1077 pCreature
= getSelectedCreature();
1080 lowguid
= pCreature
->GetDBTableGUIDLow();
1082 else // case .setmovetype #creature_guid $move_type (with selected creature)
1084 lowguid
= atoi((char*)guid_str
);
1086 pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
1088 // attempt check creature existance by DB
1091 QueryResult
*result
= sDatabase
.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",lowguid
);
1094 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1101 lowguid
= pCreature
->GetDBTableGUIDLow();
1105 // now lowguid is low guid really existed creature
1106 // and pCreature point (maybe) to this creature or NULL
1108 MovementGeneratorType move_type
;
1110 std::string type
= type_str
;
1113 move_type
= IDLE_MOTION_TYPE
;
1114 else if(type
== "random")
1115 move_type
= RANDOM_MOTION_TYPE
;
1116 else if(type
== "way")
1117 move_type
= WAYPOINT_MOTION_TYPE
;
1121 // update movement type
1122 sDatabase
.BeginTransaction();
1123 sDatabase
.PExecuteLog("UPDATE `creature` SET `MovementType` = '%u' WHERE `guid` = '%u'", move_type
,lowguid
);
1124 if( doNotDelete
== false )
1126 //sLog.outError("DEBUG: doNotDelete == false");
1127 sDatabase
.PExecuteLog("DELETE FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
1129 sDatabase
.CommitTransaction();
1132 pCreature
->SetDefaultMovementType(move_type
);
1133 (*pCreature
)->Initialize();
1134 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1136 pCreature
->setDeathState(JUST_DIED
);
1137 pCreature
->RemoveCorpse();
1138 pCreature
->Respawn();
1141 if( doNotDelete
== false )
1143 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1147 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1151 } // HandleSetMoveTypeCommand
1153 //change level of creature or pet
1154 bool ChatHandler::HandleChangeLevelCommand(const char* args
)
1159 uint8 lvl
= (uint8
) atoi((char*)args
);
1160 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1162 SendSysMessage(LANG_BAD_VALUE
);
1166 Creature
* pCreature
= getSelectedCreature();
1169 SendSysMessage(LANG_SELECT_CREATURE
);
1173 if(pCreature
->isPet())
1175 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1179 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1180 pCreature
->SetHealth( 100 + 30*lvl
);
1181 pCreature
->SetLevel( lvl
);
1184 pCreature
->SaveToDB();
1189 //set npcflag of creature
1190 bool ChatHandler::HandleNPCFlagCommand(const char* args
)
1195 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1197 Creature
* pCreature
= getSelectedCreature();
1201 SendSysMessage(LANG_SELECT_CREATURE
);
1205 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1207 sDatabase
.PExecuteLog("UPDATE `creature_template` SET `npcflag` = '%u' WHERE `entry` = '%u'", npcFlags
, pCreature
->GetEntry());
1209 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1211 uint32 entry
= pCreature
->GetUInt32Value( OBJECT_FIELD_ENTRY
);
1212 m_session
->SendCreatureQuery( entry
, pCreature
->GetGUID() );
1217 //set model of creature
1218 bool ChatHandler::HandleSetModelCommand(const char* args
)
1223 uint32 displayId
= (uint32
) atoi((char*)args
);
1225 Creature
*pCreature
= getSelectedCreature();
1229 SendSysMessage(LANG_SELECT_CREATURE
);
1233 pCreature
->SetUInt32Value(UNIT_FIELD_DISPLAYID
, displayId
);
1235 pCreature
->SaveToDB();
1240 //morph creature or player
1241 bool ChatHandler::HandleMorphCommand(const char* args
)
1246 uint16 display_id
= (uint16
)atoi((char*)args
);
1248 Unit
*target
= getSelectedUnit();
1250 target
= m_session
->GetPlayer();
1252 target
->SetUInt32Value(UNIT_FIELD_DISPLAYID
, display_id
);
1257 //set faction of creature or go
1258 bool ChatHandler::HandleFactionIdCommand(const char* args
)
1263 uint32 factionId
= (uint32
) atoi((char*)args
);
1265 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1267 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1271 Creature
* pCreature
= getSelectedCreature();
1275 SendSysMessage(LANG_SELECT_CREATURE
);
1279 pCreature
->setFaction(factionId
);
1281 // faction is set in creature_template - not inside creature
1282 //pCreature->SaveToDB(); -- obsolete
1283 sDatabase
.PExecuteLog("UPDATE `creature_template` SET `faction` = '%u' WHERE `entry` = '%u'", factionId
, pCreature
->GetEntry());
1289 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
1291 char* kickName
= strtok((char*)args
, " ");
1294 Player
* player
= getSelectedPlayer();
1298 SendSysMessage(LANG_NO_CHAR_SELECTED
);
1302 if(player
==m_session
->GetPlayer())
1304 SendSysMessage(LANG_COMMAND_KICKSELF
);
1308 player
->GetSession()->KickPlayer();
1312 std::string name
= kickName
;
1313 normalizePlayerName(name
);
1315 if(name
==m_session
->GetPlayer()->GetName())
1317 SendSysMessage(LANG_COMMAND_KICKSELF
);
1321 if(sWorld
.KickPlayer(name
))
1323 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,name
.c_str());
1326 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER
,name
.c_str());
1332 //show info of player
1333 bool ChatHandler::HandlePInfoCommand(const char* args
)
1335 Player
* target
= NULL
;
1336 uint64 targetGUID
= 0;
1338 char* px
= strtok((char*)args
, " ");
1346 normalizePlayerName(name
);
1347 target
= objmgr
.GetPlayer(name
.c_str());
1349 py
= strtok(NULL
, " ");
1352 targetGUID
= objmgr
.GetPlayerGUIDByName(name
);
1354 py
= strtok(NULL
, " ");
1360 if(!target
&& !targetGUID
)
1362 target
= getSelectedPlayer();
1365 if(!target
&& !targetGUID
)
1367 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1373 uint32 total_player_time
= 0;
1376 // get additional information from Player object
1379 targetGUID
= target
->GetGUID();
1380 name
= target
->GetName(); // re-read for case getSelectedPlayer() target
1381 accId
= target
->GetSession()->GetAccountId();
1382 money
= target
->GetMoney();
1383 total_player_time
= target
->GetTotalPlayedTime();
1384 level
= target
->getLevel();
1386 // get additional information from DB
1389 accId
= objmgr
.GetPlayerAccountIdByGUID(targetGUID
);
1390 Player
plr(m_session
); // use current session for temporary load
1391 plr
.MinimalLoadFromDB(NULL
, targetGUID
);
1392 money
= plr
.GetMoney();
1393 total_player_time
= plr
.GetTotalPlayedTime();
1394 level
= plr
.getLevel();
1397 std::string username
= LANG_ERROR
;
1398 std::string last_ip
= LANG_ERROR
;
1399 uint32 security
= 0;
1401 QueryResult
* result
= loginDatabase
.PQuery("SELECT `username`,`gmlevel`,`last_ip` FROM `account` WHERE `id` = '%u'",accId
);
1404 Field
* fields
= result
->Fetch();
1405 username
= fields
[0].GetCppString();
1406 security
= fields
[1].GetUInt32();
1407 if(m_session
->GetSecurity() >= security
)
1408 last_ip
= fields
[2].GetCppString();
1415 PSendSysMessage(LANG_PINFO_ACCOUNT
, (target
?"":LANG_OFFLINE
), name
.c_str(), GUID_LOPART(targetGUID
), username
.c_str(), accId
, security
, last_ip
.c_str());
1417 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
1418 uint32 gold
= money
/GOLD
;
1419 uint32 silv
= (money
% GOLD
) / SILVER
;
1420 uint32 copp
= (money
% GOLD
) % SILVER
;
1421 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
1423 if ( py
&& strncmp(py
, "rep", 3) == 0 )
1427 // rep option not implemented for offline case
1428 SendSysMessage(LANG_PINFO_NO_REP
);
1432 static const char* ReputationRankStr
[MAX_REPUTATION_RANK
] = {"Hated", "Hostile", "Unfriendly", "Neutral", "Friendly", "Honored", "Reverted", "Exalted"};
1434 for(FactionsList::const_iterator itr
= target
->m_factions
.begin(); itr
!= target
->m_factions
.end(); ++itr
)
1436 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
1438 FactionName
= factionEntry
->name
[sWorld
.GetDBClang()];
1440 FactionName
= "#Not found#";
1441 ReputationRank Rank
= target
->GetReputationRank(factionEntry
);
1443 PSendSysMessage("Id:%4d %s %s %5d %1x", itr
->second
.ID
, FactionName
, ReputationRankStr
[Rank
], target
->GetReputation(factionEntry
), itr
->second
.Flags
);
1450 void ChatHandler::ShowTicket(uint64 guid
, uint32 category
, char const* text
)
1453 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
1454 name
= LANG_UNKNOWN
;
1456 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, name
.c_str(),category
,text
);
1460 bool ChatHandler::HandleTicketCommand(const char* args
)
1462 char* px
= strtok((char*)args
, " ");
1467 QueryResult
*result
= sDatabase
.Query("SELECT `ticket_id` FROM `character_ticket`");
1468 size_t count
= result
? result
->GetRowCount() : 0;
1470 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
,m_session
->GetPlayer()->isAcceptTickets() ? LANG_ON
: LANG_OFF
);
1476 if(strncmp(px
,"on",3) == 0)
1478 m_session
->GetPlayer()->SetAcceptTicket(true);
1479 SendSysMessage(LANG_COMMAND_TICKETON
);
1484 if(strncmp(px
,"off",4) == 0)
1486 m_session
->GetPlayer()->SetAcceptTicket(false);
1487 SendSysMessage(LANG_COMMAND_TICKETOFF
);
1495 QueryResult
*result
= sDatabase
.Query("SELECT `guid`,`ticket_category`,`ticket_text` FROM `character_ticket`");
1497 if(!result
|| uint64(num
) > result
->GetRowCount())
1499 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1504 for(int i
= 1; i
< num
; ++i
)
1507 Field
* fields
= result
->Fetch();
1509 uint64 guid
= fields
[0].GetUInt64();
1510 uint32 category
= fields
[1].GetUInt32();
1511 char const* text
= fields
[2].GetString();
1513 ShowTicket(guid
,category
,text
);
1518 std::string name
= px
;
1519 normalizePlayerName(name
);
1520 //sDatabase.escape_string(name); // prevent SQL injection - normal name don't must changed by this call
1522 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
1527 // ticket $char_name
1528 QueryResult
*result
= sDatabase
.PQuery("SELECT `guid`,`ticket_category`,`ticket_text` FROM `character_ticket` WHERE `guid` = '%u'",GUID_LOPART(guid
));
1533 Field
* fields
= result
->Fetch();
1535 uint32 category
= fields
[1].GetUInt32();
1536 char const* text
= fields
[2].GetString();
1538 ShowTicket(guid
,category
,text
);
1544 uint32
ChatHandler::GetTicketIDByNum(uint32 num
)
1546 QueryResult
*result
= sDatabase
.Query("SELECT `ticket_id` FROM `character_ticket`");
1548 if(!result
|| num
> result
->GetRowCount())
1550 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1555 for(uint32 i
= 1; i
< num
; ++i
)
1558 Field
* fields
= result
->Fetch();
1560 uint32 id
= fields
[0].GetUInt32();
1566 bool ChatHandler::HandleDelTicketCommand(const char *args
)
1568 char* px
= strtok((char*)args
, " ");
1573 if(strncmp(px
,"all",4) == 0)
1575 QueryResult
*result
= sDatabase
.Query("SELECT `guid` FROM `character_ticket`");
1580 // notify players about ticket deleting
1583 Field
* fields
= result
->Fetch();
1585 uint64 guid
= fields
[0].GetUInt64();
1587 if(Player
* sender
= objmgr
.GetPlayer(guid
))
1588 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
1590 }while(result
->NextRow());
1594 sDatabase
.PExecute("DELETE FROM `character_ticket`");
1595 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
1599 int num
= (uint32
)atoi(px
);
1604 QueryResult
*result
= sDatabase
.PQuery("SELECT `ticket_id`,`guid` FROM `character_ticket` LIMIT '%i'",num
);
1606 if(!result
|| uint64(num
) > result
->GetRowCount())
1608 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1613 for(int i
= 1; i
< num
; ++i
)
1616 Field
* fields
= result
->Fetch();
1618 uint32 id
= fields
[0].GetUInt32();
1619 uint64 guid
= fields
[1].GetUInt64();
1622 sDatabase
.PExecute("DELETE FROM `character_ticket` WHERE `ticket_id` = '%u'", id
);
1624 // notify players about ticket deleting
1625 if(Player
* sender
= objmgr
.GetPlayer(guid
))
1627 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
1628 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,sender
->GetName());
1631 SendSysMessage(LANG_COMMAND_TICKETDEL
);
1636 std::string name
= px
;
1637 normalizePlayerName(name
);
1638 //sDatabase.escape_string(name); // prevent SQL injection - normal name don't must changed by this call
1640 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
1645 // delticket $char_name
1646 sDatabase
.PExecute("DELETE FROM `character_ticket` WHERE `guid` = '%u'",GUID_LOPART(guid
));
1648 // notify players about ticket deleting
1649 if(Player
* sender
= objmgr
.GetPlayer(guid
))
1650 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
1652 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,px
);
1656 //set spawn dist of creature
1657 bool ChatHandler::HandleSpawnDistCommand(const char* args
)
1662 int option
= atoi((char*)args
);
1665 SendSysMessage(LANG_BAD_VALUE
);
1669 int mtype
=0; // MovementType
1673 Creature
*pCreature
= getSelectedCreature();
1677 u_guid
= pCreature
->GetDBTableGUIDLow();
1681 sDatabase
.PExecuteLog("UPDATE `creature` SET `spawndist`=%i, `MovementType`=%i WHERE `guid`=%u",option
,mtype
,u_guid
);
1682 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
1686 bool ChatHandler::HandleSpawnTimeCommand(const char* args
)
1691 char* stime
= strtok((char*)args
, " ");
1696 int i_stime
= atoi((char*)stime
);
1700 SendSysMessage(LANG_BAD_VALUE
);
1704 Creature
*pCreature
= getSelectedCreature();
1708 u_guid
= pCreature
->GetDBTableGUIDLow();
1712 sDatabase
.PExecuteLog("UPDATE `creature` SET `spawntimesecs`=%i WHERE `guid`=%u",i_stime
,u_guid
);
1713 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
1719 * Add a waypoint to a creature.
1721 * The user can either select an npc or provide its GUID.
1723 * The user can even select a visual waypoint - then the new waypoint
1724 * is placed *after* the selected one - this makes insertion of new
1725 * waypoints possible.
1729 * -> adds a waypoint to the npc with the GUID 12345
1732 * -> adds a waypoint to the currently selected creature
1735 * @param args if the user did not provide a GUID, it is NULL
1737 * @return true - command did succeed, false - something went wrong
1739 bool ChatHandler::HandleWpAddCommand(const char* args
)
1741 sLog
.outDebug("DEBUG: HandleWpAddCommand");
1744 char* guid_str
= NULL
;
1748 guid_str
= strtok((char*)args
, " ");
1753 Unit
* target
= getSelectedCreature();
1754 // Did player provide a GUID?
1757 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
1760 // -> Player must have selected a creature
1764 SendSysMessage(LANG_SELECT_CREATURE
);
1767 if (target
->GetEntry() == VISUAL_WAYPOINT
)
1769 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
1771 QueryResult
*result
=
1772 sDatabase
.PQuery( "SELECT `id`, `point` FROM `creature_movement` WHERE `wpguid` = %u",
1773 target
->GetGUIDLow() );
1776 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
1777 // User selected a visual spawnpoint -> get the NPC
1779 // Since we compare float values, we have to deal with
1780 // some difficulties.
1781 // Here we search for all waypoints that only differ in one from 1 thousand
1782 // (0.001) - There is no other way to compare C++ floats with mySQL floats
1783 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
1784 const char* maxDIFF
= "0.01";
1785 result
= sDatabase
.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 )",
1786 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
1789 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
1795 Field
*fields
= result
->Fetch();
1796 lowguid
= fields
[0].GetUInt32();
1797 point
= fields
[1].GetUInt32();
1798 }while( result
->NextRow() );
1803 lowguid
= target
->GetGUIDLow();
1809 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
1812 // Warn if player also selected a creature
1813 // -> Creature selection is ignored <-
1816 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
1818 lowguid
= atoi((char*)guid_str
);
1820 // lowguid -> GUID of the NPC
1821 // point -> number of the waypoint (if not 0)
1822 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
1824 Creature
* pCreature
= NULL
;
1827 pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
1829 // attempt check creature existance by DB
1832 QueryResult
*result
= sDatabase
.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",lowguid
);
1835 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
1841 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
1843 QueryResult
*result
= sDatabase
.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
1846 point
= (*result
)[0].GetUInt32()+1;
1852 Player
* player
= m_session
->GetPlayer();
1854 sDatabase
.PExecuteLog("INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`) VALUES ('%u','%u','%f', '%f', '%f', '%f')",
1855 lowguid
, point
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation());
1857 // update movement type
1858 sDatabase
.PExecuteLog("UPDATE `creature` SET `MovementType` = '%u' WHERE `guid` = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1861 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1862 (*pCreature
)->Initialize();
1863 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1865 pCreature
->setDeathState(JUST_DIED
);
1866 pCreature
->RemoveCorpse();
1867 pCreature
->Respawn();
1871 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
1874 } // HandleWpAddCommand
1877 * .wp modify emote | spell | text | del | move | add
1879 * add -> add a WP after the selected visual waypoint
1880 * User must select a visual waypoint and then issue ".wp modify add"
1883 * User has selected a visual waypoint before.
1884 * <emoteID> is added to this waypoint. Everytime the
1885 * NPC comes to this waypoint, the emote is called.
1887 * emote <GUID> <WPNUM> <emoteID>
1888 * User has not selected visual waypoint before.
1889 * For the waypoint <WPNUM> for the NPC with <GUID>
1890 * an emote <emoteID> is added.
1891 * Everytime the NPC comes to this waypoint, the emote is called.
1894 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
1896 bool ChatHandler::HandleWpModifyCommand(const char* args
)
1898 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
1903 // first arg: add del text emote spell waittime move
1904 char* show_str
= strtok((char*)args
, " ");
1910 std::string show
= show_str
;
1912 // Remember: "show" must also be the name of a column!
1913 if( (show
!= "emote") && (show
!= "spell") && (show
!= "aiscript")
1914 && (show
!= "text1") && (show
!= "text2") && (show
!= "text3") && (show
!= "text4") && (show
!= "text5")
1915 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
1916 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation")
1917 && (show
!= "import") && (show
!= "export") )
1922 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
1923 char* arg_str
= NULL
;
1925 // Did user provide a GUID
1926 // or did the user select a creature?
1927 // -> variable lowguid is filled with the GUID of the NPC
1931 Unit
* target
= getSelectedCreature();
1935 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
1937 // The visual waypoint
1938 Creature
* wpCreature
= NULL
;
1940 wpGuid
= target
->GetGUIDLow();
1942 // Did the user select a visual spawnpoint?
1944 wpCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(wpGuid
,HIGHGUID_UNIT
));
1946 // attempt check creature existance by DB
1949 QueryResult
*result
= sDatabase
.PQuery( "SELECT `guid` FROM `creature` WHERE `guid` = '%u'",wpGuid
);
1952 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, wpGuid
);
1957 // User did select a visual waypoint?
1958 // Check the creature
1959 if (wpCreature
->GetEntry() != VISUAL_WAYPOINT
)
1961 if( (show
!= "export") && (show
!= "import") )
1963 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
1967 arg_str
= strtok((char*)NULL
, " ");
1971 QueryResult
*result
=
1972 sDatabase
.PQuery( "SELECT `id`, `point` FROM `creature_movement` WHERE `wpguid` = %u",
1973 target
->GetGUIDLow() );
1976 sLog
.outDebug("DEBUG: HandleWpModifyCommand - No waypoint found - used 'wpguid'");
1978 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
1979 // Select waypoint number from database
1980 // Since we compare float values, we have to deal with
1981 // some difficulties.
1982 // Here we search for all waypoints that only differ in one from 1 thousand
1983 // (0.001) - There is no other way to compare C++ floats with mySQL floats
1984 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
1985 const char* maxDIFF
= "0.01";
1986 result
= sDatabase
.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 )",
1987 wpCreature
->GetPositionX(), maxDIFF
, wpCreature
->GetPositionY(), maxDIFF
, wpCreature
->GetPositionZ(), maxDIFF
);
1990 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
1994 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
1998 Field
*fields
= result
->Fetch();
1999 lowguid
= fields
[0].GetUInt32();
2000 point
= fields
[1].GetUInt32();
2001 }while( result
->NextRow() );
2004 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2006 // We have the waypoint number and the GUID of the "master npc"
2007 // Text is enclosed in "<>", all other arguments not
2008 if( show
.find("text") != std::string::npos
)
2010 arg_str
= strtok((char*)NULL
, "<>");
2014 arg_str
= strtok((char*)NULL
, " ");
2020 // User did provide <GUID> <WPNUM>
2021 char* guid_str
= strtok((char*)NULL
, " ");
2022 char* point_str
= strtok((char*)NULL
, " ");
2024 // Text is enclosed in "<>", all other arguments not
2025 if( show
.find("text") != std::string::npos
)
2027 arg_str
= strtok((char*)NULL
, "<>");
2031 arg_str
= strtok((char*)NULL
, " ");
2036 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2041 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2044 if( (show
!= "del") && (show
!= "move") && (show
!= "add") )
2048 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show
.c_str());
2052 lowguid
= atoi((char*)guid_str
);
2053 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2054 point
= atoi((char*)point_str
);
2055 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2057 // Now we need the GUID of the visual waypoint
2058 // -> "del", "move", "add" command
2060 QueryResult
*result
= sDatabase
.PQuery( "SELECT `wpguid` FROM `creature_movement` WHERE `id` = '%u' AND `point` = '%u'", lowguid
, point
);
2065 Field
*fields
= result
->Fetch();
2066 wpGuid
= fields
[0].GetUInt32();
2067 }while( result
->NextRow() );
2074 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2075 // Select waypoint number from database
2076 QueryResult
*result
= sDatabase
.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point`='%d' AND `id` = '%u'", point
, lowguid
);
2079 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2083 Field
*fields
= result
->Fetch();
2084 float x
= fields
[0].GetFloat();
2085 float y
= fields
[1].GetFloat();
2086 float z
= fields
[2].GetFloat();
2090 // Select waypoint number from database
2091 // Since we compare float values, we have to deal with
2092 // some difficulties.
2093 // Here we search for all waypoints that only differ in one from 1 thousand
2094 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2095 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2096 const char* maxDIFF
= "0.01";
2098 result
= sDatabase
.PQuery( "SELECT `guid` FROM `creature` WHERE (abs(`position_x` - %f) <= %s ) and (abs(`position_y` - %f) <= %s ) and (abs(`position_z` - %f) <= %s ) and `id`=%d",
2099 x
, maxDIFF
, y
, maxDIFF
, z
, maxDIFF
, VISUAL_WAYPOINT
);
2102 PSendSysMessage(LANG_WAYPOINT_WPCREATNOTFOUND
, VISUAL_WAYPOINT
);
2107 Field
*fields
= result
->Fetch();
2108 wpGuid
= fields
[0].GetUInt32();
2109 }while( result
->NextRow() );
2116 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2118 // Check for argument
2119 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add") && (show
!= "aiscript"))
2121 if( arg_str
== NULL
)
2123 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2127 // wpGuid -> GUID of the waypoint creature
2128 // lowguid -> GUID of the NPC
2129 // point -> waypoint number
2131 // Special functions:
2132 // add - move - del -> no args commands
2133 // Add a waypoint after the selected visual
2136 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2138 // Get the creature for which we read the waypoint
2139 Creature
* npcCreature
= NULL
;
2140 npcCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(), MAKE_GUID(lowguid
, HIGHGUID_UNIT
));
2144 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2149 // obtain real GUID for DB operations
2150 lowguid
= npcCreature
->GetDBTableGUIDLow();
2152 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2155 // Add the visual spawnpoint (DB only)
2156 // Adjust the waypoints
2157 // Respawn the owner of the waypoints
2158 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- SELECT MAX(`point`)");
2159 QueryResult
*result
= sDatabase
.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
2160 uint32 maxPoint
= 0;
2163 maxPoint
= (*result
)[0].GetUInt32();
2166 for( uint32 i
=maxPoint
; i
>point
; i
-- )
2168 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET point=point+1 WHERE id='%u' AND point='%u'", lowguid
, i
);
2171 Player
* chr
= m_session
->GetPlayer();
2172 sDatabase
.PExecuteLog("INSERT INTO `creature_movement` (`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES ('%u','%u','%f', '%f', '%f')",
2173 lowguid
, point
+1, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2177 (*npcCreature
)->Initialize();
2178 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2180 npcCreature
->setDeathState(JUST_DIED
);
2181 npcCreature
->RemoveCorpse();
2182 npcCreature
->Respawn();
2186 Creature
* wpCreature
= new Creature(chr
);
2187 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), chr
->GetMapId(),
2188 chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation(), VISUAL_WAYPOINT
))
2190 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2194 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '%u' WHERE `id` = '%u' and `point` = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
+1);
2196 wpCreature
->SaveToDB();
2197 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2198 wpCreature
->LoadFromDB(wpCreature
->GetGUIDLow(), chr
->GetInstanceId());
2199 MapManager::Instance().GetMap(wpCreature
->GetMapId(), wpCreature
)->Add(wpCreature
);
2201 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2207 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2209 // Get the creature for which we read the waypoint
2210 Creature
* npcCreature
= NULL
;
2211 npcCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
, HIGHGUID_UNIT
));
2214 Creature
* wpCreature
= NULL
;
2217 wpCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(wpGuid
, HIGHGUID_UNIT
));
2218 wpCreature
->CombatStop(true);
2219 wpCreature
->DeleteFromDB();
2220 ObjectAccessor::Instance().AddObjectToRemoveList(wpCreature
);
2224 // Remove the visual spawnpoint
2225 // Adjust the waypoints
2226 // Respawn the owner of the waypoints
2228 sDatabase
.PExecuteLog("DELETE FROM `creature_movement` WHERE id='%u' AND point='%u'",
2230 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET point=point-1 WHERE id='%u' AND point>'%u'",
2235 // Any waypoints left?
2236 QueryResult
*result2
= sDatabase
.PQuery( "SELECT `point` FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
2239 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2243 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2246 (*npcCreature
)->Initialize();
2247 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2249 npcCreature
->setDeathState(JUST_DIED
);
2250 npcCreature
->RemoveCorpse();
2251 npcCreature
->Respawn();
2255 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2261 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2263 Player
*chr
= m_session
->GetPlayer();
2265 // Get the creature for which we read the waypoint
2266 Creature
* npcCreature
= NULL
;
2267 npcCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
2270 Creature
* wpCreature
= NULL
;
2272 // Move the visual spawnpoint
2273 // Respawn the owner of the waypoints
2276 wpCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(wpGuid
, HIGHGUID_UNIT
));
2277 wpCreature
->CombatStop(true);
2278 wpCreature
->DeleteFromDB();
2279 ObjectAccessor::Instance().AddObjectToRemoveList(wpCreature
);
2281 Creature
* wpCreature2
= new Creature(chr
);
2282 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), chr
->GetMapId(),
2283 chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation(), VISUAL_WAYPOINT
))
2285 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2289 wpCreature2
->SaveToDB();
2290 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2291 wpCreature2
->LoadFromDB(wpCreature2
->GetGUIDLow(), chr
->GetInstanceId());
2292 MapManager::Instance().GetMap(npcCreature
->GetMapId(), npcCreature
)->Add(wpCreature2
);
2293 //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2296 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET `position_x` = '%f',`position_y` = '%f',`position_z` = '%f' where `id` = '%u' AND point='%u'",
2297 chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), lowguid
, point
);
2301 (*npcCreature
)->Initialize();
2302 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2304 npcCreature
->setDeathState(JUST_DIED
);
2305 npcCreature
->RemoveCorpse();
2306 npcCreature
->Respawn();
2309 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2314 if(show
== "export")
2316 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
2318 std::ofstream outfile
;
2319 outfile
.open (arg_str
);
2321 QueryResult
*result
= sDatabase
.PQuery(
2322 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2323 "SELECT `point`, `position_x`, `position_y`, `position_z`, `orientation`, `model1`, `model2`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `aiscript`, `id` FROM `creature_movement` WHERE `id` = '%u' ORDER BY `point`", lowguid
);
2329 Field
*fields
= result
->Fetch();
2331 outfile
<< "insert into creature_movement ";
2332 outfile
<< "( `id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `model1`, `model2`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `aiscript` ) values ";
2334 //sLog.outDebug("( ");
2336 //sLog.outDebug("id");
2337 outfile
<< fields
[16].GetUInt32(); // id
2339 //sLog.outDebug("point");
2340 outfile
<< fields
[0].GetUInt32(); // point
2342 //sLog.outDebug("position_x");
2343 outfile
<< fields
[1].GetFloat(); // position_x
2345 //sLog.outDebug("position_y");
2346 outfile
<< fields
[2].GetFloat(); // position_y
2348 //sLog.outDebug("position_z");
2349 outfile
<< fields
[3].GetUInt32(); // position_z
2351 //sLog.outDebug("orientation");
2352 outfile
<< fields
[4].GetUInt32(); // orientation
2354 //sLog.outDebug("model1");
2355 outfile
<< fields
[5].GetUInt32(); // model1
2357 //sLog.outDebug("model2");
2358 outfile
<< fields
[6].GetUInt32(); // model2
2360 //sLog.outDebug("waittime");
2361 outfile
<< fields
[7].GetUInt16(); // waittime
2363 //sLog.outDebug("emote");
2364 outfile
<< fields
[8].GetUInt32(); // emote
2366 //sLog.outDebug("spell");
2367 outfile
<< fields
[9].GetUInt32(); // spell
2369 //sLog.outDebug("text1");
2370 const char *tmpChar
= fields
[10].GetString();
2373 outfile
<< "NULL"; // text1
2378 outfile
<< tmpChar
; // text1
2382 //sLog.outDebug("text2");
2383 tmpChar
= fields
[11].GetString();
2386 outfile
<< "NULL"; // text2
2391 outfile
<< tmpChar
; // text2
2395 //sLog.outDebug("text3");
2396 tmpChar
= fields
[12].GetString();
2399 outfile
<< "NULL"; // text3
2404 outfile
<< tmpChar
; // text3
2408 //sLog.outDebug("text4");
2409 tmpChar
= fields
[13].GetString();
2412 outfile
<< "NULL"; // text4
2417 outfile
<< tmpChar
; // text4
2421 //sLog.outDebug("text5");
2422 tmpChar
= fields
[14].GetString();
2425 outfile
<< "NULL"; // text5
2430 outfile
<< tmpChar
; // text5
2434 //sLog.outDebug("aiscript");
2435 tmpChar
= fields
[15].GetString();
2438 outfile
<< "NULL"; // aiscript
2443 outfile
<< tmpChar
; // aiscript
2448 } while( result
->NextRow() );
2451 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
2455 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
2456 outfile
<< LANG_WAYPOINT_NOTHINGTOEXPORT
;
2462 if(show
== "import")
2464 PSendSysMessage("DEBUG: wp import, GUID: %u", lowguid
);
2467 std::ifstream
infile (arg_str
);
2468 if (infile
.is_open())
2470 while (! infile
.eof() )
2472 getline (infile
,line
);
2473 //cout << line << endl;
2474 QueryResult
*result
= sDatabase
.PQuery(line
.c_str());
2479 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
2484 // Create creature - npc that has the waypoint
2485 Creature
* npcCreature
= NULL
;
2488 npcCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
2490 // attempt check creature existance by DB
2493 if(!objmgr
.GetCreatureData(lowguid
))
2495 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2500 const char *text
= arg_str
;
2504 // show_str check for present in list of correct values, no sql injection possible
2505 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET %s=NULL WHERE id='%u' AND point='%u'",
2506 show_str
, lowguid
, point
);
2510 // show_str check for present in list of correct values, no sql injection possible
2511 std::string text2
= text
;
2512 sDatabase
.escape_string(text2
);
2513 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET %s='%s' WHERE id='%u' AND point='%u'",
2514 show_str
, text2
.c_str(), lowguid
, point
);
2519 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2520 (*npcCreature
)->Initialize();
2521 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2523 npcCreature
->setDeathState(JUST_DIED
);
2524 npcCreature
->RemoveCorpse();
2525 npcCreature
->Respawn();
2528 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2534 * .wp show info | on | off
2536 * info -> User has selected a visual waypoint before
2538 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2539 * provided the GUID of the NPC and the number of
2542 * on -> User has selected an NPC; all visual waypoints for this
2543 * NPC are added to the world
2545 * on <GUID> -> User did not select an NPC - instead the GUID of the
2546 * NPC is provided. All visual waypoints for this NPC
2547 * are added from the world.
2549 * off -> User has selected an NPC; all visual waypoints for this
2550 * NPC are removed from the world.
2552 * on <GUID> -> User did not select an NPC - instead the GUID of the
2553 * NPC is provided. All visual waypoints for this NPC
2554 * are removed from the world.
2558 bool ChatHandler::HandleWpShowCommand(const char* args
)
2560 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2565 // first arg: on, off, first, last
2566 char* show_str
= strtok((char*)args
, " ");
2571 // second arg: GUID (optional, if a creature is selected)
2572 char* guid_str
= strtok((char*)NULL
, " ");
2573 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2578 // Did user provide a GUID
2579 // or did the user select a creature?
2580 // -> variable lowguid is filled with the GUID
2582 Unit
* target
= getSelectedCreature();
2583 // Did player provide a GUID?
2586 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2588 // -> Player must have selected a creature
2592 SendSysMessage(LANG_SELECT_CREATURE
);
2595 lowguid
= target
->GetGUIDLow();
2599 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2601 // Warn if player also selected a creature
2602 // -> Creature selection is ignored <-
2605 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2607 lowguid
= atoi((char*)guid_str
);
2610 sLog
.outDebug("DEBUG: HandleWpShowCommand: danach");
2612 std::string show
= show_str
;
2615 Creature
* pCreature
= NULL
;
2617 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid
);
2619 pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(lowguid
,HIGHGUID_UNIT
));
2621 sLog
.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", pCreature
);
2622 // attempt check creature existance by DB
2625 if(!objmgr
.GetCreatureData(lowguid
))
2627 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2632 sLog
.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str
);
2633 //PSendSysMessage("wpshow - show: %s", show);
2635 // Show info for the selected waypoint
2638 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
2640 // Check if the user did specify a visual waypoint
2641 if( pCreature
->GetEntry() != VISUAL_WAYPOINT
)
2643 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2647 //PSendSysMessage("wp on, GUID: %u", lowguid);
2649 //pCreature->GetPositionX();
2651 QueryResult
*result
=
2652 sDatabase
.PQuery( "SELECT `id`, `point`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `model1`, `model2`, `aiscript` FROM `creature_movement` WHERE `wpguid` = %u",
2653 pCreature
->GetGUID() );
2656 // Since we compare float values, we have to deal with
2657 // some difficulties.
2658 // Here we search for all waypoints that only differ in one from 1 thousand
2659 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2660 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2661 const char* maxDIFF
= "0.01";
2662 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, pCreature
->GetGUID());
2664 result
= sDatabase
.PQuery( "SELECT `id`, `point`, `waittime`, `emote`, `spell`, `text1`, `text2`, `text3`, `text4`, `text5`, `model1`, `model2`, `aiscript` FROM `creature_movement` WHERE (abs(`position_x` - %f) <= %s ) and (abs(`position_y` - %f) <= %s ) and (abs(`position_z` - %f) <= %s )",
2665 pCreature
->GetPositionX(), maxDIFF
, pCreature
->GetPositionY(), maxDIFF
, pCreature
->GetPositionZ(), maxDIFF
);
2668 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2674 Field
*fields
= result
->Fetch();
2675 uint32 creGUID
= fields
[0].GetUInt32();
2676 uint32 point
= fields
[1].GetUInt32();
2677 int waittime
= fields
[2].GetUInt32();
2678 uint32 emote
= fields
[3].GetUInt32();
2679 uint32 spell
= fields
[4].GetUInt32();
2680 const char * text1
= fields
[5].GetString();
2681 const char * text2
= fields
[6].GetString();
2682 const char * text3
= fields
[7].GetString();
2683 const char * text4
= fields
[8].GetString();
2684 const char * text5
= fields
[9].GetString();
2685 uint32 model1
= fields
[10].GetUInt32();
2686 uint32 model2
= fields
[11].GetUInt32();
2687 const char * aiscript
= fields
[12].GetString();
2688 // Get the creature for which we read the waypoint
2689 Creature
* wpCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(creGUID
,HIGHGUID_UNIT
));
2691 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
2692 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
2693 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
2694 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
2695 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
2696 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
2697 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 1, text1
);
2698 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 2, text2
);
2699 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 3, text3
);
2700 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 4, text4
);
2701 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 5, text5
);
2702 PSendSysMessage(LANG_WAYPOINT_INFO_AISCRIPT
, aiscript
);
2704 }while( result
->NextRow() );
2712 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
2714 QueryResult
*result
= sDatabase
.PQuery( "SELECT `point`, `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
2717 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2720 // Delete all visuals for this NPC
2721 QueryResult
*result2
= sDatabase
.PQuery( "SELECT `wpguid` FROM `creature_movement` WHERE `id` = '%u' and wpguid <> 0", lowguid
);
2724 bool hasError
= false;
2727 Field
*fields
= result2
->Fetch();
2728 uint32 wpguid
= fields
[0].GetUInt32();
2729 Creature
* pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(wpguid
,HIGHGUID_UNIT
));
2733 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
2735 sDatabase
.PExecuteLog("DELETE FROM `creature` WHERE `guid` = '%u'", wpguid
);
2739 pCreature
->CombatStop(true);
2740 pCreature
->DeleteFromDB();
2741 ObjectAccessor::Instance().AddObjectToRemoveList(pCreature
);
2744 }while( result2
->NextRow() );
2748 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2749 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
2750 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
2756 Field
*fields
= result
->Fetch();
2757 uint32 point
= fields
[0].GetUInt32();
2758 float x
= fields
[1].GetFloat();
2759 float y
= fields
[2].GetFloat();
2760 float z
= fields
[3].GetFloat();
2762 uint32 id
= VISUAL_WAYPOINT
;
2764 Player
*chr
= m_session
->GetPlayer();
2765 float o
= chr
->GetOrientation();
2767 Creature
* wpCreature
= new Creature(chr
);
2768 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), chr
->GetMapId(), x
, y
, z
, o
, id
))
2770 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
2775 wpCreature
->SetVisibility(VISIBILITY_OFF
);
2776 sLog
.outDebug("DEBUG: UPDATE `creature_movement` SET `wpguid` = '%u");
2777 // set "wpguid" column to the visual waypoint
2778 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '%u' WHERE `id` = '%u' and `point` = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
2780 wpCreature
->SaveToDB();
2781 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2782 wpCreature
->LoadFromDB(wpCreature
->GetGUIDLow(), chr
->GetInstanceId());
2783 MapManager::Instance().GetMap(wpCreature
->GetMapId(), wpCreature
)->Add(wpCreature
);
2784 //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
2785 }while( result
->NextRow() );
2794 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
2796 QueryResult
*result
= sDatabase
.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point`='1' AND `id` = '%u'",lowguid
);
2799 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2803 Field
*fields
= result
->Fetch();
2804 float x
= fields
[0].GetFloat();
2805 float y
= fields
[1].GetFloat();
2806 float z
= fields
[2].GetFloat();
2807 uint32 id
= VISUAL_WAYPOINT
;
2809 Player
*chr
= m_session
->GetPlayer();
2810 float o
= chr
->GetOrientation();
2812 Creature
* pCreature
= new Creature(chr
);
2813 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), chr
->GetMapId(), x
, y
, z
, o
, id
))
2815 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
2821 pCreature
->SaveToDB();
2822 pCreature
->LoadFromDB(pCreature
->GetGUIDLow(), chr
->GetInstanceId());
2823 MapManager::Instance().GetMap(pCreature
->GetMapId(), pCreature
)->Add(pCreature
);
2824 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
2833 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
2835 QueryResult
*result
= sDatabase
.PQuery( "SELECT MAX(`point`) FROM `creature_movement` WHERE `id` = '%u'",lowguid
);
2838 Maxpoint
= (*result
)[0].GetUInt32();
2845 result
= sDatabase
.PQuery( "SELECT `position_x`,`position_y`,`position_z` FROM `creature_movement` WHERE `point` ='%u' AND `id` = '%u'",Maxpoint
, lowguid
);
2848 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
2851 Field
*fields
= result
->Fetch();
2852 float x
= fields
[0].GetFloat();
2853 float y
= fields
[1].GetFloat();
2854 float z
= fields
[2].GetFloat();
2855 uint32 id
= VISUAL_WAYPOINT
;
2857 Player
*chr
= m_session
->GetPlayer();
2858 float o
= chr
->GetOrientation();
2860 Creature
* pCreature
= new Creature(chr
);
2861 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), chr
->GetMapId(), x
, y
, z
, o
, id
))
2863 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
2869 pCreature
->SaveToDB();
2870 pCreature
->LoadFromDB(pCreature
->GetGUIDLow(), chr
->GetInstanceId());
2871 MapManager::Instance().GetMap(pCreature
->GetMapId(), pCreature
)->Add(pCreature
);
2872 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
2880 QueryResult
*result
= sDatabase
.PQuery("SELECT `guid` FROM `creature` WHERE `id` = '%d'", VISUAL_WAYPOINT
);
2883 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
2886 bool hasError
= false;
2889 Field
*fields
= result
->Fetch();
2890 uint32 guid
= fields
[0].GetUInt32();
2891 Creature
* pCreature
= ObjectAccessor::Instance().GetCreature(*m_session
->GetPlayer(),MAKE_GUID(guid
,HIGHGUID_UNIT
));
2893 //Creature* pCreature = ObjectAccessor::Instance().GetCreature(*m_session->GetPlayer(), guid);
2897 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
2899 sDatabase
.PExecuteLog("DELETE FROM `creature` WHERE `guid` = '%u'", guid
);
2903 pCreature
->CombatStop(true);
2905 pCreature
->DeleteFromDB();
2907 ObjectAccessor::Instance().AddObjectToRemoveList(pCreature
);
2909 }while(result
->NextRow());
2910 // set "wpguid" column to "empty" - no visual waypoint spawned
2911 sDatabase
.PExecuteLog("UPDATE `creature_movement` SET `wpguid` = '0'");
2915 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2916 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
2917 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
2920 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
2927 PSendSysMessage("DEBUG: wpshow - no valid command found");
2930 } // HandleWpShowCommand
2933 bool ChatHandler::HandleRenameCommand(const char* args
)
2935 Player
* target
= NULL
;
2936 uint64 targetGUID
= 0;
2937 std::string oldname
;
2939 char* px
= strtok((char*)args
, " ");
2944 normalizePlayerName(oldname
);
2945 //sDatabase.escape_string(oldname);
2946 target
= objmgr
.GetPlayer(oldname
.c_str());
2949 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
2952 if(!target
&& !targetGUID
)
2954 target
= getSelectedPlayer();
2957 if(!target
&& !targetGUID
)
2959 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2965 PSendSysMessage(LANG_RENAME_PLAYER
, target
->GetName());
2966 target
->SetNeedRename(true);
2967 sDatabase
.PExecute("UPDATE `character` SET `rename` = '1' WHERE `guid` = '%u'", target
->GetGUIDLow());
2971 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
2972 sDatabase
.PExecute("UPDATE `character` SET `rename` = '1' WHERE `guid` = '%u'", GUID_LOPART(targetGUID
));
2979 bool ChatHandler::HandleGameObjectCommand(const char* args
)
2984 char* pParam1
= strtok((char*)args
, " ");
2985 uint32 id
= atoi((char*)pParam1
);
2989 char* lootID
= strtok(NULL
, " ");
2990 char* spawntimeSecs
= strtok(NULL
, " ");
2992 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
2996 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
3000 Player
*chr
= m_session
->GetPlayer();
3001 float x
= float(chr
->GetPositionX());
3002 float y
= float(chr
->GetPositionY());
3003 float z
= float(chr
->GetPositionZ());
3004 float o
= float(chr
->GetOrientation());
3006 float rot2
= sin(o
/2);
3007 float rot3
= cos(o
/2);
3009 GameObject
* pGameObj
= new GameObject(chr
);
3010 uint32 lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
3012 if(!pGameObj
->Create(lowGUID
, goI
->id
, chr
->GetMapId(), x
, y
, z
, o
, 0, 0, rot2
, rot3
, 0, 0))
3017 //pGameObj->SetZoneId(chr->GetZoneId());
3018 pGameObj
->SetMapId(chr
->GetMapId());
3019 //pGameObj->SetNameId(id);
3020 sLog
.outDebug(LANG_GAMEOBJECT_CURRENT
, goI
->name
, lowGUID
, x
, y
, z
, o
);
3024 uint32 value
= atoi((char*)lootID
);
3025 pGameObj
->lootid
= value
;
3026 //sLog.outDebug("*** LOOT: %d", value);
3031 uint32 value
= atoi((char*)spawntimeSecs
);
3032 pGameObj
->SetRespawnTime(value
);
3033 //sLog.outDebug("*** spawntimeSecs: %d", value);
3036 pGameObj
->SaveToDB();
3037 MapManager::Instance().GetMap(pGameObj
->GetMapId(), pGameObj
)->Add(pGameObj
);
3039 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,goI
->name
,lowGUID
,x
,y
,z
);
3045 bool ChatHandler::HandleAnimCommand(const char* args
)
3050 uint32 anim_id
= atoi((char*)args
);
3052 WorldPacket
data( SMSG_EMOTE
, (8+4) );
3053 data
<< anim_id
<< m_session
->GetPlayer( )->GetGUID();
3054 WPAssert(data
.size() == 12);
3055 MapManager::Instance().GetMap(m_session
->GetPlayer()->GetMapId(), m_session
->GetPlayer())->MessageBoardcast(m_session
->GetPlayer(), &data
, true);
3060 bool ChatHandler::HandleStandStateCommand(const char* args
)
3065 uint32 anim_id
= atoi((char*)args
);
3066 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);