2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "WorldSession.h"
24 #include "ObjectMgr.h"
27 #include "GameObject.h"
30 #include "ObjectAccessor.h"
31 #include "MapManager.h"
34 #include "GameEvent.h"
36 #include "AccountMgr.h"
37 #include "WaypointManager.h"
43 #include "GlobalEvents.h"
45 static uint32 ReputationRankStrIndex
[MAX_REPUTATION_RANK
] =
47 LANG_REP_HATED
, LANG_REP_HOSTILE
, LANG_REP_UNFRIENDLY
, LANG_REP_NEUTRAL
,
48 LANG_REP_FRIENDLY
, LANG_REP_HONORED
, LANG_REP_REVERED
, LANG_REP_EXALTED
51 //mute player for some times
52 bool ChatHandler::HandleMuteCommand(const char* args
)
57 char *charname
= strtok((char*)args
, " ");
61 std::string cname
= charname
;
63 char *timetonotspeak
= strtok(NULL
, " ");
67 uint32 notspeaktime
= (uint32
) atoi(timetonotspeak
);
69 if(!normalizePlayerName(cname
))
71 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
72 SetSentErrorMessage(true);
76 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
79 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
80 SetSentErrorMessage(true);
84 Player
*chr
= objmgr
.GetPlayer(guid
);
87 uint32 account_id
= 0;
92 account_id
= chr
->GetSession()->GetAccountId();
93 security
= chr
->GetSession()->GetSecurity();
97 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
98 security
= accmgr
.GetSecurity(account_id
);
101 if(m_session
&& security
>= m_session
->GetSecurity())
103 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
104 SetSentErrorMessage(true);
108 time_t mutetime
= time(NULL
) + notspeaktime
*60;
111 chr
->GetSession()->m_muteTime
= mutetime
;
113 loginDatabase
.PExecute("UPDATE account SET mutetime = " I64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
116 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
118 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, cname
.c_str(), notspeaktime
);
124 bool ChatHandler::HandleUnmuteCommand(const char* args
)
129 char *charname
= strtok((char*)args
, " ");
133 std::string cname
= charname
;
135 if(!normalizePlayerName(cname
))
137 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
138 SetSentErrorMessage(true);
142 uint64 guid
= objmgr
.GetPlayerGUIDByName(cname
.c_str());
145 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
146 SetSentErrorMessage(true);
150 Player
*chr
= objmgr
.GetPlayer(guid
);
153 uint32 account_id
= 0;
158 account_id
= chr
->GetSession()->GetAccountId();
159 security
= chr
->GetSession()->GetSecurity();
163 account_id
= objmgr
.GetPlayerAccountIdByGUID(guid
);
164 security
= accmgr
.GetSecurity(account_id
);
167 if(m_session
&& security
>= m_session
->GetSecurity())
169 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW
);
170 SetSentErrorMessage(true);
178 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
179 SetSentErrorMessage(true);
183 chr
->GetSession()->m_muteTime
= 0;
186 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
189 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
191 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, cname
.c_str());
195 bool ChatHandler::HandleTargetObjectCommand(const char* args
)
197 Player
* pl
= m_session
->GetPlayer();
199 GameEvent::ActiveEvents
const& activeEventsList
= gameeventmgr
.GetActiveEventList();
202 int32 id
= atoi((char*)args
);
204 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",
205 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
208 std::string name
= args
;
209 WorldDatabase
.escape_string(name
);
210 result
= WorldDatabase
.PQuery(
211 "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_ "
212 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
213 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
218 std::ostringstream eventFilter
;
219 eventFilter
<< " AND (event IS NULL ";
220 bool initString
= true;
222 for (GameEvent::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
226 eventFilter
<< "OR event IN (" <<*itr
;
230 eventFilter
<< "," << *itr
;
238 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
239 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
240 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
241 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
246 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
250 Field
*fields
= result
->Fetch();
251 uint32 lowguid
= fields
[0].GetUInt32();
252 uint32 id
= fields
[1].GetUInt32();
253 float x
= fields
[2].GetFloat();
254 float y
= fields
[3].GetFloat();
255 float z
= fields
[4].GetFloat();
256 float o
= fields
[5].GetFloat();
257 int mapid
= fields
[6].GetUInt16();
260 GameObjectInfo
const* goI
= objmgr
.GetGameObjectInfo(id
);
264 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
268 GameObject
* target
= ObjectAccessor::GetGameObject(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
270 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
274 int32 curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
275 if(curRespawnDelay
< 0)
278 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
279 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
281 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
286 //teleport to gameobject
287 bool ChatHandler::HandleGoObjectCommand(const char* args
)
292 Player
* _player
= m_session
->GetPlayer();
294 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
295 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
299 int32 guid
= atoi(cId
);
307 if (GameObjectData
const* go_data
= objmgr
.GetGOData(guid
))
312 ort
= go_data
->orientation
;
313 mapid
= go_data
->mapid
;
317 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
318 SetSentErrorMessage(true);
322 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
324 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
325 SetSentErrorMessage(true);
329 // stop flight if need
330 if(_player
->isInFlight())
332 _player
->GetMotionMaster()->MovementExpired();
333 _player
->m_taxi
.ClearTaxiDestinations();
335 // save only in non-flight case
337 _player
->SaveRecallPosition();
339 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
343 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
345 Player
* _player
= m_session
->GetPlayer();
350 char *atId
= strtok((char*)args
, " ");
354 int32 i_atId
= atoi(atId
);
359 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
362 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
363 SetSentErrorMessage(true);
367 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
369 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
370 SetSentErrorMessage(true);
374 // stop flight if need
375 if(_player
->isInFlight())
377 _player
->GetMotionMaster()->MovementExpired();
378 _player
->m_taxi
.ClearTaxiDestinations();
380 // save only in non-flight case
382 _player
->SaveRecallPosition();
384 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
388 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
390 Player
* _player
= m_session
->GetPlayer();
395 char *gyId
= strtok((char*)args
, " ");
399 int32 i_gyId
= atoi(gyId
);
404 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
407 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
408 SetSentErrorMessage(true);
412 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
414 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
415 SetSentErrorMessage(true);
419 // stop flight if need
420 if(_player
->isInFlight())
422 _player
->GetMotionMaster()->MovementExpired();
423 _player
->m_taxi
.ClearTaxiDestinations();
425 // save only in non-flight case
427 _player
->SaveRecallPosition();
429 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
433 /** \brief Teleport the GM to the specified creature
435 * .gocreature <GUID> --> TP using creature.guid
436 * .gocreature azuregos --> TP player to the mob with this name
437 * Warning: If there is more than one mob with this name
438 * you will be teleported to the first one that is found.
439 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
440 * Warning: If there is more than one mob with this "id"
441 * you will be teleported to the first one that is found.
443 //teleport to creature
444 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
448 Player
* _player
= m_session
->GetPlayer();
450 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
451 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
455 std::ostringstream whereClause
;
457 // User wants to teleport to the NPC's template entry
458 if( strcmp(pParam1
, "id") == 0 )
460 //sLog.outError("DEBUG: ID found");
462 // Get the "creature_template.entry"
463 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
464 char* tail
= strtok(NULL
,"");
467 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
471 int32 tEntry
= atoi(cId
);
472 //sLog.outError("DEBUG: ID value: %d", tEntry);
476 whereClause
<< "WHERE id = '" << tEntry
<< "'";
480 //sLog.outError("DEBUG: ID *not found*");
482 int32 guid
= atoi(pParam1
);
484 // Number is invalid - maybe the user specified the mob's name
487 std::string name
= pParam1
;
488 WorldDatabase
.escape_string(name
);
489 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
493 whereClause
<< "WHERE guid = '" << guid
<< "'";
496 //sLog.outError("DEBUG: %s", whereClause.c_str());
498 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
501 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
502 SetSentErrorMessage(true);
505 if( result
->GetRowCount() > 1 )
507 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
510 Field
*fields
= result
->Fetch();
511 float x
= fields
[0].GetFloat();
512 float y
= fields
[1].GetFloat();
513 float z
= fields
[2].GetFloat();
514 float ort
= fields
[3].GetFloat();
515 int mapid
= fields
[4].GetUInt16();
519 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
521 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
522 SetSentErrorMessage(true);
526 // stop flight if need
527 if(_player
->isInFlight())
529 _player
->GetMotionMaster()->MovementExpired();
530 _player
->m_taxi
.ClearTaxiDestinations();
532 // save only in non-flight case
534 _player
->SaveRecallPosition();
536 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
540 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
542 uint64 guid
= m_session
->GetPlayer()->GetSelection();
546 SendSysMessage(LANG_NO_SELECTION
);
547 SetSentErrorMessage(true);
551 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
555 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
560 // Can be NULL at console call
561 Player
*target
= getSelectedPlayer ();
563 std::string namepart
= args
;
564 std::wstring wnamepart
;
566 if (!Utf8toWStr (namepart
,wnamepart
))
569 // converting string that we try to find to lower case
570 wstrToLower (wnamepart
);
572 uint32 counter
= 0; // Counter for figure out that we found smth.
574 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
576 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
579 FactionState
const* repState
= NULL
;
582 FactionStateList::const_iterator repItr
= target
->m_factions
.find (factionEntry
->reputationListID
);
583 if(repItr
!= target
->m_factions
.end())
584 repState
= &repItr
->second
;
588 int loc
= m_session
? m_session
->GetSessionDbcLocale() : sWorld
.GetDefaultDbcLocale();
589 std::string name
= factionEntry
->name
[loc
];
593 if (!Utf8FitTo(name
, wnamepart
))
596 for(; loc
< MAX_LOCALE
; ++loc
)
598 if(m_session
&& loc
==m_session
->GetSessionDbcLocale())
601 name
= factionEntry
->name
[loc
];
605 if (Utf8FitTo(name
, wnamepart
))
612 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
613 // or "id - [faction] [no reputation]" format
614 std::ostringstream ss
;
616 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
618 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
620 if (repState
) // and then target!=NULL also
622 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
623 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
625 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
627 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
628 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
629 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
630 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
631 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
632 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
633 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
634 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
635 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
636 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
637 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
638 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
641 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
643 SendSysMessage(ss
.str().c_str());
649 if (counter
== 0) // if counter == 0 then we found nth
650 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
654 bool ChatHandler::HandleModifyRepCommand(const char * args
)
656 if (!*args
) return false;
658 Player
* target
= NULL
;
659 target
= getSelectedPlayer();
663 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
664 SetSentErrorMessage(true);
668 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
672 uint32 factionId
= atoi(factionTxt
);
675 char *rankTxt
= strtok(NULL
, " ");
676 if (!factionTxt
|| !rankTxt
)
679 amount
= atoi(rankTxt
);
680 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
682 std::string rankStr
= rankTxt
;
683 std::wstring wrankStr
;
684 if(!Utf8toWStr(rankStr
,wrankStr
))
686 wstrToLower( wrankStr
);
690 for (; r
< MAX_REPUTATION_RANK
; ++r
)
692 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
697 if(!Utf8toWStr(rank
,wrank
))
702 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
704 char *deltaTxt
= strtok(NULL
, " ");
707 int32 delta
= atoi(deltaTxt
);
708 if ((delta
< 0) || (delta
> Player::ReputationRank_Length
[r
] -1))
710 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (Player::ReputationRank_Length
[r
]-1));
711 SetSentErrorMessage(true);
718 amount
+= Player::ReputationRank_Length
[r
];
720 if (r
>= MAX_REPUTATION_RANK
)
722 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
723 SetSentErrorMessage(true);
728 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
732 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
733 SetSentErrorMessage(true);
737 if (factionEntry
->reputationListID
< 0)
739 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
);
740 SetSentErrorMessage(true);
744 target
->SetFactionReputation(factionEntry
,amount
);
745 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
, target
->GetName(), target
->GetReputation(factionId
));
749 bool ChatHandler::HandleNameCommand(const char* args
)
755 if(strlen((char*)args)>75)
757 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
761 for (uint8 i = 0; i < strlen(args); i++)
763 if(!isalpha(args[i]) && args[i]!=' ')
765 SendSysMessage(LANG_CHARS_ONLY);
771 guid = m_session->GetPlayer()->GetSelection();
774 SendSysMessage(LANG_NO_SELECTION);
778 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
782 SendSysMessage(LANG_SELECT_CREATURE);
786 pCreature->SetName(args);
787 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
788 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
790 pCreature->SaveToDB();
796 bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
803 if(strlen((char*)args)>75)
806 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
810 for (uint8 i = 0; i < strlen(args); i++)
812 if(!isalpha(args[i]) && args[i]!=' ')
814 SendSysMessage(LANG_CHARS_ONLY);
819 guid = m_session->GetPlayer()->GetSelection();
822 SendSysMessage(LANG_NO_SELECTION);
826 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
830 SendSysMessage(LANG_SELECT_CREATURE);
834 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
835 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
837 pCreature->SaveToDB();
842 //move item to other slot
843 bool ChatHandler::HandleItemMoveCommand(const char* args
)
847 uint8 srcslot
, dstslot
;
849 char* pParam1
= strtok((char*)args
, " ");
853 char* pParam2
= strtok(NULL
, " ");
857 srcslot
= (uint8
)atoi(pParam1
);
858 dstslot
= (uint8
)atoi(pParam2
);
860 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
861 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
866 m_session
->GetPlayer()->SwapItem( src
, dst
);
871 //add spawn of creature
872 bool ChatHandler::HandleAddSpwCommand(const char* args
)
876 char* charID
= strtok((char*)args
, " ");
880 char* team
= strtok(NULL
, " ");
882 if (team
) { teamval
= atoi(team
); }
883 if (teamval
< 0) { teamval
= 0; }
885 uint32 id
= atoi(charID
);
887 Player
*chr
= m_session
->GetPlayer();
888 float x
= chr
->GetPositionX();
889 float y
= chr
->GetPositionY();
890 float z
= chr
->GetPositionZ();
891 float o
= chr
->GetOrientation();
892 Map
*map
= chr
->GetMap();
894 Creature
* pCreature
= new Creature
;
895 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, (uint32
)teamval
))
901 pCreature
->Relocate(x
,y
,z
,o
);
903 if(!pCreature
->IsPositionValid())
905 sLog
.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature
->GetGUIDLow(),pCreature
->GetEntry(),pCreature
->GetPositionX(),pCreature
->GetPositionY());
910 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
912 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
914 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
915 pCreature
->LoadFromDB(db_guid
, map
);
918 objmgr
.AddCreatureToGrid(db_guid
, objmgr
.GetCreatureData(db_guid
));
922 bool ChatHandler::HandleDelCreatureCommand(const char* args
)
924 Creature
* unit
= NULL
;
928 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
929 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
933 uint32 lowguid
= atoi(cId
);
937 if (CreatureData
const* cr_data
= objmgr
.GetCreatureData(lowguid
))
938 unit
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
941 unit
= getSelectedCreature();
943 if(!unit
|| unit
->isPet() || unit
->isTotem())
945 SendSysMessage(LANG_SELECT_CREATURE
);
946 SetSentErrorMessage(true);
950 // Delete the creature
952 unit
->DeleteFromDB();
953 unit
->CleanupsBeforeDelete();
954 unit
->AddObjectToRemoveList();
956 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
961 //delete object by selection or guid
962 bool ChatHandler::HandleDelObjectCommand(const char* args
)
964 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
965 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
969 uint32 lowguid
= atoi(cId
);
973 GameObject
* obj
= NULL
;
976 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
977 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
981 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
982 SetSentErrorMessage(true);
986 uint64 owner_guid
= obj
->GetOwnerGUID();
989 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
990 if(!owner
&& !IS_PLAYER_GUID(owner_guid
))
992 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
993 SetSentErrorMessage(true);
997 owner
->RemoveGameObject(obj
,false);
1000 obj
->SetRespawnTime(0); // not save respawn time
1002 obj
->DeleteFromDB();
1004 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
1009 //turn selected object
1010 bool ChatHandler::HandleTurnObjectCommand(const char* args
)
1012 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
1013 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1017 uint32 lowguid
= atoi(cId
);
1021 GameObject
* obj
= NULL
;
1024 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1025 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1029 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1030 SetSentErrorMessage(true);
1034 char* po
= strtok(NULL
, " ");
1039 o
= (float)atof(po
);
1043 Player
*chr
= m_session
->GetPlayer();
1044 o
= chr
->GetOrientation();
1047 float rot2
= sin(o
/2);
1048 float rot3
= cos(o
/2);
1050 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
1051 map
->Remove(obj
,false);
1053 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
1055 obj
->SetFloatValue(GAMEOBJECT_FACING
, o
);
1056 obj
->SetFloatValue(GAMEOBJECT_ROTATION
+2, rot2
);
1057 obj
->SetFloatValue(GAMEOBJECT_ROTATION
+3, rot3
);
1064 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), o
);
1069 //move selected creature
1070 bool ChatHandler::HandleMoveCreatureCommand(const char* args
)
1074 Creature
* pCreature
= getSelectedCreature();
1078 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1079 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1083 uint32 lowguid
= atoi(cId
);
1085 /* FIXME: impossibel without entry
1087 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1090 // Attempting creature load from DB data
1093 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1096 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1097 SetSentErrorMessage(true);
1101 uint32 map_id
= data
->mapid
;
1103 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1105 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1106 SetSentErrorMessage(true);
1112 lowguid
= pCreature
->GetDBTableGUIDLow();
1117 lowguid
= pCreature
->GetDBTableGUIDLow();
1120 float x
= m_session
->GetPlayer()->GetPositionX();
1121 float y
= m_session
->GetPlayer()->GetPositionY();
1122 float z
= m_session
->GetPlayer()->GetPositionZ();
1123 float o
= m_session
->GetPlayer()->GetOrientation();
1127 if(CreatureData
const* data
= objmgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1129 const_cast<CreatureData
*>(data
)->posX
= x
;
1130 const_cast<CreatureData
*>(data
)->posY
= y
;
1131 const_cast<CreatureData
*>(data
)->posZ
= z
;
1132 const_cast<CreatureData
*>(data
)->orientation
= o
;
1134 MapManager::Instance().GetMap(pCreature
->GetMapId(),pCreature
)->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1135 pCreature
->GetMotionMaster()->Initialize();
1136 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1138 pCreature
->setDeathState(JUST_DIED
);
1139 pCreature
->Respawn();
1143 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1144 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1148 //move selected object
1149 bool ChatHandler::HandleMoveObjectCommand(const char* args
)
1151 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1152 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1156 uint32 lowguid
= atoi(cId
);
1160 GameObject
* obj
= NULL
;
1163 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1164 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1168 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1169 SetSentErrorMessage(true);
1173 char* px
= strtok(NULL
, " ");
1174 char* py
= strtok(NULL
, " ");
1175 char* pz
= strtok(NULL
, " ");
1179 Player
*chr
= m_session
->GetPlayer();
1181 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
1182 map
->Remove(obj
,false);
1184 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
1185 obj
->SetFloatValue(GAMEOBJECT_POS_X
, chr
->GetPositionX());
1186 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, chr
->GetPositionY());
1187 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, chr
->GetPositionZ());
1196 float x
= (float)atof(px
);
1197 float y
= (float)atof(py
);
1198 float z
= (float)atof(pz
);
1200 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
1202 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
1203 SetSentErrorMessage(true);
1207 Map
* map
= MapManager::Instance().GetMap(obj
->GetMapId(),obj
);
1208 map
->Remove(obj
,false);
1210 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
1211 obj
->SetFloatValue(GAMEOBJECT_POS_X
, x
);
1212 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, y
);
1213 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, z
);
1221 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow());
1226 //demorph player or unit
1227 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1229 Unit
*target
= getSelectedUnit();
1231 target
= m_session
->GetPlayer();
1238 //add item in vendorlist
1239 bool ChatHandler::HandleAddVendorItemCommand(const char* args
)
1244 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1247 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1248 SetSentErrorMessage(true);
1252 uint32 itemId
= atol(pitem
);
1254 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1255 uint32 maxcount
= 0;
1257 maxcount
= atol(fmaxcount
);
1259 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1260 uint32 incrtime
= 0;
1262 incrtime
= atol(fincrtime
);
1264 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1265 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1267 Creature
* vendor
= getSelectedCreature();
1269 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1271 if(!objmgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1273 SetSentErrorMessage(true);
1277 objmgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1279 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1281 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1285 //del item from vendor list
1286 bool ChatHandler::HandleDelVendorItemCommand(const char* args
)
1291 Creature
* vendor
= getSelectedCreature();
1292 if (!vendor
|| !vendor
->isVendor())
1294 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1295 SetSentErrorMessage(true);
1299 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1302 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1303 SetSentErrorMessage(true);
1306 uint32 itemId
= atol(pitem
);
1308 if(!objmgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1310 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1311 SetSentErrorMessage(true);
1315 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1317 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1321 //add move for creature
1322 bool ChatHandler::HandleAddMoveCommand(const char* args
)
1327 char* guid_str
= strtok((char*)args
, " ");
1328 char* wait_str
= strtok((char*)NULL
, " ");
1330 uint32 lowguid
= atoi((char*)guid_str
);
1332 Creature
* pCreature
= NULL
;
1334 /* FIXME: impossible without entry
1336 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1339 // attempt check creature existence by DB data
1342 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1345 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1346 SetSentErrorMessage(true);
1352 // obtain real GUID for DB operations
1353 lowguid
= pCreature
->GetDBTableGUIDLow();
1356 int wait
= wait_str
? atoi(wait_str
) : 0;
1361 Player
* player
= m_session
->GetPlayer();
1363 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1365 // update movement type
1366 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1369 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1370 pCreature
->GetMotionMaster()->Initialize();
1371 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1373 pCreature
->setDeathState(JUST_DIED
);
1374 pCreature
->Respawn();
1376 pCreature
->SaveToDB();
1379 SendSysMessage(LANG_WAYPOINT_ADDED
);
1385 * Set the movement type for an NPC.<br/>
1387 * Valid movement types are:
1389 * <li> stay - NPC wont move </li>
1390 * <li> random - NPC will move randomly according to the spawndist </li>
1391 * <li> way - NPC will move with given waypoints set </li>
1393 * additional parameter: NODEL - so no waypoints are deleted, if you
1394 * change the movement type
1396 bool ChatHandler::HandleSetMoveTypeCommand(const char* args
)
1402 // GUID (optional - you can also select the creature)
1403 // stay|random|way (determines the kind of movement)
1404 // NODEL (optional - tells the system NOT to delete any waypoints)
1405 // this is very handy if you want to do waypoints, that are
1406 // later switched on/off according to special events (like escort
1408 char* guid_str
= strtok((char*)args
, " ");
1409 char* type_str
= strtok((char*)NULL
, " ");
1410 char* dontdel_str
= strtok((char*)NULL
, " ");
1412 bool doNotDelete
= false;
1418 Creature
* pCreature
= NULL
;
1422 //sLog.outError("DEBUG: All 3 params are set");
1424 // All 3 params are set
1428 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1430 //sLog.outError("DEBUG: doNotDelete = true;");
1436 // Only 2 params - but maybe NODEL is set
1439 sLog
.outError("DEBUG: Only 2 params ");
1440 if( stricmp( type_str
, "NODEL" ) == 0 )
1442 //sLog.outError("DEBUG: type_str, NODEL ");
1449 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1451 type_str
= guid_str
;
1452 pCreature
= getSelectedCreature();
1453 if(!pCreature
|| pCreature
->isPet())
1455 lowguid
= pCreature
->GetDBTableGUIDLow();
1457 else // case .setmovetype #creature_guid $move_type (with selected creature)
1459 lowguid
= atoi((char*)guid_str
);
1461 /* impossible without entry
1463 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1466 // attempt check creature existence by DB data
1469 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1472 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1473 SetSentErrorMessage(true);
1479 lowguid
= pCreature
->GetDBTableGUIDLow();
1483 // now lowguid is low guid really existed creature
1484 // and pCreature point (maybe) to this creature or NULL
1486 MovementGeneratorType move_type
;
1488 std::string type
= type_str
;
1491 move_type
= IDLE_MOTION_TYPE
;
1492 else if(type
== "random")
1493 move_type
= RANDOM_MOTION_TYPE
;
1494 else if(type
== "way")
1495 move_type
= WAYPOINT_MOTION_TYPE
;
1499 // update movement type
1500 if(doNotDelete
== false)
1501 WaypointMgr
.DeletePath(lowguid
);
1505 pCreature
->SetDefaultMovementType(move_type
);
1506 pCreature
->GetMotionMaster()->Initialize();
1507 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1509 pCreature
->setDeathState(JUST_DIED
);
1510 pCreature
->Respawn();
1512 pCreature
->SaveToDB();
1514 if( doNotDelete
== false )
1516 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1520 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1524 } // HandleSetMoveTypeCommand
1526 //change level of creature or pet
1527 bool ChatHandler::HandleChangeLevelCommand(const char* args
)
1532 uint8 lvl
= (uint8
) atoi((char*)args
);
1533 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1535 SendSysMessage(LANG_BAD_VALUE
);
1536 SetSentErrorMessage(true);
1540 Creature
* pCreature
= getSelectedCreature();
1543 SendSysMessage(LANG_SELECT_CREATURE
);
1544 SetSentErrorMessage(true);
1548 if(pCreature
->isPet())
1550 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1554 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1555 pCreature
->SetHealth( 100 + 30*lvl
);
1556 pCreature
->SetLevel( lvl
);
1557 pCreature
->SaveToDB();
1563 //set npcflag of creature
1564 bool ChatHandler::HandleNPCFlagCommand(const char* args
)
1569 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1571 Creature
* pCreature
= getSelectedCreature();
1575 SendSysMessage(LANG_SELECT_CREATURE
);
1576 SetSentErrorMessage(true);
1580 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1582 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1584 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1589 //set model of creature
1590 bool ChatHandler::HandleSetModelCommand(const char* args
)
1595 uint32 displayId
= (uint32
) atoi((char*)args
);
1597 Creature
*pCreature
= getSelectedCreature();
1599 if(!pCreature
|| pCreature
->isPet())
1601 SendSysMessage(LANG_SELECT_CREATURE
);
1602 SetSentErrorMessage(true);
1606 pCreature
->SetDisplayId(displayId
);
1607 pCreature
->SetNativeDisplayId(displayId
);
1609 pCreature
->SaveToDB();
1614 //morph creature or player
1615 bool ChatHandler::HandleMorphCommand(const char* args
)
1620 uint16 display_id
= (uint16
)atoi((char*)args
);
1622 Unit
*target
= getSelectedUnit();
1624 target
= m_session
->GetPlayer();
1626 target
->SetDisplayId(display_id
);
1631 //set faction of creature or go
1632 bool ChatHandler::HandleFactionIdCommand(const char* args
)
1637 uint32 factionId
= (uint32
) atoi((char*)args
);
1639 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1641 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1642 SetSentErrorMessage(true);
1646 Creature
* pCreature
= getSelectedCreature();
1650 SendSysMessage(LANG_SELECT_CREATURE
);
1651 SetSentErrorMessage(true);
1655 pCreature
->setFaction(factionId
);
1657 // faction is set in creature_template - not inside creature
1660 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1662 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1663 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1667 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1673 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
1675 char* kickName
= strtok((char*)args
, " ");
1678 Player
* player
= getSelectedPlayer();
1682 SendSysMessage(LANG_NO_CHAR_SELECTED
);
1683 SetSentErrorMessage(true);
1687 if(player
==m_session
->GetPlayer())
1689 SendSysMessage(LANG_COMMAND_KICKSELF
);
1690 SetSentErrorMessage(true);
1694 player
->GetSession()->KickPlayer();
1698 std::string name
= kickName
;
1699 if(!normalizePlayerName(name
))
1701 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1702 SetSentErrorMessage(true);
1706 if(m_session
&& name
==m_session
->GetPlayer()->GetName())
1708 SendSysMessage(LANG_COMMAND_KICKSELF
);
1709 SetSentErrorMessage(true);
1713 if(sWorld
.KickPlayer(name
))
1715 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,name
.c_str());
1718 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER
,name
.c_str());
1724 //show info of player
1725 bool ChatHandler::HandlePInfoCommand(const char* args
)
1727 Player
* target
= NULL
;
1728 uint64 targetGUID
= 0;
1730 char* px
= strtok((char*)args
, " ");
1742 if(!normalizePlayerName(name
))
1744 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1745 SetSentErrorMessage(true);
1749 target
= objmgr
.GetPlayer(name
.c_str());
1751 py
= strtok(NULL
, " ");
1754 targetGUID
= objmgr
.GetPlayerGUIDByName(name
);
1756 py
= strtok(NULL
, " ");
1762 if(!target
&& !targetGUID
)
1764 target
= getSelectedPlayer();
1767 if(!target
&& !targetGUID
)
1769 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1770 SetSentErrorMessage(true);
1776 uint32 total_player_time
= 0;
1780 // get additional information from Player object
1783 targetGUID
= target
->GetGUID();
1784 name
= target
->GetName(); // re-read for case getSelectedPlayer() target
1785 accId
= target
->GetSession()->GetAccountId();
1786 money
= target
->GetMoney();
1787 total_player_time
= target
->GetTotalPlayedTime();
1788 level
= target
->getLevel();
1789 latency
= target
->GetSession()->GetLatency();
1791 // get additional information from DB
1794 accId
= objmgr
.GetPlayerAccountIdByGUID(targetGUID
);
1795 Player
plr(m_session
); // use current session for temporary load
1796 plr
.MinimalLoadFromDB(NULL
, targetGUID
);
1797 money
= plr
.GetMoney();
1798 total_player_time
= plr
.GetTotalPlayedTime();
1799 level
= plr
.getLevel();
1802 std::string username
= GetMangosString(LANG_ERROR
);
1803 std::string last_ip
= GetMangosString(LANG_ERROR
);
1804 uint32 security
= 0;
1805 std::string last_login
= GetMangosString(LANG_ERROR
);
1807 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
1810 Field
* fields
= result
->Fetch();
1811 username
= fields
[0].GetCppString();
1812 security
= fields
[1].GetUInt32();
1814 if(!m_session
|| m_session
->GetSecurity() >= security
)
1816 last_ip
= fields
[2].GetCppString();
1817 last_login
= fields
[3].GetCppString();
1828 PSendSysMessage(LANG_PINFO_ACCOUNT
, (target
?"":GetMangosString(LANG_OFFLINE
)), name
.c_str(), GUID_LOPART(targetGUID
), username
.c_str(), accId
, security
, last_ip
.c_str(), last_login
.c_str(), latency
);
1830 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
1831 uint32 gold
= money
/GOLD
;
1832 uint32 silv
= (money
% GOLD
) / SILVER
;
1833 uint32 copp
= (money
% GOLD
) % SILVER
;
1834 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
1836 if ( py
&& strncmp(py
, "rep", 3) == 0 )
1840 // rep option not implemented for offline case
1841 SendSysMessage(LANG_PINFO_NO_REP
);
1842 SetSentErrorMessage(true);
1847 for(FactionStateList::const_iterator itr
= target
->m_factions
.begin(); itr
!= target
->m_factions
.end(); ++itr
)
1849 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
1851 FactionName
= factionEntry
->name
[m_session
->GetSessionDbcLocale()];
1853 FactionName
= "#Not found#";
1854 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
1855 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
1856 std::ostringstream ss
;
1857 ss
<< itr
->second
.ID
<< ": |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << FactionName
<< "]|h|r " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
1859 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
1860 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
1861 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
1862 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
1863 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
1864 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
1865 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
1866 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
1867 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
1868 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
1869 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
1870 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
1872 SendSysMessage(ss
.str().c_str());
1879 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
1882 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
1883 name
= GetMangosString(LANG_UNKNOWN
);
1885 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, name
.c_str(),time
,text
);
1889 bool ChatHandler::HandleTicketCommand(const char* args
)
1891 char* px
= strtok((char*)args
, " ");
1898 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1899 SetSentErrorMessage(true);
1904 QueryResult
*result
= CharacterDatabase
.Query("SELECT COUNT(ticket_id) FROM character_ticket");
1907 count
= (*result
)[0].GetUInt32();
1913 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
1915 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
1920 if(strncmp(px
,"on",3) == 0)
1924 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1925 SetSentErrorMessage(true);
1929 m_session
->GetPlayer()->SetAcceptTicket(true);
1930 SendSysMessage(LANG_COMMAND_TICKETON
);
1935 if(strncmp(px
,"off",4) == 0)
1939 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1940 SetSentErrorMessage(true);
1944 m_session
->GetPlayer()->SetAcceptTicket(false);
1945 SendSysMessage(LANG_COMMAND_TICKETOFF
);
1953 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC LIMIT %d,1",num
-1);
1957 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1959 SetSentErrorMessage(true);
1963 Field
* fields
= result
->Fetch();
1965 uint64 guid
= fields
[0].GetUInt64();
1966 char const* text
= fields
[1].GetString();
1967 char const* time
= fields
[2].GetString();
1969 ShowTicket(guid
,text
,time
);
1974 std::string name
= px
;
1976 if(!normalizePlayerName(name
))
1978 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1979 SetSentErrorMessage(true);
1983 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
1988 // ticket $char_name
1989 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid
));
1994 Field
* fields
= result
->Fetch();
1996 char const* text
= fields
[0].GetString();
1997 char const* time
= fields
[1].GetString();
1999 ShowTicket(guid
,text
,time
);
2005 uint32
ChatHandler::GetTicketIDByNum(uint32 num
)
2007 QueryResult
*result
= CharacterDatabase
.Query("SELECT ticket_id FROM character_ticket");
2009 if(!result
|| num
> result
->GetRowCount())
2011 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2016 for(uint32 i
= 1; i
< num
; ++i
)
2019 Field
* fields
= result
->Fetch();
2021 uint32 id
= fields
[0].GetUInt32();
2027 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2029 char* px
= strtok((char*)args
, " ");
2034 if(strncmp(px
,"all",4) == 0)
2036 QueryResult
*result
= CharacterDatabase
.Query("SELECT guid FROM character_ticket");
2041 // notify players about ticket deleting
2044 Field
* fields
= result
->Fetch();
2046 uint64 guid
= fields
[0].GetUInt64();
2048 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2049 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2051 }while(result
->NextRow());
2055 CharacterDatabase
.PExecute("DELETE FROM character_ticket");
2056 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2060 int num
= (uint32
)atoi(px
);
2065 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT ticket_id,guid FROM character_ticket LIMIT %i",num
);
2067 if(!result
|| uint64(num
) > result
->GetRowCount())
2069 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2071 SetSentErrorMessage(true);
2075 for(int i
= 1; i
< num
; ++i
)
2078 Field
* fields
= result
->Fetch();
2080 uint32 id
= fields
[0].GetUInt32();
2081 uint64 guid
= fields
[1].GetUInt64();
2084 CharacterDatabase
.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id
);
2086 // notify players about ticket deleting
2087 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2089 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2090 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,sender
->GetName());
2093 SendSysMessage(LANG_COMMAND_TICKETDEL
);
2098 std::string name
= px
;
2100 if(!normalizePlayerName(name
))
2102 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2103 SetSentErrorMessage(true);
2107 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2112 // delticket $char_name
2113 CharacterDatabase
.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid
));
2115 // notify players about ticket deleting
2116 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2117 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2119 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,px
);
2123 //set spawn dist of creature
2124 bool ChatHandler::HandleSpawnDistCommand(const char* args
)
2129 float option
= atof((char*)args
);
2132 SendSysMessage(LANG_BAD_VALUE
);
2136 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
2138 mtype
= RANDOM_MOTION_TYPE
;
2140 Creature
*pCreature
= getSelectedCreature();
2141 uint32 u_guidlow
= 0;
2144 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2148 pCreature
->SetRespawnRadius((float)option
);
2149 pCreature
->SetDefaultMovementType(mtype
);
2150 pCreature
->GetMotionMaster()->Initialize();
2151 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
2153 pCreature
->setDeathState(JUST_DIED
);
2154 pCreature
->Respawn();
2157 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
2158 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
2162 bool ChatHandler::HandleSpawnTimeCommand(const char* args
)
2167 char* stime
= strtok((char*)args
, " ");
2172 int i_stime
= atoi((char*)stime
);
2176 SendSysMessage(LANG_BAD_VALUE
);
2177 SetSentErrorMessage(true);
2181 Creature
*pCreature
= getSelectedCreature();
2182 uint32 u_guidlow
= 0;
2185 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2189 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
2190 pCreature
->SetRespawnDelay((uint32
)i_stime
);
2191 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
2197 * Add a waypoint to a creature.
2199 * The user can either select an npc or provide its GUID.
2201 * The user can even select a visual waypoint - then the new waypoint
2202 * is placed *after* the selected one - this makes insertion of new
2203 * waypoints possible.
2207 * -> adds a waypoint to the npc with the GUID 12345
2210 * -> adds a waypoint to the currently selected creature
2213 * @param args if the user did not provide a GUID, it is NULL
2215 * @return true - command did succeed, false - something went wrong
2217 bool ChatHandler::HandleWpAddCommand(const char* args
)
2219 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2222 char* guid_str
= NULL
;
2226 guid_str
= strtok((char*)args
, " ");
2231 Creature
* target
= getSelectedCreature();
2232 // Did player provide a GUID?
2235 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2238 // -> Player must have selected a creature
2240 if(!target
|| target
->isPet())
2242 SendSysMessage(LANG_SELECT_CREATURE
);
2243 SetSentErrorMessage(true);
2246 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2248 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2250 QueryResult
*result
=
2251 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2252 target
->GetGUIDLow() );
2255 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2256 // User selected a visual spawnpoint -> get the NPC
2258 // Since we compare float values, we have to deal with
2259 // some difficulties.
2260 // Here we search for all waypoints that only differ in one from 1 thousand
2261 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2262 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2263 const char* maxDIFF
= "0.01";
2264 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 )",
2265 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2268 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2269 SetSentErrorMessage(true);
2275 Field
*fields
= result
->Fetch();
2276 lowguid
= fields
[0].GetUInt32();
2277 point
= fields
[1].GetUInt32();
2278 }while( result
->NextRow() );
2281 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2284 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2285 SetSentErrorMessage(true);
2289 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2292 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2293 SetSentErrorMessage(true);
2299 lowguid
= target
->GetDBTableGUIDLow();
2304 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2307 // Warn if player also selected a creature
2308 // -> Creature selection is ignored <-
2311 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2313 lowguid
= atoi((char*)guid_str
);
2315 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2318 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2319 SetSentErrorMessage(true);
2323 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2324 if(!target
|| target
->isPet())
2326 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2327 SetSentErrorMessage(true);
2331 // lowguid -> GUID of the NPC
2332 // point -> number of the waypoint (if not 0)
2333 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2335 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2337 Player
* player
= m_session
->GetPlayer();
2338 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2340 // update movement type
2343 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2344 target
->GetMotionMaster()->Initialize();
2345 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2347 target
->setDeathState(JUST_DIED
);
2353 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2355 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2358 } // HandleWpAddCommand
2361 * .wp modify emote | spell | text | del | move | add
2363 * add -> add a WP after the selected visual waypoint
2364 * User must select a visual waypoint and then issue ".wp modify add"
2367 * User has selected a visual waypoint before.
2368 * <emoteID> is added to this waypoint. Everytime the
2369 * NPC comes to this waypoint, the emote is called.
2371 * emote <GUID> <WPNUM> <emoteID>
2372 * User has not selected visual waypoint before.
2373 * For the waypoint <WPNUM> for the NPC with <GUID>
2374 * an emote <emoteID> is added.
2375 * Everytime the NPC comes to this waypoint, the emote is called.
2378 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2380 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2382 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2387 // first arg: add del text emote spell waittime move
2388 char* show_str
= strtok((char*)args
, " ");
2394 std::string show
= show_str
;
2396 // Remember: "show" must also be the name of a column!
2397 if( (show
!= "emote") && (show
!= "spell") && (show
!= "text1") && (show
!= "text2")
2398 && (show
!= "text3") && (show
!= "text4") && (show
!= "text5")
2399 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2400 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2405 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2407 // Did user provide a GUID
2408 // or did the user select a creature?
2409 // -> variable lowguid is filled with the GUID of the NPC
2413 Creature
* target
= getSelectedCreature();
2417 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2419 // Did the user select a visual spawnpoint?
2420 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2422 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2423 SetSentErrorMessage(true);
2427 wpGuid
= target
->GetGUIDLow();
2429 // The visual waypoint
2430 QueryResult
*result
=
2431 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2432 target
->GetGUIDLow() );
2435 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2436 SetSentErrorMessage(true);
2439 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2441 Field
*fields
= result
->Fetch();
2442 lowguid
= fields
[0].GetUInt32();
2443 point
= fields
[1].GetUInt32();
2446 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2451 // User did provide <GUID> <WPNUM>
2453 char* guid_str
= strtok((char*)NULL
, " ");
2456 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2459 lowguid
= atoi((char*)guid_str
);
2461 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2464 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2465 SetSentErrorMessage(true);
2469 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2471 char* point_str
= strtok((char*)NULL
, " ");
2474 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2477 point
= atoi((char*)point_str
);
2479 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2481 // Now we need the GUID of the visual waypoint
2482 // -> "del", "move", "add" command
2484 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2487 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2488 SetSentErrorMessage(true);
2492 Field
*fields
= result
->Fetch();
2493 wpGuid
= fields
[0].GetUInt32();
2499 char* arg_str
= NULL
;
2500 // Check for argument
2501 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2503 // Text is enclosed in "<>", all other arguments not
2504 if( show
.find("text") != std::string::npos
)
2505 arg_str
= strtok((char*)NULL
, "<>");
2507 arg_str
= strtok((char*)NULL
, " ");
2511 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2516 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2518 // wpGuid -> GUID of the waypoint creature
2519 // lowguid -> GUID of the NPC
2520 // point -> waypoint number
2522 // Special functions:
2523 // add - move - del -> no args commands
2524 // Add a waypoint after the selected visual
2525 if(show
== "add" && target
)
2527 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2529 // Get the creature for which we read the waypoint
2530 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2533 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2534 SetSentErrorMessage(true);
2538 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2542 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2543 SetSentErrorMessage(true);
2547 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2550 // Add the visual spawnpoint (DB only)
2551 // Adjust the waypoints
2552 // Respawn the owner of the waypoints
2553 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2555 Player
* chr
= m_session
->GetPlayer();
2556 Map
*map
= chr
->GetMap();
2560 npcCreature
->GetMotionMaster()->Initialize();
2561 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2563 npcCreature
->setDeathState(JUST_DIED
);
2564 npcCreature
->Respawn();
2568 // create the waypoint creature
2570 Creature
* wpCreature
= new Creature
;
2571 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
,VISUAL_WAYPOINT
,0))
2573 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2578 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2580 if(!wpCreature
->IsPositionValid())
2582 sLog
.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature
->GetGUIDLow(),wpCreature
->GetEntry(),wpCreature
->GetPositionX(),wpCreature
->GetPositionY());
2587 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2588 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2589 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2590 map
->Add(wpCreature
);
2591 wpGuid
= wpCreature
->GetGUIDLow();
2595 WaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2600 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2604 if(show
== "del" && target
)
2606 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2608 // Get the creature for which we read the waypoint
2609 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2612 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2613 SetSentErrorMessage(true);
2617 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2620 Creature
* wpCreature
= NULL
;
2623 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2624 wpCreature
->DeleteFromDB();
2625 wpCreature
->CleanupsBeforeDelete();
2626 wpCreature
->AddObjectToRemoveList();
2630 // Remove the visual spawnpoint
2631 // Adjust the waypoints
2632 // Respawn the owner of the waypoints
2634 WaypointMgr
.DeleteNode(lowguid
, point
);
2638 // Any waypoints left?
2639 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2642 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2646 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2649 npcCreature
->GetMotionMaster()->Initialize();
2650 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2652 npcCreature
->setDeathState(JUST_DIED
);
2653 npcCreature
->Respawn();
2655 npcCreature
->SaveToDB();
2658 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2662 if(show
== "move" && target
)
2664 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2666 Player
*chr
= m_session
->GetPlayer();
2667 Map
*map
= chr
->GetMap();
2669 // Get the creature for which we read the waypoint
2670 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2673 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2674 SetSentErrorMessage(true);
2678 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2681 Creature
* wpCreature
= NULL
;
2683 // Move the visual spawnpoint
2684 // Respawn the owner of the waypoints
2687 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2688 wpCreature
->DeleteFromDB();
2689 wpCreature
->CleanupsBeforeDelete();
2690 wpCreature
->AddObjectToRemoveList();
2692 Creature
* wpCreature2
= new Creature
;
2693 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, VISUAL_WAYPOINT
, 0))
2695 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2700 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2702 if(!wpCreature2
->IsPositionValid())
2704 sLog
.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature2
->GetGUIDLow(),wpCreature2
->GetEntry(),wpCreature2
->GetPositionX(),wpCreature2
->GetPositionY());
2709 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
2710 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2711 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2712 map
->Add(wpCreature2
);
2713 //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
2716 WaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2720 npcCreature
->GetMotionMaster()->Initialize();
2721 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2723 npcCreature
->setDeathState(JUST_DIED
);
2724 npcCreature
->Respawn();
2727 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2732 // Create creature - npc that has the waypoint
2733 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2736 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2737 SetSentErrorMessage(true);
2741 WaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2743 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2746 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2747 npcCreature
->GetMotionMaster()->Initialize();
2748 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2750 npcCreature
->setDeathState(JUST_DIED
);
2751 npcCreature
->Respawn();
2754 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2760 * .wp show info | on | off
2762 * info -> User has selected a visual waypoint before
2764 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2765 * provided the GUID of the NPC and the number of
2768 * on -> User has selected an NPC; all visual waypoints for this
2769 * NPC are added to the world
2771 * on <GUID> -> User did not select an NPC - instead the GUID of the
2772 * NPC is provided. All visual waypoints for this NPC
2773 * are added from the world.
2775 * off -> User has selected an NPC; all visual waypoints for this
2776 * NPC are removed from the world.
2778 * on <GUID> -> User did not select an NPC - instead the GUID of the
2779 * NPC is provided. All visual waypoints for this NPC
2780 * are removed from the world.
2784 bool ChatHandler::HandleWpShowCommand(const char* args
)
2786 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2791 // first arg: on, off, first, last
2792 char* show_str
= strtok((char*)args
, " ");
2797 // second arg: GUID (optional, if a creature is selected)
2798 char* guid_str
= strtok((char*)NULL
, " ");
2799 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2804 // Did user provide a GUID
2805 // or did the user select a creature?
2806 // -> variable lowguid is filled with the GUID
2807 Creature
* target
= getSelectedCreature();
2808 // Did player provide a GUID?
2811 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2813 // -> Player must have selected a creature
2817 SendSysMessage(LANG_SELECT_CREATURE
);
2818 SetSentErrorMessage(true);
2824 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2826 // Warn if player also selected a creature
2827 // -> Creature selection is ignored <-
2830 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2833 uint32 lowguid
= atoi((char*)guid_str
);
2835 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2838 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2839 SetSentErrorMessage(true);
2843 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2847 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2848 SetSentErrorMessage(true);
2853 uint32 lowguid
= target
->GetDBTableGUIDLow();
2855 std::string show
= show_str
;
2858 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u", lowguid
);
2860 sLog
.outDebug("DEBUG: HandleWpShowCommand: Habe creature: %ld", target
);
2862 sLog
.outDebug("DEBUG: HandleWpShowCommand: wpshow - show: %s", show_str
);
2863 //PSendSysMessage("wpshow - show: %s", show);
2865 // Show info for the selected waypoint
2868 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
2870 // Check if the user did specify a visual waypoint
2871 if( target
->GetEntry() != VISUAL_WAYPOINT
)
2873 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2874 SetSentErrorMessage(true);
2878 //PSendSysMessage("wp on, GUID: %u", lowguid);
2880 //pCreature->GetPositionX();
2882 QueryResult
*result
=
2883 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2884 target
->GetGUID() );
2887 // Since we compare float values, we have to deal with
2888 // some difficulties.
2889 // Here we search for all waypoints that only differ in one from 1 thousand
2890 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2891 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2892 const char* maxDIFF
= "0.01";
2893 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
2895 result
= WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2896 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2899 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2900 SetSentErrorMessage(true);
2906 Field
*fields
= result
->Fetch();
2907 uint32 creGUID
= fields
[0].GetUInt32();
2908 uint32 point
= fields
[1].GetUInt32();
2909 int waittime
= fields
[2].GetUInt32();
2910 uint32 emote
= fields
[3].GetUInt32();
2911 uint32 spell
= fields
[4].GetUInt32();
2912 const char * text1
= fields
[5].GetString();
2913 const char * text2
= fields
[6].GetString();
2914 const char * text3
= fields
[7].GetString();
2915 const char * text4
= fields
[8].GetString();
2916 const char * text5
= fields
[9].GetString();
2917 uint32 model1
= fields
[10].GetUInt32();
2918 uint32 model2
= fields
[11].GetUInt32();
2920 // Get the creature for which we read the waypoint
2921 Creature
* wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2923 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
2924 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
2925 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
2926 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
2927 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
2928 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
2929 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 1, text1
);
2930 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 2, text2
);
2931 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 3, text3
);
2932 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 4, text4
);
2933 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, 5, text5
);
2935 }while( result
->NextRow() );
2943 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
2945 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
2948 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2949 SetSentErrorMessage(true);
2952 // Delete all visuals for this NPC
2953 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
2956 bool hasError
= false;
2959 Field
*fields
= result2
->Fetch();
2960 uint32 wpguid
= fields
[0].GetUInt32();
2961 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2965 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
2967 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
2971 pCreature
->DeleteFromDB();
2972 pCreature
->CleanupsBeforeDelete();
2973 pCreature
->AddObjectToRemoveList();
2976 }while( result2
->NextRow() );
2980 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2981 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
2982 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
2988 Field
*fields
= result
->Fetch();
2989 uint32 point
= fields
[0].GetUInt32();
2990 float x
= fields
[1].GetFloat();
2991 float y
= fields
[2].GetFloat();
2992 float z
= fields
[3].GetFloat();
2994 uint32 id
= VISUAL_WAYPOINT
;
2996 Player
*chr
= m_session
->GetPlayer();
2997 Map
*map
= chr
->GetMap();
2998 float o
= chr
->GetOrientation();
3000 Creature
* wpCreature
= new Creature
;
3001 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
3003 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3009 wpCreature
->Relocate(x
, y
, z
, o
);
3011 if(!wpCreature
->IsPositionValid())
3013 sLog
.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature
->GetGUIDLow(),wpCreature
->GetEntry(),wpCreature
->GetPositionX(),wpCreature
->GetPositionY());
3019 wpCreature
->SetVisibility(VISIBILITY_OFF
);
3020 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
3021 // set "wpguid" column to the visual waypoint
3022 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3024 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3025 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3026 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3027 map
->Add(wpCreature
);
3028 //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
3029 }while( result
->NextRow() );
3038 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3040 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3043 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3044 SetSentErrorMessage(true);
3048 Field
*fields
= result
->Fetch();
3049 float x
= fields
[0].GetFloat();
3050 float y
= fields
[1].GetFloat();
3051 float z
= fields
[2].GetFloat();
3052 uint32 id
= VISUAL_WAYPOINT
;
3054 Player
*chr
= m_session
->GetPlayer();
3055 float o
= chr
->GetOrientation();
3056 Map
*map
= chr
->GetMap();
3058 Creature
* pCreature
= new Creature
;
3059 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, id
, 0))
3061 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3067 pCreature
->Relocate(x
, y
, z
, o
);
3069 if(!pCreature
->IsPositionValid())
3071 sLog
.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature
->GetGUIDLow(),pCreature
->GetEntry(),pCreature
->GetPositionX(),pCreature
->GetPositionY());
3077 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3078 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3079 map
->Add(pCreature
);
3080 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3089 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3091 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3094 Maxpoint
= (*result
)[0].GetUInt32();
3101 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3104 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3105 SetSentErrorMessage(true);
3108 Field
*fields
= result
->Fetch();
3109 float x
= fields
[0].GetFloat();
3110 float y
= fields
[1].GetFloat();
3111 float z
= fields
[2].GetFloat();
3112 uint32 id
= VISUAL_WAYPOINT
;
3114 Player
*chr
= m_session
->GetPlayer();
3115 float o
= chr
->GetOrientation();
3116 Map
*map
= chr
->GetMap();
3118 Creature
* pCreature
= new Creature
;
3119 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, id
, 0))
3121 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3127 pCreature
->Relocate(x
, y
, z
, o
);
3129 if(!pCreature
->IsPositionValid())
3131 sLog
.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature
->GetGUIDLow(),pCreature
->GetEntry(),pCreature
->GetPositionX(),pCreature
->GetPositionY());
3137 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3138 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3139 map
->Add(pCreature
);
3140 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3148 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3151 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3152 SetSentErrorMessage(true);
3155 bool hasError
= false;
3158 Field
*fields
= result
->Fetch();
3159 uint32 guid
= fields
[0].GetUInt32();
3160 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3162 //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3166 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3168 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3172 pCreature
->DeleteFromDB();
3173 pCreature
->CleanupsBeforeDelete();
3174 pCreature
->AddObjectToRemoveList();
3176 }while(result
->NextRow());
3177 // set "wpguid" column to "empty" - no visual waypoint spawned
3178 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
3182 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3183 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3184 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3187 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3194 PSendSysMessage("DEBUG: wpshow - no valid command found");
3197 } // HandleWpShowCommand
3199 bool ChatHandler::HandleWpExportCommand(const char *args
)
3204 // Next arg is: <GUID> <ARGUMENT>
3206 // Did user provide a GUID
3207 // or did the user select a creature?
3208 // -> variable lowguid is filled with the GUID of the NPC
3210 Creature
* target
= getSelectedCreature();
3211 char* arg_str
= NULL
;
3214 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3215 lowguid
= target
->GetGUIDLow();
3218 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3221 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3224 Field
*fields
= result
->Fetch();
3225 lowguid
= fields
[0].GetUInt32();;
3229 arg_str
= strtok((char*)args
, " ");
3233 // user provided <GUID>
3234 char* guid_str
= strtok((char*)args
, " ");
3237 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3240 lowguid
= atoi((char*)guid_str
);
3242 arg_str
= strtok((char*)NULL
, " ");
3247 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3251 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3253 QueryResult
*result
= WorldDatabase
.PQuery(
3254 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3255 "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid
);
3259 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3260 SetSentErrorMessage(true);
3264 std::ofstream outfile
;
3265 outfile
.open (arg_str
);
3269 Field
*fields
= result
->Fetch();
3271 outfile
<< "INSERT INTO creature_movement ";
3272 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES ";
3275 outfile
<< fields
[15].GetUInt32(); // id
3277 outfile
<< fields
[0].GetUInt32(); // point
3279 outfile
<< fields
[1].GetFloat(); // position_x
3281 outfile
<< fields
[2].GetFloat(); // position_y
3283 outfile
<< fields
[3].GetUInt32(); // position_z
3285 outfile
<< fields
[4].GetUInt32(); // orientation
3287 outfile
<< fields
[5].GetUInt32(); // model1
3289 outfile
<< fields
[6].GetUInt32(); // model2
3291 outfile
<< fields
[7].GetUInt16(); // waittime
3293 outfile
<< fields
[8].GetUInt32(); // emote
3295 outfile
<< fields
[9].GetUInt32(); // spell
3297 const char *tmpChar
= fields
[10].GetString();
3300 outfile
<< "NULL"; // text1
3305 outfile
<< tmpChar
; // text1
3309 tmpChar
= fields
[11].GetString();
3312 outfile
<< "NULL"; // text2
3317 outfile
<< tmpChar
; // text2
3321 tmpChar
= fields
[12].GetString();
3324 outfile
<< "NULL"; // text3
3329 outfile
<< tmpChar
; // text3
3333 tmpChar
= fields
[13].GetString();
3336 outfile
<< "NULL"; // text4
3341 outfile
<< tmpChar
; // text4
3345 tmpChar
= fields
[14].GetString();
3348 outfile
<< "NULL"; // text5
3353 outfile
<< tmpChar
; // text5
3358 } while( result
->NextRow() );
3361 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3367 bool ChatHandler::HandleWpImportCommand(const char *args
)
3372 char* arg_str
= strtok((char*)args
, " ");
3377 std::ifstream
infile (arg_str
);
3378 if (infile
.is_open())
3380 while (! infile
.eof() )
3382 getline (infile
,line
);
3383 //cout << line << endl;
3384 QueryResult
*result
= WorldDatabase
.PQuery(line
.c_str());
3389 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3395 bool ChatHandler::HandleRenameCommand(const char* args
)
3397 Player
* target
= NULL
;
3398 uint64 targetGUID
= 0;
3399 std::string oldname
;
3401 char* px
= strtok((char*)args
, " ");
3407 if(!normalizePlayerName(oldname
))
3409 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3410 SetSentErrorMessage(true);
3414 target
= objmgr
.GetPlayer(oldname
.c_str());
3417 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3420 if(!target
&& !targetGUID
)
3422 target
= getSelectedPlayer();
3425 if(!target
&& !targetGUID
)
3427 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3428 SetSentErrorMessage(true);
3434 PSendSysMessage(LANG_RENAME_PLAYER
, target
->GetName());
3435 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3436 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3440 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldname
.c_str(), GUID_LOPART(targetGUID
));
3441 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3448 bool ChatHandler::HandleGameObjectCommand(const char* args
)
3453 char* pParam1
= strtok((char*)args
, " ");
3457 uint32 id
= atoi((char*)pParam1
);
3461 char* spawntimeSecs
= strtok(NULL
, " ");
3463 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
3467 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
3468 SetSentErrorMessage(true);
3472 Player
*chr
= m_session
->GetPlayer();
3473 float x
= float(chr
->GetPositionX());
3474 float y
= float(chr
->GetPositionY());
3475 float z
= float(chr
->GetPositionZ());
3476 float o
= float(chr
->GetOrientation());
3477 Map
*map
= chr
->GetMap();
3479 float rot2
= sin(o
/2);
3480 float rot3
= cos(o
/2);
3482 GameObject
* pGameObj
= new GameObject
;
3483 uint32 db_lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
3485 if(!pGameObj
->Create(db_lowGUID
, goI
->id
, map
, x
, y
, z
, o
, 0, 0, rot2
, rot3
, 0, 1))
3493 uint32 value
= atoi((char*)spawntimeSecs
);
3494 pGameObj
->SetRespawnTime(value
);
3495 //sLog.outDebug("*** spawntimeSecs: %d", value);
3498 // fill the gameobject data and save to the db
3499 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()));
3501 // this will generate a new guid if the object is in an instance
3502 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
3508 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), goI
->name
, db_lowGUID
, x
, y
, z
, o
);
3512 // TODO: is it really necessary to add both the real and DB table guid here ?
3513 objmgr
.AddGameobjectToGrid(db_lowGUID
, objmgr
.GetGOData(db_lowGUID
));
3515 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,goI
->name
,db_lowGUID
,x
,y
,z
);
3520 bool ChatHandler::HandleAnimCommand(const char* args
)
3525 uint32 anim_id
= atoi((char*)args
);
3526 m_session
->GetPlayer()->HandleEmoteCommand(anim_id
);
3531 bool ChatHandler::HandleStandStateCommand(const char* args
)
3536 uint32 anim_id
= atoi((char*)args
);
3537 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3542 bool ChatHandler::HandleAddHonorCommand(const char* args
)
3547 Player
*target
= getSelectedPlayer();
3550 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3551 SetSentErrorMessage(true);
3555 uint32 amount
= (uint32
)atoi(args
);
3556 target
->RewardHonor(NULL
, 1, amount
);
3560 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3562 Unit
*target
= getSelectedUnit();
3565 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3566 SetSentErrorMessage(true);
3570 m_session
->GetPlayer()->RewardHonor(target
, 1);
3574 bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3576 Player
*target
= getSelectedPlayer();
3579 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3580 SetSentErrorMessage(true);
3584 target
->UpdateHonorFields();
3588 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3593 std::string namepart
= args
;
3594 std::wstring wnamepart
;
3596 // converting string that we try to find to lower case
3597 if(!Utf8toWStr(namepart
,wnamepart
))
3600 wstrToLower(wnamepart
);
3604 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3605 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3607 for(uint32 id
= 0; id
< events
.size(); ++id
)
3609 GameEventData
const& eventData
= events
[id
];
3611 std::string descr
= eventData
.description
;
3615 if (Utf8FitTo(descr
, wnamepart
))
3617 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3620 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3622 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3629 SendSysMessage(LANG_NOEVENTFOUND
);
3634 bool ChatHandler::HandleEventActiveListCommand(const char* args
)
3638 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3639 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3641 char const* active
= GetMangosString(LANG_ACTIVE
);
3643 for(GameEvent::ActiveEvents::const_iterator itr
= activeEvents
.begin(); itr
!= activeEvents
.end(); ++itr
)
3645 uint32 event_id
= *itr
;
3646 GameEventData
const& eventData
= events
[event_id
];
3649 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,event_id
,event_id
,eventData
.description
.c_str(),active
);
3651 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,event_id
,eventData
.description
.c_str(),active
);
3657 SendSysMessage(LANG_NOEVENTFOUND
);
3662 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3667 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3668 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3672 uint32 event_id
= atoi(cId
);
3674 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3676 if(event_id
>=events
.size())
3678 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3679 SetSentErrorMessage(true);
3683 GameEventData
const& eventData
= events
[event_id
];
3684 if(!eventData
.isValid())
3686 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3687 SetSentErrorMessage(true);
3691 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3692 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3693 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3695 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3696 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3698 uint32 delay
= gameeventmgr
.NextCheck(event_id
);
3699 time_t nextTime
= time(NULL
)+delay
;
3700 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3702 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3703 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3705 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3706 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3711 bool ChatHandler::HandleEventStartCommand(const char* args
)
3716 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3717 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3721 int32 event_id
= atoi(cId
);
3723 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3725 if(event_id
< 1 || event_id
>=events
.size())
3727 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3728 SetSentErrorMessage(true);
3732 GameEventData
const& eventData
= events
[event_id
];
3733 if(!eventData
.isValid())
3735 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3736 SetSentErrorMessage(true);
3740 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3741 if(activeEvents
.find(event_id
) != activeEvents
.end())
3743 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3744 SetSentErrorMessage(true);
3748 gameeventmgr
.StartEvent(event_id
,true);
3752 bool ChatHandler::HandleEventStopCommand(const char* args
)
3757 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3758 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3762 int32 event_id
= atoi(cId
);
3764 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3766 if(event_id
< 1 || event_id
>=events
.size())
3768 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3769 SetSentErrorMessage(true);
3773 GameEventData
const& eventData
= events
[event_id
];
3774 if(!eventData
.isValid())
3776 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3777 SetSentErrorMessage(true);
3781 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3783 if(activeEvents
.find(event_id
) == activeEvents
.end())
3785 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3786 SetSentErrorMessage(true);
3790 gameeventmgr
.StopEvent(event_id
,true);
3794 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3800 std::string playername
= args
;
3802 if(!normalizePlayerName(playername
))
3804 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3805 SetSentErrorMessage(true);
3809 player
= objmgr
.GetPlayer(playername
.c_str());
3813 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3814 SetSentErrorMessage(true);
3820 player
= getSelectedPlayer();
3823 player
= m_session
->GetPlayer();
3826 player
->CombatStop();
3827 player
->getHostilRefManager().deleteReferences();
3831 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3833 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3835 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3837 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3841 if( skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
)
3843 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3845 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3849 // skip racial skills
3850 if( skillLine
->racemask
!= 0 )
3853 // skip wrong class skills
3854 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3857 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3860 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3861 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3864 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3869 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
3873 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
3875 // Learns all recipes of specified profession and sets skill to max
3876 // Example: .learn all_recipes enchanting
3878 Player
* target
= getSelectedPlayer();
3881 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3888 std::wstring wnamepart
;
3890 if(!Utf8toWStr(args
,wnamepart
))
3893 uint32 counter
= 0; // Counter for figure out that we found smth.
3895 // converting string that we try to find to lower case
3896 wstrToLower( wnamepart
);
3898 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3900 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3902 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3906 if( skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
3907 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
)
3910 int loc
= m_session
->GetSessionDbcLocale();
3911 std::string name
= skillInfo
->name
[loc
];
3913 if(Utf8FitTo(name
, wnamepart
))
3915 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3917 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3921 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3924 // skip racial skills
3925 if( skillLine
->racemask
!= 0 )
3928 // skip wrong class skills
3929 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3932 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3933 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3936 if( !target
->HasSpell(spellInfo
->Id
) )
3937 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
);
3940 uint16 maxLevel
= target
->GetPureMaxSkillValue(skillInfo
->id
);
3941 target
->SetSkill(skillInfo
->id
, maxLevel
, maxLevel
);
3942 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
3950 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
3956 std::string ip
= strtok ((char*)args
, " ");
3957 char* limit_str
= strtok (NULL
, " ");
3958 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3960 loginDatabase
.escape_string (ip
);
3962 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
3964 return LookupPlayerSearchCommand (result
,limit
);
3967 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
3972 std::string account
= strtok ((char*)args
, " ");
3973 char* limit_str
= strtok (NULL
, " ");
3974 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3976 if (!AccountMgr::normilizeString (account
))
3979 loginDatabase
.escape_string (account
);
3981 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
3983 return LookupPlayerSearchCommand (result
,limit
);
3986 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
3992 std::string email
= strtok ((char*)args
, " ");
3993 char* limit_str
= strtok (NULL
, " ");
3994 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3996 loginDatabase
.escape_string (email
);
3998 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
4000 return LookupPlayerSearchCommand (result
,limit
);
4003 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
4007 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4008 SetSentErrorMessage(true);
4015 Field
* fields
= result
->Fetch();
4016 uint32 acc_id
= fields
[0].GetUInt32();
4017 std::string acc_name
= fields
[1].GetCppString();
4019 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4022 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4029 Field
* charfields
= chars
->Fetch();
4030 guid
= charfields
[0].GetUInt64();
4031 name
= charfields
[1].GetCppString();
4033 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4036 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4040 } while(result
->NextRow());
4047 /// Triggering corpses expire check in world
4048 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)