2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
21 #include "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 "GMTicketMgr.h"
38 #include "WaypointManager.h"
44 #include "GlobalEvents.h"
46 #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
48 static uint32 ReputationRankStrIndex
[MAX_REPUTATION_RANK
] =
50 LANG_REP_HATED
, LANG_REP_HOSTILE
, LANG_REP_UNFRIENDLY
, LANG_REP_NEUTRAL
,
51 LANG_REP_FRIENDLY
, LANG_REP_HONORED
, LANG_REP_REVERED
, LANG_REP_EXALTED
54 //mute player for some times
55 bool ChatHandler::HandleMuteCommand(const char* args
)
60 std::string name
= extractPlayerNameFromLink((char*)args
);
63 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
64 SetSentErrorMessage(true);
68 char *timetonotspeak
= strtok(NULL
, " ");
72 uint32 notspeaktime
= (uint32
) atoi(timetonotspeak
);
74 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
77 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
78 SetSentErrorMessage(true);
82 Player
*chr
= objmgr
.GetPlayer(guid
);
84 // must have strong lesser security level
85 if(HasLowerSecurity (chr
,guid
,true))
88 uint32 account_id
= chr
? chr
->GetSession()->GetAccountId() : objmgr
.GetPlayerAccountIdByGUID(guid
);
90 time_t mutetime
= time(NULL
) + notspeaktime
*60;
93 chr
->GetSession()->m_muteTime
= mutetime
;
95 loginDatabase
.PExecute("UPDATE account SET mutetime = " I64FMTD
" WHERE id = '%u'",uint64(mutetime
), account_id
);
98 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_DISABLED
, notspeaktime
);
100 std::string nameLink
= playerLink(name
);
102 PSendSysMessage(LANG_YOU_DISABLE_CHAT
, nameLink
.c_str(), notspeaktime
);
108 bool ChatHandler::HandleUnmuteCommand(const char* args
)
113 std::string name
= extractPlayerNameFromLink((char*)args
);
116 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
117 SetSentErrorMessage(true);
121 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
124 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
125 SetSentErrorMessage(true);
129 Player
*chr
= objmgr
.GetPlayer(guid
);
131 // must have strong lesser security level
132 if(HasLowerSecurity (chr
,guid
,true))
135 uint32 account_id
= chr
? chr
->GetSession()->GetAccountId() : objmgr
.GetPlayerAccountIdByGUID(guid
);
141 SendSysMessage(LANG_CHAT_ALREADY_ENABLED
);
142 SetSentErrorMessage(true);
146 chr
->GetSession()->m_muteTime
= 0;
149 loginDatabase
.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id
);
152 ChatHandler(chr
).PSendSysMessage(LANG_YOUR_CHAT_ENABLED
);
154 std::string nameLink
= playerLink(name
);
156 PSendSysMessage(LANG_YOU_ENABLE_CHAT
, nameLink
.c_str());
160 bool ChatHandler::HandleTargetObjectCommand(const char* args
)
162 Player
* pl
= m_session
->GetPlayer();
164 GameEvent::ActiveEvents
const& activeEventsList
= gameeventmgr
.GetActiveEventList();
167 int32 id
= atoi((char*)args
);
169 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",
170 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),id
);
173 std::string name
= args
;
174 WorldDatabase
.escape_string(name
);
175 result
= WorldDatabase
.PQuery(
176 "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_ "
177 "FROM gameobject,gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_
" "_CONCAT3_("'%%'","'%s'","'%%'")" ORDER BY order_ ASC LIMIT 1",
178 pl
->GetPositionX(), pl
->GetPositionY(), pl
->GetPositionZ(), pl
->GetMapId(),name
.c_str());
183 std::ostringstream eventFilter
;
184 eventFilter
<< " AND (event IS NULL ";
185 bool initString
= true;
187 for (GameEvent::ActiveEvents::const_iterator itr
= activeEventsList
.begin(); itr
!= activeEventsList
.end(); ++itr
)
191 eventFilter
<< "OR event IN (" <<*itr
;
195 eventFilter
<< "," << *itr
;
203 result
= WorldDatabase
.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, "
204 "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
205 "LEFT OUTER JOIN game_event_gameobject on gameobject.guid=game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 1",
206 m_session
->GetPlayer()->GetPositionX(), m_session
->GetPlayer()->GetPositionY(), m_session
->GetPlayer()->GetPositionZ(), m_session
->GetPlayer()->GetMapId(),eventFilter
.str().c_str());
211 SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND
);
215 Field
*fields
= result
->Fetch();
216 uint32 lowguid
= fields
[0].GetUInt32();
217 uint32 id
= fields
[1].GetUInt32();
218 float x
= fields
[2].GetFloat();
219 float y
= fields
[3].GetFloat();
220 float z
= fields
[4].GetFloat();
221 float o
= fields
[5].GetFloat();
222 int mapid
= fields
[6].GetUInt16();
225 GameObjectInfo
const* goI
= objmgr
.GetGameObjectInfo(id
);
229 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
233 GameObject
* target
= ObjectAccessor::GetGameObject(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,id
,HIGHGUID_GAMEOBJECT
));
235 PSendSysMessage(LANG_GAMEOBJECT_DETAIL
, lowguid
, goI
->name
, lowguid
, id
, x
, y
, z
, mapid
, o
);
239 int32 curRespawnDelay
= target
->GetRespawnTimeEx()-time(NULL
);
240 if(curRespawnDelay
< 0)
243 std::string curRespawnDelayStr
= secsToTimeString(curRespawnDelay
,true);
244 std::string defRespawnDelayStr
= secsToTimeString(target
->GetRespawnDelay(),true);
246 PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES
, defRespawnDelayStr
.c_str(),curRespawnDelayStr
.c_str());
251 //teleport to gameobject
252 bool ChatHandler::HandleGoObjectCommand(const char* args
)
257 Player
* _player
= m_session
->GetPlayer();
259 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
260 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
264 int32 guid
= atoi(cId
);
272 if (GameObjectData
const* go_data
= objmgr
.GetGOData(guid
))
277 ort
= go_data
->orientation
;
278 mapid
= go_data
->mapid
;
282 SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND
);
283 SetSentErrorMessage(true);
287 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
289 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
290 SetSentErrorMessage(true);
294 // stop flight if need
295 if(_player
->isInFlight())
297 _player
->GetMotionMaster()->MovementExpired();
298 _player
->m_taxi
.ClearTaxiDestinations();
300 // save only in non-flight case
302 _player
->SaveRecallPosition();
304 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
308 bool ChatHandler::HandleGoTriggerCommand(const char* args
)
310 Player
* _player
= m_session
->GetPlayer();
315 char *atId
= strtok((char*)args
, " ");
319 int32 i_atId
= atoi(atId
);
324 AreaTriggerEntry
const* at
= sAreaTriggerStore
.LookupEntry(i_atId
);
327 PSendSysMessage(LANG_COMMAND_GOAREATRNOTFOUND
,i_atId
);
328 SetSentErrorMessage(true);
332 if(!MapManager::IsValidMapCoord(at
->mapid
,at
->x
,at
->y
,at
->z
))
334 PSendSysMessage(LANG_INVALID_TARGET_COORD
,at
->x
,at
->y
,at
->mapid
);
335 SetSentErrorMessage(true);
339 // stop flight if need
340 if(_player
->isInFlight())
342 _player
->GetMotionMaster()->MovementExpired();
343 _player
->m_taxi
.ClearTaxiDestinations();
345 // save only in non-flight case
347 _player
->SaveRecallPosition();
349 _player
->TeleportTo(at
->mapid
, at
->x
, at
->y
, at
->z
, _player
->GetOrientation());
353 bool ChatHandler::HandleGoGraveyardCommand(const char* args
)
355 Player
* _player
= m_session
->GetPlayer();
360 char *gyId
= strtok((char*)args
, " ");
364 int32 i_gyId
= atoi(gyId
);
369 WorldSafeLocsEntry
const* gy
= sWorldSafeLocsStore
.LookupEntry(i_gyId
);
372 PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST
,i_gyId
);
373 SetSentErrorMessage(true);
377 if(!MapManager::IsValidMapCoord(gy
->map_id
,gy
->x
,gy
->y
,gy
->z
))
379 PSendSysMessage(LANG_INVALID_TARGET_COORD
,gy
->x
,gy
->y
,gy
->map_id
);
380 SetSentErrorMessage(true);
384 // stop flight if need
385 if(_player
->isInFlight())
387 _player
->GetMotionMaster()->MovementExpired();
388 _player
->m_taxi
.ClearTaxiDestinations();
390 // save only in non-flight case
392 _player
->SaveRecallPosition();
394 _player
->TeleportTo(gy
->map_id
, gy
->x
, gy
->y
, gy
->z
, _player
->GetOrientation());
398 /** \brief Teleport the GM to the specified creature
400 * .gocreature <GUID> --> TP using creature.guid
401 * .gocreature azuregos --> TP player to the mob with this name
402 * Warning: If there is more than one mob with this name
403 * you will be teleported to the first one that is found.
404 * .gocreature id 6109 --> TP player to the mob, that has this creature_template.entry
405 * Warning: If there is more than one mob with this "id"
406 * you will be teleported to the first one that is found.
408 //teleport to creature
409 bool ChatHandler::HandleGoCreatureCommand(const char* args
)
413 Player
* _player
= m_session
->GetPlayer();
415 // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
416 char* pParam1
= extractKeyFromLink((char*)args
,"Hcreature");
420 std::ostringstream whereClause
;
422 // User wants to teleport to the NPC's template entry
423 if( strcmp(pParam1
, "id") == 0 )
425 //sLog.outError("DEBUG: ID found");
427 // Get the "creature_template.entry"
428 // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
429 char* tail
= strtok(NULL
,"");
432 char* cId
= extractKeyFromLink(tail
,"Hcreature_entry");
436 int32 tEntry
= atoi(cId
);
437 //sLog.outError("DEBUG: ID value: %d", tEntry);
441 whereClause
<< "WHERE id = '" << tEntry
<< "'";
445 //sLog.outError("DEBUG: ID *not found*");
447 int32 guid
= atoi(pParam1
);
449 // Number is invalid - maybe the user specified the mob's name
452 std::string name
= pParam1
;
453 WorldDatabase
.escape_string(name
);
454 whereClause
<< ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_
" '" << name
<< "'";
458 whereClause
<< "WHERE guid = '" << guid
<< "'";
461 //sLog.outError("DEBUG: %s", whereClause.c_str());
463 QueryResult
*result
= WorldDatabase
.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause
.str().c_str() );
466 SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND
);
467 SetSentErrorMessage(true);
470 if( result
->GetRowCount() > 1 )
472 SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE
);
475 Field
*fields
= result
->Fetch();
476 float x
= fields
[0].GetFloat();
477 float y
= fields
[1].GetFloat();
478 float z
= fields
[2].GetFloat();
479 float ort
= fields
[3].GetFloat();
480 int mapid
= fields
[4].GetUInt16();
484 if(!MapManager::IsValidMapCoord(mapid
,x
,y
,z
,ort
))
486 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,mapid
);
487 SetSentErrorMessage(true);
491 // stop flight if need
492 if(_player
->isInFlight())
494 _player
->GetMotionMaster()->MovementExpired();
495 _player
->m_taxi
.ClearTaxiDestinations();
497 // save only in non-flight case
499 _player
->SaveRecallPosition();
501 _player
->TeleportTo(mapid
, x
, y
, z
, ort
);
505 bool ChatHandler::HandleGUIDCommand(const char* /*args*/)
507 uint64 guid
= m_session
->GetPlayer()->GetSelection();
511 SendSysMessage(LANG_NO_SELECTION
);
512 SetSentErrorMessage(true);
516 PSendSysMessage(LANG_OBJECT_GUID
, GUID_LOPART(guid
), GUID_HIPART(guid
));
520 bool ChatHandler::HandleLookupFactionCommand(const char* args
)
525 // Can be NULL at console call
526 Player
*target
= getSelectedPlayer ();
528 std::string namepart
= args
;
529 std::wstring wnamepart
;
531 if (!Utf8toWStr (namepart
,wnamepart
))
534 // converting string that we try to find to lower case
535 wstrToLower (wnamepart
);
537 uint32 counter
= 0; // Counter for figure out that we found smth.
539 for (uint32 id
= 0; id
< sFactionStore
.GetNumRows(); ++id
)
541 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry (id
);
544 FactionState
const* repState
= NULL
;
547 FactionStateList::const_iterator repItr
= target
->m_factions
.find (factionEntry
->reputationListID
);
548 if(repItr
!= target
->m_factions
.end())
549 repState
= &repItr
->second
;
553 int loc
= m_session
? m_session
->GetSessionDbcLocale() : sWorld
.GetDefaultDbcLocale();
554 std::string name
= factionEntry
->name
[loc
];
558 if (!Utf8FitTo(name
, wnamepart
))
561 for(; loc
< MAX_LOCALE
; ++loc
)
563 if(m_session
&& loc
==m_session
->GetSessionDbcLocale())
566 name
= factionEntry
->name
[loc
];
570 if (Utf8FitTo(name
, wnamepart
))
577 // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
578 // or "id - [faction] [no reputation]" format
579 std::ostringstream ss
;
581 ss
<< id
<< " - |cffffffff|Hfaction:" << id
<< "|h[" << name
<< " " << localeNames
[loc
] << "]|h|r";
583 ss
<< id
<< " - " << name
<< " " << localeNames
[loc
];
585 if (repState
) // and then target!=NULL also
587 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
588 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
590 ss
<< " " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
592 if(repState
->Flags
& FACTION_FLAG_VISIBLE
)
593 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
594 if(repState
->Flags
& FACTION_FLAG_AT_WAR
)
595 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
596 if(repState
->Flags
& FACTION_FLAG_PEACE_FORCED
)
597 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
598 if(repState
->Flags
& FACTION_FLAG_HIDDEN
)
599 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
600 if(repState
->Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
601 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
602 if(repState
->Flags
& FACTION_FLAG_INACTIVE
)
603 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
606 ss
<< GetMangosString(LANG_FACTION_NOREPUTATION
);
608 SendSysMessage(ss
.str().c_str());
614 if (counter
== 0) // if counter == 0 then we found nth
615 SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND
);
619 bool ChatHandler::HandleModifyRepCommand(const char * args
)
621 if (!*args
) return false;
623 Player
* target
= NULL
;
624 target
= getSelectedPlayer();
628 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
629 SetSentErrorMessage(true);
633 // check online security
634 if (HasLowerSecurity(target
, 0))
637 char* factionTxt
= extractKeyFromLink((char*)args
,"Hfaction");
641 uint32 factionId
= atoi(factionTxt
);
644 char *rankTxt
= strtok(NULL
, " ");
645 if (!factionTxt
|| !rankTxt
)
648 amount
= atoi(rankTxt
);
649 if ((amount
== 0) && (rankTxt
[0] != '-') && !isdigit(rankTxt
[0]))
651 std::string rankStr
= rankTxt
;
652 std::wstring wrankStr
;
653 if(!Utf8toWStr(rankStr
,wrankStr
))
655 wstrToLower( wrankStr
);
659 for (; r
< MAX_REPUTATION_RANK
; ++r
)
661 std::string rank
= GetMangosString(ReputationRankStrIndex
[r
]);
666 if(!Utf8toWStr(rank
,wrank
))
671 if(wrank
.substr(0,wrankStr
.size())==wrankStr
)
673 char *deltaTxt
= strtok(NULL
, " ");
676 int32 delta
= atoi(deltaTxt
);
677 if ((delta
< 0) || (delta
> Player::ReputationRank_Length
[r
] -1))
679 PSendSysMessage(LANG_COMMAND_FACTION_DELTA
, (Player::ReputationRank_Length
[r
]-1));
680 SetSentErrorMessage(true);
687 amount
+= Player::ReputationRank_Length
[r
];
689 if (r
>= MAX_REPUTATION_RANK
)
691 PSendSysMessage(LANG_COMMAND_FACTION_INVPARAM
, rankTxt
);
692 SetSentErrorMessage(true);
697 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(factionId
);
701 PSendSysMessage(LANG_COMMAND_FACTION_UNKNOWN
, factionId
);
702 SetSentErrorMessage(true);
706 if (factionEntry
->reputationListID
< 0)
708 PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
);
709 SetSentErrorMessage(true);
713 target
->SetFactionReputation(factionEntry
,amount
);
714 PSendSysMessage(LANG_COMMAND_MODIFY_REP
, factionEntry
->name
[m_session
->GetSessionDbcLocale()], factionId
, GetNameLink(target
).c_str(), target
->GetReputation(factionId
));
718 bool ChatHandler::HandleNameCommand(const char* /*args*/)
724 if(strlen((char*)args)>75)
726 PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
730 for (uint8 i = 0; i < strlen(args); i++)
732 if(!isalpha(args[i]) && args[i]!=' ')
734 SendSysMessage(LANG_CHARS_ONLY);
740 guid = m_session->GetPlayer()->GetSelection();
743 SendSysMessage(LANG_NO_SELECTION);
747 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
751 SendSysMessage(LANG_SELECT_CREATURE);
755 pCreature->SetName(args);
756 uint32 idname = objmgr.AddCreatureTemplate(pCreature->GetName());
757 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
759 pCreature->SaveToDB();
765 bool ChatHandler::HandleSubNameCommand(const char* /*args*/)
772 if(strlen((char*)args)>75)
775 PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
779 for (uint8 i = 0; i < strlen(args); i++)
781 if(!isalpha(args[i]) && args[i]!=' ')
783 SendSysMessage(LANG_CHARS_ONLY);
788 guid = m_session->GetPlayer()->GetSelection();
791 SendSysMessage(LANG_NO_SELECTION);
795 Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
799 SendSysMessage(LANG_SELECT_CREATURE);
803 uint32 idname = objmgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
804 pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
806 pCreature->SaveToDB();
811 //move item to other slot
812 bool ChatHandler::HandleItemMoveCommand(const char* args
)
816 uint8 srcslot
, dstslot
;
818 char* pParam1
= strtok((char*)args
, " ");
822 char* pParam2
= strtok(NULL
, " ");
826 srcslot
= (uint8
)atoi(pParam1
);
827 dstslot
= (uint8
)atoi(pParam2
);
832 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,srcslot
))
835 if(!m_session
->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0
,dstslot
))
838 uint16 src
= ((INVENTORY_SLOT_BAG_0
<< 8) | srcslot
);
839 uint16 dst
= ((INVENTORY_SLOT_BAG_0
<< 8) | dstslot
);
841 m_session
->GetPlayer()->SwapItem( src
, dst
);
846 //add spawn of creature
847 bool ChatHandler::HandleNpcAddCommand(const char* args
)
851 char* charID
= extractKeyFromLink((char*)args
,"Hcreature_entry");
855 char* team
= strtok(NULL
, " ");
857 if (team
) { teamval
= atoi(team
); }
858 if (teamval
< 0) { teamval
= 0; }
860 uint32 id
= atoi(charID
);
862 Player
*chr
= m_session
->GetPlayer();
863 float x
= chr
->GetPositionX();
864 float y
= chr
->GetPositionY();
865 float z
= chr
->GetPositionZ();
866 float o
= chr
->GetOrientation();
867 Map
*map
= chr
->GetMap();
869 Creature
* pCreature
= new Creature
;
870 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, (uint32
)teamval
))
876 pCreature
->Relocate(x
,y
,z
,o
);
878 if(!pCreature
->IsPositionValid())
880 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());
885 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
887 uint32 db_guid
= pCreature
->GetDBTableGUIDLow();
889 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
890 pCreature
->LoadFromDB(db_guid
, map
);
893 objmgr
.AddCreatureToGrid(db_guid
, objmgr
.GetCreatureData(db_guid
));
897 bool ChatHandler::HandleNpcDeleteCommand(const char* args
)
899 Creature
* unit
= NULL
;
903 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
904 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
908 uint32 lowguid
= atoi(cId
);
912 if (CreatureData
const* cr_data
= objmgr
.GetCreatureData(lowguid
))
913 unit
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, cr_data
->id
, HIGHGUID_UNIT
));
916 unit
= getSelectedCreature();
918 if(!unit
|| unit
->isPet() || unit
->isTotem() || unit
->isVehicle())
920 SendSysMessage(LANG_SELECT_CREATURE
);
921 SetSentErrorMessage(true);
925 // Delete the creature
927 unit
->DeleteFromDB();
928 unit
->CleanupsBeforeDelete();
929 unit
->AddObjectToRemoveList();
931 SendSysMessage(LANG_COMMAND_DELCREATMESSAGE
);
936 //delete object by selection or guid
937 bool ChatHandler::HandleDelObjectCommand(const char* args
)
939 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
940 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
944 uint32 lowguid
= atoi(cId
);
948 GameObject
* obj
= NULL
;
951 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
952 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
956 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
957 SetSentErrorMessage(true);
961 uint64 owner_guid
= obj
->GetOwnerGUID();
964 Unit
* owner
= ObjectAccessor::GetUnit(*m_session
->GetPlayer(),owner_guid
);
965 if(!owner
&& !IS_PLAYER_GUID(owner_guid
))
967 PSendSysMessage(LANG_COMMAND_DELOBJREFERCREATURE
, GUID_LOPART(owner_guid
), obj
->GetGUIDLow());
968 SetSentErrorMessage(true);
972 owner
->RemoveGameObject(obj
,false);
975 obj
->SetRespawnTime(0); // not save respawn time
979 PSendSysMessage(LANG_COMMAND_DELOBJMESSAGE
, obj
->GetGUIDLow());
984 //turn selected object
985 bool ChatHandler::HandleTurnObjectCommand(const char* args
)
987 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
988 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
992 uint32 lowguid
= atoi(cId
);
996 GameObject
* obj
= NULL
;
999 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1000 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1004 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1005 SetSentErrorMessage(true);
1009 char* po
= strtok(NULL
, " ");
1014 o
= (float)atof(po
);
1018 Player
*chr
= m_session
->GetPlayer();
1019 o
= chr
->GetOrientation();
1022 float rot2
= sin(o
/2);
1023 float rot3
= cos(o
/2);
1025 Map
* map
= obj
->GetMap();
1026 map
->Remove(obj
,false);
1028 obj
->Relocate(obj
->GetPositionX(), obj
->GetPositionY(), obj
->GetPositionZ(), o
);
1030 obj
->SetFloatValue(GAMEOBJECT_FACING
, o
);
1031 obj
->SetFloatValue(GAMEOBJECT_PARENTROTATION
+2, rot2
);
1032 obj
->SetFloatValue(GAMEOBJECT_PARENTROTATION
+3, rot3
);
1039 PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE
, obj
->GetGUIDLow(), o
);
1044 //move selected creature
1045 bool ChatHandler::HandleNpcMoveCommand(const char* args
)
1049 Creature
* pCreature
= getSelectedCreature();
1053 // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
1054 char* cId
= extractKeyFromLink((char*)args
,"Hcreature");
1058 uint32 lowguid
= atoi(cId
);
1060 /* FIXME: impossibel without entry
1062 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1065 // Attempting creature load from DB data
1068 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1071 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1072 SetSentErrorMessage(true);
1076 uint32 map_id
= data
->mapid
;
1078 if(m_session
->GetPlayer()->GetMapId()!=map_id
)
1080 PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP
, lowguid
);
1081 SetSentErrorMessage(true);
1087 lowguid
= pCreature
->GetDBTableGUIDLow();
1092 lowguid
= pCreature
->GetDBTableGUIDLow();
1095 float x
= m_session
->GetPlayer()->GetPositionX();
1096 float y
= m_session
->GetPlayer()->GetPositionY();
1097 float z
= m_session
->GetPlayer()->GetPositionZ();
1098 float o
= m_session
->GetPlayer()->GetOrientation();
1102 if(CreatureData
const* data
= objmgr
.GetCreatureData(pCreature
->GetDBTableGUIDLow()))
1104 const_cast<CreatureData
*>(data
)->posX
= x
;
1105 const_cast<CreatureData
*>(data
)->posY
= y
;
1106 const_cast<CreatureData
*>(data
)->posZ
= z
;
1107 const_cast<CreatureData
*>(data
)->orientation
= o
;
1109 pCreature
->GetMap()->CreatureRelocation(pCreature
,x
, y
, z
,o
);
1110 pCreature
->GetMotionMaster()->Initialize();
1111 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1113 pCreature
->setDeathState(JUST_DIED
);
1114 pCreature
->Respawn();
1118 WorldDatabase
.PExecuteLog("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x
, y
, z
, o
, lowguid
);
1119 PSendSysMessage(LANG_COMMAND_CREATUREMOVED
);
1123 //move selected object
1124 bool ChatHandler::HandleMoveObjectCommand(const char* args
)
1126 // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
1127 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
1131 uint32 lowguid
= atoi(cId
);
1135 GameObject
* obj
= NULL
;
1138 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
1139 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
1143 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
1144 SetSentErrorMessage(true);
1148 char* px
= strtok(NULL
, " ");
1149 char* py
= strtok(NULL
, " ");
1150 char* pz
= strtok(NULL
, " ");
1154 Player
*chr
= m_session
->GetPlayer();
1156 Map
* map
= obj
->GetMap();
1157 map
->Remove(obj
,false);
1159 obj
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), obj
->GetOrientation());
1160 obj
->SetFloatValue(GAMEOBJECT_POS_X
, chr
->GetPositionX());
1161 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, chr
->GetPositionY());
1162 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, chr
->GetPositionZ());
1171 float x
= (float)atof(px
);
1172 float y
= (float)atof(py
);
1173 float z
= (float)atof(pz
);
1175 if(!MapManager::IsValidMapCoord(obj
->GetMapId(),x
,y
,z
))
1177 PSendSysMessage(LANG_INVALID_TARGET_COORD
,x
,y
,obj
->GetMapId());
1178 SetSentErrorMessage(true);
1182 Map
* map
= obj
->GetMap();
1183 map
->Remove(obj
,false);
1185 obj
->Relocate(x
, y
, z
, obj
->GetOrientation());
1186 obj
->SetFloatValue(GAMEOBJECT_POS_X
, x
);
1187 obj
->SetFloatValue(GAMEOBJECT_POS_Y
, y
);
1188 obj
->SetFloatValue(GAMEOBJECT_POS_Z
, z
);
1196 PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE
, obj
->GetGUIDLow());
1201 //demorph player or unit
1202 bool ChatHandler::HandleDeMorphCommand(const char* /*args*/)
1204 Unit
*target
= getSelectedUnit();
1206 target
= m_session
->GetPlayer();
1209 // check online security
1210 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1218 //add item in vendorlist
1219 bool ChatHandler::HandleAddVendorItemCommand(const char* args
)
1224 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1227 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1228 SetSentErrorMessage(true);
1232 uint32 itemId
= atol(pitem
);
1234 char* fmaxcount
= strtok(NULL
, " "); //add maxcount, default: 0
1235 uint32 maxcount
= 0;
1237 maxcount
= atol(fmaxcount
);
1239 char* fincrtime
= strtok(NULL
, " "); //add incrtime, default: 0
1240 uint32 incrtime
= 0;
1242 incrtime
= atol(fincrtime
);
1244 char* fextendedcost
= strtok(NULL
, " "); //add ExtendedCost, default: 0
1245 uint32 extendedcost
= fextendedcost
? atol(fextendedcost
) : 0;
1247 Creature
* vendor
= getSelectedCreature();
1249 uint32 vendor_entry
= vendor
? vendor
->GetEntry() : 0;
1251 if(!objmgr
.IsVendorItemValid(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
,m_session
->GetPlayer()))
1253 SetSentErrorMessage(true);
1257 objmgr
.AddVendorItem(vendor_entry
,itemId
,maxcount
,incrtime
,extendedcost
);
1259 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1261 PSendSysMessage(LANG_ITEM_ADDED_TO_LIST
,itemId
,pProto
->Name1
,maxcount
,incrtime
,extendedcost
);
1265 //del item from vendor list
1266 bool ChatHandler::HandleDelVendorItemCommand(const char* args
)
1271 Creature
* vendor
= getSelectedCreature();
1272 if (!vendor
|| !vendor
->isVendor())
1274 SendSysMessage(LANG_COMMAND_VENDORSELECTION
);
1275 SetSentErrorMessage(true);
1279 char* pitem
= extractKeyFromLink((char*)args
,"Hitem");
1282 SendSysMessage(LANG_COMMAND_NEEDITEMSEND
);
1283 SetSentErrorMessage(true);
1286 uint32 itemId
= atol(pitem
);
1288 if(!objmgr
.RemoveVendorItem(vendor
->GetEntry(),itemId
))
1290 PSendSysMessage(LANG_ITEM_NOT_IN_LIST
,itemId
);
1291 SetSentErrorMessage(true);
1295 ItemPrototype
const* pProto
= objmgr
.GetItemPrototype(itemId
);
1297 PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST
,itemId
,pProto
->Name1
);
1301 //add move for creature
1302 bool ChatHandler::HandleNpcAddMoveCommand(const char* args
)
1307 char* guid_str
= strtok((char*)args
, " ");
1308 char* wait_str
= strtok((char*)NULL
, " ");
1310 uint32 lowguid
= atoi((char*)guid_str
);
1312 Creature
* pCreature
= NULL
;
1314 /* FIXME: impossible without entry
1316 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1319 // attempt check creature existence by DB data
1322 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1325 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1326 SetSentErrorMessage(true);
1332 // obtain real GUID for DB operations
1333 lowguid
= pCreature
->GetDBTableGUIDLow();
1336 int wait
= wait_str
? atoi(wait_str
) : 0;
1341 Player
* player
= m_session
->GetPlayer();
1343 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), wait
, 0);
1345 // update movement type
1346 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
1349 pCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
1350 pCreature
->GetMotionMaster()->Initialize();
1351 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1353 pCreature
->setDeathState(JUST_DIED
);
1354 pCreature
->Respawn();
1356 pCreature
->SaveToDB();
1359 SendSysMessage(LANG_WAYPOINT_ADDED
);
1365 * Set the movement type for an NPC.<br/>
1367 * Valid movement types are:
1369 * <li> stay - NPC wont move </li>
1370 * <li> random - NPC will move randomly according to the spawndist </li>
1371 * <li> way - NPC will move with given waypoints set </li>
1373 * additional parameter: NODEL - so no waypoints are deleted, if you
1374 * change the movement type
1376 bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args
)
1382 // GUID (optional - you can also select the creature)
1383 // stay|random|way (determines the kind of movement)
1384 // NODEL (optional - tells the system NOT to delete any waypoints)
1385 // this is very handy if you want to do waypoints, that are
1386 // later switched on/off according to special events (like escort
1388 char* guid_str
= strtok((char*)args
, " ");
1389 char* type_str
= strtok((char*)NULL
, " ");
1390 char* dontdel_str
= strtok((char*)NULL
, " ");
1392 bool doNotDelete
= false;
1398 Creature
* pCreature
= NULL
;
1402 //sLog.outError("DEBUG: All 3 params are set");
1404 // All 3 params are set
1408 if( stricmp( dontdel_str
, "NODEL" ) == 0 )
1410 //sLog.outError("DEBUG: doNotDelete = true;");
1416 // Only 2 params - but maybe NODEL is set
1419 sLog
.outError("DEBUG: Only 2 params ");
1420 if( stricmp( type_str
, "NODEL" ) == 0 )
1422 //sLog.outError("DEBUG: type_str, NODEL ");
1429 if(!type_str
) // case .setmovetype $move_type (with selected creature)
1431 type_str
= guid_str
;
1432 pCreature
= getSelectedCreature();
1433 if(!pCreature
|| pCreature
->isPet())
1435 lowguid
= pCreature
->GetDBTableGUIDLow();
1437 else // case .setmovetype #creature_guid $move_type (with selected creature)
1439 lowguid
= atoi((char*)guid_str
);
1441 /* impossible without entry
1443 pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT));
1446 // attempt check creature existence by DB data
1449 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
1452 PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND
, lowguid
);
1453 SetSentErrorMessage(true);
1459 lowguid
= pCreature
->GetDBTableGUIDLow();
1463 // now lowguid is low guid really existed creature
1464 // and pCreature point (maybe) to this creature or NULL
1466 MovementGeneratorType move_type
;
1468 std::string type
= type_str
;
1471 move_type
= IDLE_MOTION_TYPE
;
1472 else if(type
== "random")
1473 move_type
= RANDOM_MOTION_TYPE
;
1474 else if(type
== "way")
1475 move_type
= WAYPOINT_MOTION_TYPE
;
1479 // update movement type
1480 if(doNotDelete
== false)
1481 WaypointMgr
.DeletePath(lowguid
);
1485 pCreature
->SetDefaultMovementType(move_type
);
1486 pCreature
->GetMotionMaster()->Initialize();
1487 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
1489 pCreature
->setDeathState(JUST_DIED
);
1490 pCreature
->Respawn();
1492 pCreature
->SaveToDB();
1494 if( doNotDelete
== false )
1496 PSendSysMessage(LANG_MOVE_TYPE_SET
,type_str
);
1500 PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL
,type_str
);
1504 } // HandleNpcSetMoveTypeCommand
1506 //change level of creature or pet
1507 bool ChatHandler::HandleChangeLevelCommand(const char* args
)
1512 uint8 lvl
= (uint8
) atoi((char*)args
);
1513 if ( lvl
< 1 || lvl
> sWorld
.getConfig(CONFIG_MAX_PLAYER_LEVEL
) + 3)
1515 SendSysMessage(LANG_BAD_VALUE
);
1516 SetSentErrorMessage(true);
1520 Creature
* pCreature
= getSelectedCreature();
1523 SendSysMessage(LANG_SELECT_CREATURE
);
1524 SetSentErrorMessage(true);
1528 if(pCreature
->isPet())
1530 ((Pet
*)pCreature
)->GivePetLevel(lvl
);
1534 pCreature
->SetMaxHealth( 100 + 30*lvl
);
1535 pCreature
->SetHealth( 100 + 30*lvl
);
1536 pCreature
->SetLevel( lvl
);
1537 pCreature
->SaveToDB();
1543 //set npcflag of creature
1544 bool ChatHandler::HandleNpcFlagCommand(const char* args
)
1549 uint32 npcFlags
= (uint32
) atoi((char*)args
);
1551 Creature
* pCreature
= getSelectedCreature();
1555 SendSysMessage(LANG_SELECT_CREATURE
);
1556 SetSentErrorMessage(true);
1560 pCreature
->SetUInt32Value(UNIT_NPC_FLAGS
, npcFlags
);
1562 WorldDatabase
.PExecuteLog("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags
, pCreature
->GetEntry());
1564 SendSysMessage(LANG_VALUE_SAVED_REJOIN
);
1569 //set model of creature
1570 bool ChatHandler::HandleNpcSetModelCommand(const char* args
)
1575 uint32 displayId
= (uint32
) atoi((char*)args
);
1577 Creature
*pCreature
= getSelectedCreature();
1579 if(!pCreature
|| pCreature
->isPet())
1581 SendSysMessage(LANG_SELECT_CREATURE
);
1582 SetSentErrorMessage(true);
1586 pCreature
->SetDisplayId(displayId
);
1587 pCreature
->SetNativeDisplayId(displayId
);
1589 pCreature
->SaveToDB();
1594 //morph creature or player
1595 bool ChatHandler::HandleMorphCommand(const char* args
)
1600 uint16 display_id
= (uint16
)atoi((char*)args
);
1602 Unit
*target
= getSelectedUnit();
1604 target
= m_session
->GetPlayer();
1606 // check online security
1607 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1610 target
->SetDisplayId(display_id
);
1615 //set faction of creature
1616 bool ChatHandler::HandleNpcFactionIdCommand(const char* args
)
1621 uint32 factionId
= (uint32
) atoi((char*)args
);
1623 if (!sFactionTemplateStore
.LookupEntry(factionId
))
1625 PSendSysMessage(LANG_WRONG_FACTION
, factionId
);
1626 SetSentErrorMessage(true);
1630 Creature
* pCreature
= getSelectedCreature();
1634 SendSysMessage(LANG_SELECT_CREATURE
);
1635 SetSentErrorMessage(true);
1639 pCreature
->setFaction(factionId
);
1641 // faction is set in creature_template - not inside creature
1644 if(CreatureInfo
const *cinfo
= pCreature
->GetCreatureInfo())
1646 const_cast<CreatureInfo
*>(cinfo
)->faction_A
= factionId
;
1647 const_cast<CreatureInfo
*>(cinfo
)->faction_H
= factionId
;
1651 WorldDatabase
.PExecuteLog("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId
, factionId
, pCreature
->GetEntry());
1657 bool ChatHandler::HandleKickPlayerCommand(const char *args
)
1661 Player
* player
= getSelectedPlayer();
1665 SendSysMessage(LANG_NO_CHAR_SELECTED
);
1666 SetSentErrorMessage(true);
1670 if(player
==m_session
->GetPlayer())
1672 SendSysMessage(LANG_COMMAND_KICKSELF
);
1673 SetSentErrorMessage(true);
1677 // check online security
1678 if (HasLowerSecurity(player
, 0))
1681 player
->GetSession()->KickPlayer();
1685 std::string name
= extractPlayerNameFromLink((char*)args
);
1688 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1689 SetSentErrorMessage(true);
1693 if(m_session
&& name
==m_session
->GetPlayer()->GetName())
1695 SendSysMessage(LANG_COMMAND_KICKSELF
);
1696 SetSentErrorMessage(true);
1700 // check online security
1701 Player
* player
= ObjectAccessor::Instance().FindPlayerByName(name
.c_str());
1702 if (player
&& HasLowerSecurity(player
, 0))
1705 std::string nameLink
= playerLink(name
);
1707 if(sWorld
.KickPlayer(name
))
1709 PSendSysMessage(LANG_COMMAND_KICKMESSAGE
,nameLink
.c_str());
1712 PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER
,nameLink
.c_str());
1718 //set temporary phase mask for player
1719 bool ChatHandler::HandleModifyPhaseCommand(const char* args
)
1724 uint32 phasemask
= (uint32
)atoi((char*)args
);
1726 Unit
*target
= getSelectedUnit();
1728 target
= m_session
->GetPlayer();
1730 // check online security
1731 else if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
1734 target
->SetPhaseMask(phasemask
,true);
1739 //show info of player
1740 bool ChatHandler::HandlePInfoCommand(const char* args
)
1742 Player
* target
= NULL
;
1743 uint64 targetGUID
= 0;
1745 char* px
= strtok((char*)args
, " ");
1752 name
= extractPlayerNameFromLink(px
);
1755 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1756 SetSentErrorMessage(true);
1760 target
= objmgr
.GetPlayer(name
.c_str());
1762 py
= strtok(NULL
, " ");
1765 targetGUID
= objmgr
.GetPlayerGUIDByName(name
);
1767 py
= strtok(NULL
, " ");
1773 if(!target
&& !targetGUID
)
1775 target
= getSelectedPlayer();
1778 if(!target
&& !targetGUID
)
1780 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1781 SetSentErrorMessage(true);
1787 uint32 total_player_time
= 0;
1791 // get additional information from Player object
1794 // check online security
1795 if (HasLowerSecurity(target
, 0))
1798 targetGUID
= target
->GetGUID();
1799 name
= target
->GetName(); // re-read for case getSelectedPlayer() target
1800 accId
= target
->GetSession()->GetAccountId();
1801 money
= target
->GetMoney();
1802 total_player_time
= target
->GetTotalPlayedTime();
1803 level
= target
->getLevel();
1804 latency
= target
->GetSession()->GetLatency();
1806 // get additional information from DB
1809 // check offline security
1810 if (HasLowerSecurity(NULL
, targetGUID
))
1814 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID
));
1817 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1818 SetSentErrorMessage(true);
1821 Field
*fields
= result
->Fetch();
1822 total_player_time
= fields
[0].GetUInt32();
1826 if (!Player::LoadValuesArrayFromDB(data
,targetGUID
))
1828 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1829 SetSentErrorMessage(true);
1833 money
= Player::GetUInt32ValueFromArray(data
, PLAYER_FIELD_COINAGE
);
1834 level
= Player::GetUInt32ValueFromArray(data
, UNIT_FIELD_LEVEL
);
1836 accId
= objmgr
.GetPlayerAccountIdByGUID(targetGUID
);
1839 std::string username
= GetMangosString(LANG_ERROR
);
1840 std::string last_ip
= GetMangosString(LANG_ERROR
);
1841 uint32 security
= 0;
1842 std::string last_login
= GetMangosString(LANG_ERROR
);
1844 QueryResult
* result
= loginDatabase
.PQuery("SELECT username,gmlevel,last_ip,last_login FROM account WHERE id = '%u'",accId
);
1847 Field
* fields
= result
->Fetch();
1848 username
= fields
[0].GetCppString();
1849 security
= fields
[1].GetUInt32();
1851 if(!m_session
|| m_session
->GetSecurity() >= security
)
1853 last_ip
= fields
[2].GetCppString();
1854 last_login
= fields
[3].GetCppString();
1865 std::string nameLink
= playerLink(name
);
1867 PSendSysMessage(LANG_PINFO_ACCOUNT
, (target
?"":GetMangosString(LANG_OFFLINE
)), nameLink
.c_str(), GUID_LOPART(targetGUID
), username
.c_str(), accId
, security
, last_ip
.c_str(), last_login
.c_str(), latency
);
1869 std::string timeStr
= secsToTimeString(total_player_time
,true,true);
1870 uint32 gold
= money
/GOLD
;
1871 uint32 silv
= (money
% GOLD
) / SILVER
;
1872 uint32 copp
= (money
% GOLD
) % SILVER
;
1873 PSendSysMessage(LANG_PINFO_LEVEL
, timeStr
.c_str(), level
, gold
,silv
,copp
);
1875 if ( py
&& strncmp(py
, "rep", 3) == 0 )
1879 // rep option not implemented for offline case
1880 SendSysMessage(LANG_PINFO_NO_REP
);
1881 SetSentErrorMessage(true);
1886 for(FactionStateList::const_iterator itr
= target
->m_factions
.begin(); itr
!= target
->m_factions
.end(); ++itr
)
1888 FactionEntry
const *factionEntry
= sFactionStore
.LookupEntry(itr
->second
.ID
);
1890 FactionName
= factionEntry
->name
[m_session
->GetSessionDbcLocale()];
1892 FactionName
= "#Not found#";
1893 ReputationRank rank
= target
->GetReputationRank(factionEntry
);
1894 std::string rankName
= GetMangosString(ReputationRankStrIndex
[rank
]);
1895 std::ostringstream ss
;
1896 ss
<< itr
->second
.ID
<< ": |cffffffff|Hfaction:" << itr
->second
.ID
<< "|h[" << FactionName
<< "]|h|r " << rankName
<< "|h|r (" << target
->GetReputation(factionEntry
) << ")";
1898 if(itr
->second
.Flags
& FACTION_FLAG_VISIBLE
)
1899 ss
<< GetMangosString(LANG_FACTION_VISIBLE
);
1900 if(itr
->second
.Flags
& FACTION_FLAG_AT_WAR
)
1901 ss
<< GetMangosString(LANG_FACTION_ATWAR
);
1902 if(itr
->second
.Flags
& FACTION_FLAG_PEACE_FORCED
)
1903 ss
<< GetMangosString(LANG_FACTION_PEACE_FORCED
);
1904 if(itr
->second
.Flags
& FACTION_FLAG_HIDDEN
)
1905 ss
<< GetMangosString(LANG_FACTION_HIDDEN
);
1906 if(itr
->second
.Flags
& FACTION_FLAG_INVISIBLE_FORCED
)
1907 ss
<< GetMangosString(LANG_FACTION_INVISIBLE_FORCED
);
1908 if(itr
->second
.Flags
& FACTION_FLAG_INACTIVE
)
1909 ss
<< GetMangosString(LANG_FACTION_INACTIVE
);
1911 SendSysMessage(ss
.str().c_str());
1918 void ChatHandler::ShowTicket(uint64 guid
, char const* text
, char const* time
)
1921 if(!objmgr
.GetPlayerNameByGUID(guid
,name
))
1922 name
= GetMangosString(LANG_UNKNOWN
);
1924 std::string nameLink
= playerLink(name
);
1926 PSendSysMessage(LANG_COMMAND_TICKETVIEW
, nameLink
.c_str(),time
,text
);
1930 bool ChatHandler::HandleTicketCommand(const char* args
)
1932 char* px
= strtok((char*)args
, " ");
1939 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1940 SetSentErrorMessage(true);
1944 size_t count
= ticketmgr
.GetTicketCount();
1946 bool accept
= m_session
->GetPlayer()->isAcceptTickets();
1948 PSendSysMessage(LANG_COMMAND_TICKETCOUNT
, count
, accept
? GetMangosString(LANG_ON
) : GetMangosString(LANG_OFF
));
1953 if(strncmp(px
,"on",3) == 0)
1957 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1958 SetSentErrorMessage(true);
1962 m_session
->GetPlayer()->SetAcceptTicket(true);
1963 SendSysMessage(LANG_COMMAND_TICKETON
);
1968 if(strncmp(px
,"off",4) == 0)
1972 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
1973 SetSentErrorMessage(true);
1977 m_session
->GetPlayer()->SetAcceptTicket(false);
1978 SendSysMessage(LANG_COMMAND_TICKETOFF
);
1986 QueryResult
*result
= CharacterDatabase
.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
, num
-1);
1990 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
1991 SetSentErrorMessage(true);
1995 Field
* fields
= result
->Fetch();
1997 uint32 guid
= fields
[0].GetUInt32();
1998 char const* text
= fields
[1].GetString();
1999 char const* time
= fields
[2].GetString();
2001 ShowTicket(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
),text
,time
);
2006 std::string name
= extractPlayerNameFromLink(px
);
2009 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2010 SetSentErrorMessage(true);
2014 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2019 // ticket $char_name
2020 GMTicket
* ticket
= ticketmgr
.GetGMTicket(GUID_LOPART(guid
));
2024 std::string time
= TimeToTimestampStr(ticket
->GetLastUpdate());
2026 ShowTicket(guid
, ticket
->GetText(), time
.c_str());
2032 bool ChatHandler::HandleDelTicketCommand(const char *args
)
2034 char* px
= strtok((char*)args
, " ");
2039 if(strncmp(px
,"all",4) == 0)
2041 ticketmgr
.DeleteAll();
2042 SendSysMessage(LANG_COMMAND_ALLTICKETDELETED
);
2046 int num
= (uint32
)atoi(px
);
2051 QueryResult
* result
= CharacterDatabase
.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_
,num
-1);
2054 PSendSysMessage(LANG_COMMAND_TICKENOTEXIST
, num
);
2055 SetSentErrorMessage(true);
2058 Field
* fields
= result
->Fetch();
2059 uint32 guid
= fields
[0].GetUInt32();
2062 ticketmgr
.Delete(guid
);
2065 if(Player
* pl
= objmgr
.GetPlayer(MAKE_NEW_GUID(guid
, 0, HIGHGUID_PLAYER
)))
2067 pl
->GetSession()->SendGMTicketGetTicket(0x0A, 0);
2068 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
, GetNameLink(pl
).c_str());
2071 PSendSysMessage(LANG_COMMAND_TICKETDEL
);
2076 std::string name
= extractPlayerNameFromLink(px
);
2079 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
2080 SetSentErrorMessage(true);
2084 uint64 guid
= objmgr
.GetPlayerGUIDByName(name
);
2089 // delticket $char_name
2090 ticketmgr
.Delete(GUID_LOPART(guid
));
2092 // notify players about ticket deleting
2093 if(Player
* sender
= objmgr
.GetPlayer(guid
))
2094 sender
->GetSession()->SendGMTicketGetTicket(0x0A,0);
2096 std::string nameLink
= playerLink(name
);
2098 PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL
,nameLink
.c_str());
2102 //set spawn dist of creature
2103 bool ChatHandler::HandleNpcSpawnDistCommand(const char* args
)
2108 float option
= atof((char*)args
);
2111 SendSysMessage(LANG_BAD_VALUE
);
2115 MovementGeneratorType mtype
= IDLE_MOTION_TYPE
;
2117 mtype
= RANDOM_MOTION_TYPE
;
2119 Creature
*pCreature
= getSelectedCreature();
2120 uint32 u_guidlow
= 0;
2123 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2127 pCreature
->SetRespawnRadius((float)option
);
2128 pCreature
->SetDefaultMovementType(mtype
);
2129 pCreature
->GetMotionMaster()->Initialize();
2130 if(pCreature
->isAlive()) // dead creature will reset movement generator at respawn
2132 pCreature
->setDeathState(JUST_DIED
);
2133 pCreature
->Respawn();
2136 WorldDatabase
.PExecuteLog("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option
,mtype
,u_guidlow
);
2137 PSendSysMessage(LANG_COMMAND_SPAWNDIST
,option
);
2141 bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args
)
2146 char* stime
= strtok((char*)args
, " ");
2151 int i_stime
= atoi((char*)stime
);
2155 SendSysMessage(LANG_BAD_VALUE
);
2156 SetSentErrorMessage(true);
2160 Creature
*pCreature
= getSelectedCreature();
2161 uint32 u_guidlow
= 0;
2164 u_guidlow
= pCreature
->GetDBTableGUIDLow();
2168 WorldDatabase
.PExecuteLog("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime
,u_guidlow
);
2169 pCreature
->SetRespawnDelay((uint32
)i_stime
);
2170 PSendSysMessage(LANG_COMMAND_SPAWNTIME
,i_stime
);
2176 * Add a waypoint to a creature.
2178 * The user can either select an npc or provide its GUID.
2180 * The user can even select a visual waypoint - then the new waypoint
2181 * is placed *after* the selected one - this makes insertion of new
2182 * waypoints possible.
2186 * -> adds a waypoint to the npc with the GUID 12345
2189 * -> adds a waypoint to the currently selected creature
2192 * @param args if the user did not provide a GUID, it is NULL
2194 * @return true - command did succeed, false - something went wrong
2196 bool ChatHandler::HandleWpAddCommand(const char* args
)
2198 sLog
.outDebug("DEBUG: HandleWpAddCommand");
2201 char* guid_str
= NULL
;
2205 guid_str
= strtok((char*)args
, " ");
2210 Creature
* target
= getSelectedCreature();
2211 // Did player provide a GUID?
2214 sLog
.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
2217 // -> Player must have selected a creature
2219 if(!target
|| target
->isPet())
2221 SendSysMessage(LANG_SELECT_CREATURE
);
2222 SetSentErrorMessage(true);
2225 if (target
->GetEntry() == VISUAL_WAYPOINT
)
2227 sLog
.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
2229 QueryResult
*result
=
2230 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
2231 target
->GetGUIDLow() );
2234 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUIDLow());
2235 // User selected a visual spawnpoint -> get the NPC
2237 // Since we compare float values, we have to deal with
2238 // some difficulties.
2239 // Here we search for all waypoints that only differ in one from 1 thousand
2240 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2241 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2242 const char* maxDIFF
= "0.01";
2243 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 )",
2244 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2247 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
2248 SetSentErrorMessage(true);
2254 Field
*fields
= result
->Fetch();
2255 lowguid
= fields
[0].GetUInt32();
2256 point
= fields
[1].GetUInt32();
2257 }while( result
->NextRow() );
2260 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2263 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2264 SetSentErrorMessage(true);
2268 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2271 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2272 SetSentErrorMessage(true);
2278 lowguid
= target
->GetDBTableGUIDLow();
2283 sLog
.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
2286 // Warn if player also selected a creature
2287 // -> Creature selection is ignored <-
2290 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2292 lowguid
= atoi((char*)guid_str
);
2294 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2297 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2298 SetSentErrorMessage(true);
2302 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2303 if(!target
|| target
->isPet())
2305 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2306 SetSentErrorMessage(true);
2310 // lowguid -> GUID of the NPC
2311 // point -> number of the waypoint (if not 0)
2312 sLog
.outDebug("DEBUG: HandleWpAddCommand - danach");
2314 sLog
.outDebug("DEBUG: HandleWpAddCommand - point == 0");
2316 Player
* player
= m_session
->GetPlayer();
2317 WaypointMgr
.AddLastNode(lowguid
, player
->GetPositionX(), player
->GetPositionY(), player
->GetPositionZ(), player
->GetOrientation(), 0, 0);
2319 // update movement type
2322 target
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2323 target
->GetMotionMaster()->Initialize();
2324 if(target
->isAlive()) // dead creature will reset movement generator at respawn
2326 target
->setDeathState(JUST_DIED
);
2332 WorldDatabase
.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE
,lowguid
);
2334 PSendSysMessage(LANG_WAYPOINT_ADDED
, point
, lowguid
);
2337 } // HandleWpAddCommand
2340 * .wp modify emote | spell | text | del | move | add
2342 * add -> add a WP after the selected visual waypoint
2343 * User must select a visual waypoint and then issue ".wp modify add"
2346 * User has selected a visual waypoint before.
2347 * <emoteID> is added to this waypoint. Everytime the
2348 * NPC comes to this waypoint, the emote is called.
2350 * emote <GUID> <WPNUM> <emoteID>
2351 * User has not selected visual waypoint before.
2352 * For the waypoint <WPNUM> for the NPC with <GUID>
2353 * an emote <emoteID> is added.
2354 * Everytime the NPC comes to this waypoint, the emote is called.
2357 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2359 bool ChatHandler::HandleWpModifyCommand(const char* args
)
2361 sLog
.outDebug("DEBUG: HandleWpModifyCommand");
2366 // first arg: add del text emote spell waittime move
2367 char* show_str
= strtok((char*)args
, " ");
2373 std::string show
= show_str
;
2375 // Remember: "show" must also be the name of a column!
2376 if( (show
!= "emote") && (show
!= "spell") && (show
!= "textid1") && (show
!= "textid2")
2377 && (show
!= "textid3") && (show
!= "textid4") && (show
!= "textid5")
2378 && (show
!= "waittime") && (show
!= "del") && (show
!= "move") && (show
!= "add")
2379 && (show
!= "model1") && (show
!= "model2") && (show
!= "orientation"))
2384 // Next arg is: <GUID> <WPNUM> <ARGUMENT>
2386 // Did user provide a GUID
2387 // or did the user select a creature?
2388 // -> variable lowguid is filled with the GUID of the NPC
2392 Creature
* target
= getSelectedCreature();
2396 sLog
.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
2398 // Did the user select a visual spawnpoint?
2399 if (target
->GetEntry() != VISUAL_WAYPOINT
)
2401 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2402 SetSentErrorMessage(true);
2406 wpGuid
= target
->GetGUIDLow();
2408 // The visual waypoint
2409 QueryResult
*result
=
2410 WorldDatabase
.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
2411 target
->GetGUIDLow() );
2414 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, wpGuid
);
2415 SetSentErrorMessage(true);
2418 sLog
.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
2420 Field
*fields
= result
->Fetch();
2421 lowguid
= fields
[0].GetUInt32();
2422 point
= fields
[1].GetUInt32();
2425 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
2430 // User did provide <GUID> <WPNUM>
2432 char* guid_str
= strtok((char*)NULL
, " ");
2435 SendSysMessage(LANG_WAYPOINT_NOGUID
);
2438 lowguid
= atoi((char*)guid_str
);
2440 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2443 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2444 SetSentErrorMessage(true);
2448 PSendSysMessage("DEBUG: GUID provided: %d", lowguid
);
2450 char* point_str
= strtok((char*)NULL
, " ");
2453 SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN
);
2456 point
= atoi((char*)point_str
);
2458 PSendSysMessage("DEBUG: wpNumber provided: %d", point
);
2460 // Now we need the GUID of the visual waypoint
2461 // -> "del", "move", "add" command
2463 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid
, point
);
2466 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, lowguid
, point
);
2467 SetSentErrorMessage(true);
2471 Field
*fields
= result
->Fetch();
2472 wpGuid
= fields
[0].GetUInt32();
2478 char* arg_str
= NULL
;
2479 // Check for argument
2480 if( (show
.find("text") == std::string::npos
) && (show
!= "del") && (show
!= "move") && (show
!= "add"))
2482 // Text is enclosed in "<>", all other arguments not
2483 if( show
.find("text") != std::string::npos
)
2484 arg_str
= strtok((char*)NULL
, "<>");
2486 arg_str
= strtok((char*)NULL
, " ");
2490 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, show_str
);
2495 sLog
.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
2497 // wpGuid -> GUID of the waypoint creature
2498 // lowguid -> GUID of the NPC
2499 // point -> waypoint number
2501 // Special functions:
2502 // add - move - del -> no args commands
2503 // Add a waypoint after the selected visual
2504 if(show
== "add" && target
)
2506 PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid
);
2508 // Get the creature for which we read the waypoint
2509 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2512 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2513 SetSentErrorMessage(true);
2517 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2521 PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND
);
2522 SetSentErrorMessage(true);
2526 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
2529 // Add the visual spawnpoint (DB only)
2530 // Adjust the waypoints
2531 // Respawn the owner of the waypoints
2532 sLog
.outDebug("DEBUG: HandleWpModifyCommand - add");
2534 Player
* chr
= m_session
->GetPlayer();
2535 Map
*map
= chr
->GetMap();
2539 npcCreature
->GetMotionMaster()->Initialize();
2540 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2542 npcCreature
->setDeathState(JUST_DIED
);
2543 npcCreature
->Respawn();
2547 // create the waypoint creature
2549 Creature
* wpCreature
= new Creature
;
2550 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
,0))
2552 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2557 wpCreature
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2559 if(!wpCreature
->IsPositionValid())
2561 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());
2566 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2567 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2568 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(), map
);
2569 map
->Add(wpCreature
);
2570 wpGuid
= wpCreature
->GetGUIDLow();
2574 WaypointMgr
.AddAfterNode(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), 0, 0, wpGuid
);
2579 PSendSysMessage(LANG_WAYPOINT_ADDED_NO
, point
+1);
2583 if(show
== "del" && target
)
2585 PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid
);
2587 // Get the creature for which we read the waypoint
2588 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2591 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2592 SetSentErrorMessage(true);
2596 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2599 Creature
* wpCreature
= NULL
;
2602 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2603 wpCreature
->DeleteFromDB();
2604 wpCreature
->CleanupsBeforeDelete();
2605 wpCreature
->AddObjectToRemoveList();
2609 // Remove the visual spawnpoint
2610 // Adjust the waypoints
2611 // Respawn the owner of the waypoints
2613 WaypointMgr
.DeleteNode(lowguid
, point
);
2617 // Any waypoints left?
2618 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid
);
2621 npcCreature
->SetDefaultMovementType(RANDOM_MOTION_TYPE
);
2625 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2628 npcCreature
->GetMotionMaster()->Initialize();
2629 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2631 npcCreature
->setDeathState(JUST_DIED
);
2632 npcCreature
->Respawn();
2634 npcCreature
->SaveToDB();
2637 PSendSysMessage(LANG_WAYPOINT_REMOVED
);
2641 if(show
== "move" && target
)
2643 PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid
);
2645 Player
*chr
= m_session
->GetPlayer();
2646 Map
*map
= chr
->GetMap();
2648 // Get the creature for which we read the waypoint
2649 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2652 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2653 SetSentErrorMessage(true);
2657 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2660 Creature
* wpCreature
= NULL
;
2662 // Move the visual spawnpoint
2663 // Respawn the owner of the waypoints
2666 wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpGuid
, VISUAL_WAYPOINT
, HIGHGUID_UNIT
));
2667 wpCreature
->DeleteFromDB();
2668 wpCreature
->CleanupsBeforeDelete();
2669 wpCreature
->AddObjectToRemoveList();
2671 Creature
* wpCreature2
= new Creature
;
2672 if (!wpCreature2
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT
, 0))
2674 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, VISUAL_WAYPOINT
);
2679 wpCreature2
->Relocate(chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ(), chr
->GetOrientation());
2681 if(!wpCreature2
->IsPositionValid())
2683 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());
2688 wpCreature2
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
2689 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
2690 wpCreature2
->LoadFromDB(wpCreature2
->GetDBTableGUIDLow(), map
);
2691 map
->Add(wpCreature2
);
2692 //npcCreature->GetMap()->Add(wpCreature2);
2695 WaypointMgr
.SetNodePosition(lowguid
, point
, chr
->GetPositionX(), chr
->GetPositionY(), chr
->GetPositionZ());
2699 npcCreature
->GetMotionMaster()->Initialize();
2700 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2702 npcCreature
->setDeathState(JUST_DIED
);
2703 npcCreature
->Respawn();
2706 PSendSysMessage(LANG_WAYPOINT_CHANGED
);
2711 // Create creature - npc that has the waypoint
2712 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2715 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2716 SetSentErrorMessage(true);
2720 // set in game textids not supported
2721 if( show
== "textid1" || show
== "textid2" || show
== "textid3" ||
2722 show
== "textid4" || show
== "textid5" )
2727 WaypointMgr
.SetNodeText(lowguid
, point
, show_str
, arg_str
);
2729 Creature
* npcCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(), MAKE_NEW_GUID(lowguid
, data
->id
, HIGHGUID_UNIT
));
2732 npcCreature
->SetDefaultMovementType(WAYPOINT_MOTION_TYPE
);
2733 npcCreature
->GetMotionMaster()->Initialize();
2734 if(npcCreature
->isAlive()) // dead creature will reset movement generator at respawn
2736 npcCreature
->setDeathState(JUST_DIED
);
2737 npcCreature
->Respawn();
2740 PSendSysMessage(LANG_WAYPOINT_CHANGED_NO
, show_str
);
2746 * .wp show info | on | off
2748 * info -> User has selected a visual waypoint before
2750 * info <GUID> <WPNUM> -> User did not select a visual waypoint and
2751 * provided the GUID of the NPC and the number of
2754 * on -> User has selected an NPC; all visual waypoints for this
2755 * NPC are added to the world
2757 * on <GUID> -> User did not select an NPC - instead the GUID of the
2758 * NPC is provided. All visual waypoints for this NPC
2759 * are added from the world.
2761 * off -> User has selected an NPC; all visual waypoints for this
2762 * NPC are removed from the world.
2764 * on <GUID> -> User did not select an NPC - instead the GUID of the
2765 * NPC is provided. All visual waypoints for this NPC
2766 * are removed from the world.
2770 bool ChatHandler::HandleWpShowCommand(const char* args
)
2772 sLog
.outDebug("DEBUG: HandleWpShowCommand");
2777 // first arg: on, off, first, last
2778 char* show_str
= strtok((char*)args
, " ");
2783 // second arg: GUID (optional, if a creature is selected)
2784 char* guid_str
= strtok((char*)NULL
, " ");
2785 sLog
.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str
, guid_str
);
2790 // Did user provide a GUID
2791 // or did the user select a creature?
2792 // -> variable lowguid is filled with the GUID
2793 Creature
* target
= getSelectedCreature();
2794 // Did player provide a GUID?
2797 sLog
.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
2799 // -> Player must have selected a creature
2803 SendSysMessage(LANG_SELECT_CREATURE
);
2804 SetSentErrorMessage(true);
2810 sLog
.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
2812 // Warn if player also selected a creature
2813 // -> Creature selection is ignored <-
2816 SendSysMessage(LANG_WAYPOINT_CREATSELECTED
);
2819 uint32 lowguid
= atoi((char*)guid_str
);
2821 CreatureData
const* data
= objmgr
.GetCreatureData(lowguid
);
2824 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2825 SetSentErrorMessage(true);
2829 target
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(lowguid
,data
->id
,HIGHGUID_UNIT
));
2833 PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND
, lowguid
);
2834 SetSentErrorMessage(true);
2839 uint32 lowguid
= target
->GetDBTableGUIDLow();
2841 std::string show
= show_str
;
2844 sLog
.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid
, show_str
);
2846 // Show info for the selected waypoint
2849 PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid
);
2851 // Check if the user did specify a visual waypoint
2852 if( target
->GetEntry() != VISUAL_WAYPOINT
)
2854 PSendSysMessage(LANG_WAYPOINT_VP_SELECT
);
2855 SetSentErrorMessage(true);
2859 //PSendSysMessage("wp on, GUID: %u", lowguid);
2861 //pCreature->GetPositionX();
2863 QueryResult
*result
=
2864 WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
2865 target
->GetGUIDLow() );
2868 // Since we compare float values, we have to deal with
2869 // some difficulties.
2870 // Here we search for all waypoints that only differ in one from 1 thousand
2871 // (0.001) - There is no other way to compare C++ floats with mySQL floats
2872 // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
2873 const char* maxDIFF
= "0.01";
2874 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH
, target
->GetGUID());
2876 result
= WorldDatabase
.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
2877 target
->GetPositionX(), maxDIFF
, target
->GetPositionY(), maxDIFF
, target
->GetPositionZ(), maxDIFF
);
2880 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, lowguid
);
2881 SetSentErrorMessage(true);
2887 Field
*fields
= result
->Fetch();
2888 uint32 creGUID
= fields
[0].GetUInt32();
2889 uint32 point
= fields
[1].GetUInt32();
2890 int waittime
= fields
[2].GetUInt32();
2891 uint32 emote
= fields
[3].GetUInt32();
2892 uint32 spell
= fields
[4].GetUInt32();
2893 uint32 textid
[MAX_WAYPOINT_TEXT
];
2894 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
2895 textid
[i
] = fields
[5+i
].GetUInt32();
2896 uint32 model1
= fields
[10].GetUInt32();
2897 uint32 model2
= fields
[11].GetUInt32();
2899 // Get the creature for which we read the waypoint
2900 Creature
* wpCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(creGUID
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2902 PSendSysMessage(LANG_WAYPOINT_INFO_TITLE
, point
, (wpCreature
? wpCreature
->GetName() : "<not found>"), creGUID
);
2903 PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME
, waittime
);
2904 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 1, model1
);
2905 PSendSysMessage(LANG_WAYPOINT_INFO_MODEL
, 2, model2
);
2906 PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE
, emote
);
2907 PSendSysMessage(LANG_WAYPOINT_INFO_SPELL
, spell
);
2908 for(int i
= 0; i
< MAX_WAYPOINT_TEXT
; ++i
)
2909 PSendSysMessage(LANG_WAYPOINT_INFO_TEXT
, i
+1, textid
[i
], (textid
[i
] ? GetMangosString(textid
[i
]) : ""));
2911 }while( result
->NextRow() );
2919 PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid
);
2921 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid
);
2924 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
2925 SetSentErrorMessage(true);
2928 // Delete all visuals for this NPC
2929 QueryResult
*result2
= WorldDatabase
.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid
);
2932 bool hasError
= false;
2935 Field
*fields
= result2
->Fetch();
2936 uint32 wpguid
= fields
[0].GetUInt32();
2937 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(wpguid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
2941 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, wpguid
);
2943 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", wpguid
);
2947 pCreature
->DeleteFromDB();
2948 pCreature
->CleanupsBeforeDelete();
2949 pCreature
->AddObjectToRemoveList();
2952 }while( result2
->NextRow() );
2956 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
2957 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
2958 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
2964 Field
*fields
= result
->Fetch();
2965 uint32 point
= fields
[0].GetUInt32();
2966 float x
= fields
[1].GetFloat();
2967 float y
= fields
[2].GetFloat();
2968 float z
= fields
[3].GetFloat();
2970 uint32 id
= VISUAL_WAYPOINT
;
2972 Player
*chr
= m_session
->GetPlayer();
2973 Map
*map
= chr
->GetMap();
2974 float o
= chr
->GetOrientation();
2976 Creature
* wpCreature
= new Creature
;
2977 if (!wpCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
2979 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
2985 wpCreature
->Relocate(x
, y
, z
, o
);
2987 if(!wpCreature
->IsPositionValid())
2989 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());
2995 wpCreature
->SetVisibility(VISIBILITY_OFF
);
2996 sLog
.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
2997 // set "wpguid" column to the visual waypoint
2998 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature
->GetGUIDLow(), lowguid
, point
);
3000 wpCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3001 // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
3002 wpCreature
->LoadFromDB(wpCreature
->GetDBTableGUIDLow(),map
);
3003 map
->Add(wpCreature
);
3004 //wpCreature->GetMap()->Add(wpCreature);
3005 }while( result
->NextRow() );
3014 PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid
);
3016 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid
);
3019 PSendSysMessage(LANG_WAYPOINT_NOTFOUND
, lowguid
);
3020 SetSentErrorMessage(true);
3024 Field
*fields
= result
->Fetch();
3025 float x
= fields
[0].GetFloat();
3026 float y
= fields
[1].GetFloat();
3027 float z
= fields
[2].GetFloat();
3028 uint32 id
= VISUAL_WAYPOINT
;
3030 Player
*chr
= m_session
->GetPlayer();
3031 float o
= chr
->GetOrientation();
3032 Map
*map
= chr
->GetMap();
3034 Creature
* pCreature
= new Creature
;
3035 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
),map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3037 PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED
, id
);
3043 pCreature
->Relocate(x
, y
, z
, o
);
3045 if(!pCreature
->IsPositionValid())
3047 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());
3053 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3054 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3055 map
->Add(pCreature
);
3056 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
3065 PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid
);
3067 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid
);
3070 Maxpoint
= (*result
)[0].GetUInt32();
3077 result
= WorldDatabase
.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint
, lowguid
);
3080 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST
, lowguid
);
3081 SetSentErrorMessage(true);
3084 Field
*fields
= result
->Fetch();
3085 float x
= fields
[0].GetFloat();
3086 float y
= fields
[1].GetFloat();
3087 float z
= fields
[2].GetFloat();
3088 uint32 id
= VISUAL_WAYPOINT
;
3090 Player
*chr
= m_session
->GetPlayer();
3091 float o
= chr
->GetOrientation();
3092 Map
*map
= chr
->GetMap();
3094 Creature
* pCreature
= new Creature
;
3095 if (!pCreature
->Create(objmgr
.GenerateLowGuid(HIGHGUID_UNIT
), map
, chr
->GetPhaseMaskForSpawn(), id
, 0))
3097 PSendSysMessage(LANG_WAYPOINT_NOTCREATED
, id
);
3103 pCreature
->Relocate(x
, y
, z
, o
);
3105 if(!pCreature
->IsPositionValid())
3107 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());
3113 pCreature
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()), chr
->GetPhaseMaskForSpawn());
3114 pCreature
->LoadFromDB(pCreature
->GetDBTableGUIDLow(), map
);
3115 map
->Add(pCreature
);
3116 //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
3124 QueryResult
*result
= WorldDatabase
.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT
);
3127 SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND
);
3128 SetSentErrorMessage(true);
3131 bool hasError
= false;
3134 Field
*fields
= result
->Fetch();
3135 uint32 guid
= fields
[0].GetUInt32();
3136 Creature
* pCreature
= ObjectAccessor::GetCreature(*m_session
->GetPlayer(),MAKE_NEW_GUID(guid
,VISUAL_WAYPOINT
,HIGHGUID_UNIT
));
3138 //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
3142 PSendSysMessage(LANG_WAYPOINT_NOTREMOVED
, guid
);
3144 WorldDatabase
.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", guid
);
3148 pCreature
->DeleteFromDB();
3149 pCreature
->CleanupsBeforeDelete();
3150 pCreature
->AddObjectToRemoveList();
3152 }while(result
->NextRow());
3153 // set "wpguid" column to "empty" - no visual waypoint spawned
3154 WorldDatabase
.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
3158 PSendSysMessage(LANG_WAYPOINT_TOOFAR1
);
3159 PSendSysMessage(LANG_WAYPOINT_TOOFAR2
);
3160 PSendSysMessage(LANG_WAYPOINT_TOOFAR3
);
3163 SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED
);
3170 PSendSysMessage("DEBUG: wpshow - no valid command found");
3173 } // HandleWpShowCommand
3175 bool ChatHandler::HandleWpExportCommand(const char *args
)
3180 // Next arg is: <GUID> <ARGUMENT>
3182 // Did user provide a GUID
3183 // or did the user select a creature?
3184 // -> variable lowguid is filled with the GUID of the NPC
3186 Creature
* target
= getSelectedCreature();
3187 char* arg_str
= NULL
;
3190 if (target
->GetEntry() != VISUAL_WAYPOINT
)
3191 lowguid
= target
->GetGUIDLow();
3194 QueryResult
*result
= WorldDatabase
.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target
->GetGUIDLow() );
3197 PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM
, target
->GetGUIDLow());
3200 Field
*fields
= result
->Fetch();
3201 lowguid
= fields
[0].GetUInt32();;
3205 arg_str
= strtok((char*)args
, " ");
3209 // user provided <GUID>
3210 char* guid_str
= strtok((char*)args
, " ");
3213 SendSysMessage(LANG_WAYPOINT_NOGUID
);
3216 lowguid
= atoi((char*)guid_str
);
3218 arg_str
= strtok((char*)NULL
, " ");
3223 PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ
, "export");
3227 PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid
);
3229 QueryResult
*result
= WorldDatabase
.PQuery(
3230 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3231 "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid
);
3235 PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT
);
3236 SetSentErrorMessage(true);
3240 std::ofstream outfile
;
3241 outfile
.open (arg_str
);
3245 Field
*fields
= result
->Fetch();
3247 outfile
<< "INSERT INTO creature_movement ";
3248 outfile
<< "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
3251 outfile
<< fields
[15].GetUInt32(); // id
3253 outfile
<< fields
[0].GetUInt32(); // point
3255 outfile
<< fields
[1].GetFloat(); // position_x
3257 outfile
<< fields
[2].GetFloat(); // position_y
3259 outfile
<< fields
[3].GetUInt32(); // position_z
3261 outfile
<< fields
[4].GetUInt32(); // orientation
3263 outfile
<< fields
[5].GetUInt32(); // model1
3265 outfile
<< fields
[6].GetUInt32(); // model2
3267 outfile
<< fields
[7].GetUInt16(); // waittime
3269 outfile
<< fields
[8].GetUInt32(); // emote
3271 outfile
<< fields
[9].GetUInt32(); // spell
3273 outfile
<< fields
[10].GetUInt32(); // textid1
3275 outfile
<< fields
[11].GetUInt32(); // textid2
3277 outfile
<< fields
[12].GetUInt32(); // textid3
3279 outfile
<< fields
[13].GetUInt32(); // textid4
3281 outfile
<< fields
[14].GetUInt32(); // textid5
3284 } while( result
->NextRow() );
3287 PSendSysMessage(LANG_WAYPOINT_EXPORTED
);
3293 bool ChatHandler::HandleWpImportCommand(const char *args
)
3298 char* arg_str
= strtok((char*)args
, " ");
3303 std::ifstream
infile (arg_str
);
3304 if (infile
.is_open())
3306 while (! infile
.eof() )
3308 getline (infile
,line
);
3309 //cout << line << endl;
3310 QueryResult
*result
= WorldDatabase
.Query(line
.c_str());
3315 PSendSysMessage(LANG_WAYPOINT_IMPORTED
);
3321 bool ChatHandler::HandleRenameCommand(const char* args
)
3323 Player
* target
= NULL
;
3324 uint64 targetGUID
= 0;
3325 std::string oldname
;
3327 char* px
= strtok((char*)args
, " ");
3331 oldname
= extractPlayerNameFromLink(px
);
3334 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3335 SetSentErrorMessage(true);
3339 target
= objmgr
.GetPlayer(oldname
.c_str());
3342 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3345 if(!target
&& !targetGUID
)
3347 target
= getSelectedPlayer();
3350 if(!target
&& !targetGUID
)
3352 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3353 SetSentErrorMessage(true);
3359 // check online security
3360 if (HasLowerSecurity(target
, 0))
3363 PSendSysMessage(LANG_RENAME_PLAYER
, GetNameLink(target
).c_str());
3364 target
->SetAtLoginFlag(AT_LOGIN_RENAME
);
3365 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", target
->GetGUIDLow());
3369 // check offline security
3370 if (HasLowerSecurity(NULL
, targetGUID
))
3373 std::string oldNameLink
= playerLink(oldname
);
3375 PSendSysMessage(LANG_RENAME_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(targetGUID
));
3376 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3382 // customize characters
3383 bool ChatHandler::HandleCustomizeCommand(const char* args
)
3385 Player
* target
= NULL
;
3386 uint64 targetGUID
= 0;
3387 std::string oldname
;
3389 char* px
= strtok((char*)args
, " ");
3393 oldname
= extractPlayerNameFromLink(px
);
3396 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3397 SetSentErrorMessage(true);
3401 target
= objmgr
.GetPlayer(oldname
.c_str());
3404 targetGUID
= objmgr
.GetPlayerGUIDByName(oldname
);
3407 if(!target
&& !targetGUID
)
3409 target
= getSelectedPlayer();
3412 if(!target
&& !targetGUID
)
3414 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3415 SetSentErrorMessage(true);
3421 PSendSysMessage(LANG_CUSTOMIZE_PLAYER
, GetNameLink(target
).c_str());
3422 target
->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE
);
3423 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target
->GetGUIDLow());
3427 std::string oldNameLink
= playerLink(oldname
);
3429 PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID
, oldNameLink
.c_str(), GUID_LOPART(targetGUID
));
3430 CharacterDatabase
.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID
));
3437 bool ChatHandler::HandleGameObjectCommand(const char* args
)
3442 char* pParam1
= strtok((char*)args
, " ");
3446 uint32 id
= atoi((char*)pParam1
);
3450 char* spawntimeSecs
= strtok(NULL
, " ");
3452 const GameObjectInfo
*goI
= objmgr
.GetGameObjectInfo(id
);
3456 PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST
,id
);
3457 SetSentErrorMessage(true);
3461 Player
*chr
= m_session
->GetPlayer();
3462 float x
= float(chr
->GetPositionX());
3463 float y
= float(chr
->GetPositionY());
3464 float z
= float(chr
->GetPositionZ());
3465 float o
= float(chr
->GetOrientation());
3466 Map
*map
= chr
->GetMap();
3468 float rot2
= sin(o
/2);
3469 float rot3
= cos(o
/2);
3471 GameObject
* pGameObj
= new GameObject
;
3472 uint32 db_lowGUID
= objmgr
.GenerateLowGuid(HIGHGUID_GAMEOBJECT
);
3474 if(!pGameObj
->Create(db_lowGUID
, goI
->id
, map
, chr
->GetPhaseMaskForSpawn(), x
, y
, z
, o
, 0, 0, rot2
, rot3
, 0, 1))
3482 uint32 value
= atoi((char*)spawntimeSecs
);
3483 pGameObj
->SetRespawnTime(value
);
3484 //sLog.outDebug("*** spawntimeSecs: %d", value);
3487 // fill the gameobject data and save to the db
3488 pGameObj
->SaveToDB(map
->GetId(), (1 << map
->GetSpawnMode()),chr
->GetPhaseMaskForSpawn());
3490 // this will generate a new guid if the object is in an instance
3491 if(!pGameObj
->LoadFromDB(db_lowGUID
, map
))
3497 sLog
.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT
), goI
->name
, db_lowGUID
, x
, y
, z
, o
);
3501 // TODO: is it really necessary to add both the real and DB table guid here ?
3502 objmgr
.AddGameobjectToGrid(db_lowGUID
, objmgr
.GetGOData(db_lowGUID
));
3504 PSendSysMessage(LANG_GAMEOBJECT_ADD
,id
,goI
->name
,db_lowGUID
,x
,y
,z
);
3509 bool ChatHandler::HandleAnimCommand(const char* args
)
3514 uint32 anim_id
= atoi((char*)args
);
3515 m_session
->GetPlayer()->HandleEmoteCommand(anim_id
);
3520 bool ChatHandler::HandleStandStateCommand(const char* args
)
3525 uint32 anim_id
= atoi((char*)args
);
3526 m_session
->GetPlayer( )->SetUInt32Value( UNIT_NPC_EMOTESTATE
, anim_id
);
3531 bool ChatHandler::HandleAddHonorCommand(const char* args
)
3536 Player
*target
= getSelectedPlayer();
3539 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3540 SetSentErrorMessage(true);
3544 // check online security
3545 if (HasLowerSecurity(target
, 0))
3548 uint32 amount
= (uint32
)atoi(args
);
3549 target
->RewardHonor(NULL
, 1, amount
);
3553 bool ChatHandler::HandleHonorAddKillCommand(const char* /*args*/)
3555 Unit
*target
= getSelectedUnit();
3558 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3559 SetSentErrorMessage(true);
3563 // check online security
3564 if (target
->GetTypeId() == TYPEID_PLAYER
&& HasLowerSecurity((Player
*)target
, 0))
3567 m_session
->GetPlayer()->RewardHonor(target
, 1);
3571 bool ChatHandler::HandleUpdateHonorFieldsCommand(const char* /*args*/)
3573 Player
*target
= getSelectedPlayer();
3576 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3577 SetSentErrorMessage(true);
3581 // check online security
3582 if (HasLowerSecurity(target
, 0))
3585 target
->UpdateHonorFields();
3589 bool ChatHandler::HandleLookupEventCommand(const char* args
)
3594 std::string namepart
= args
;
3595 std::wstring wnamepart
;
3597 // converting string that we try to find to lower case
3598 if(!Utf8toWStr(namepart
,wnamepart
))
3601 wstrToLower(wnamepart
);
3605 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3606 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3608 for(uint32 id
= 0; id
< events
.size(); ++id
)
3610 GameEventData
const& eventData
= events
[id
];
3612 std::string descr
= eventData
.description
;
3616 if (Utf8FitTo(descr
, wnamepart
))
3618 char const* active
= activeEvents
.find(id
) != activeEvents
.end() ? GetMangosString(LANG_ACTIVE
) : "";
3621 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,id
,id
,eventData
.description
.c_str(),active
);
3623 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,id
,eventData
.description
.c_str(),active
);
3630 SendSysMessage(LANG_NOEVENTFOUND
);
3635 bool ChatHandler::HandleEventActiveListCommand(const char* /*args*/)
3639 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3640 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3642 char const* active
= GetMangosString(LANG_ACTIVE
);
3644 for(GameEvent::ActiveEvents::const_iterator itr
= activeEvents
.begin(); itr
!= activeEvents
.end(); ++itr
)
3646 uint32 event_id
= *itr
;
3647 GameEventData
const& eventData
= events
[event_id
];
3650 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT
,event_id
,event_id
,eventData
.description
.c_str(),active
);
3652 PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE
,event_id
,eventData
.description
.c_str(),active
);
3658 SendSysMessage(LANG_NOEVENTFOUND
);
3663 bool ChatHandler::HandleEventInfoCommand(const char* args
)
3668 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3669 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3673 uint32 event_id
= atoi(cId
);
3675 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3677 if(event_id
>=events
.size())
3679 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3680 SetSentErrorMessage(true);
3684 GameEventData
const& eventData
= events
[event_id
];
3685 if(!eventData
.isValid())
3687 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3688 SetSentErrorMessage(true);
3692 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3693 bool active
= activeEvents
.find(event_id
) != activeEvents
.end();
3694 char const* activeStr
= active
? GetMangosString(LANG_ACTIVE
) : "";
3696 std::string startTimeStr
= TimeToTimestampStr(eventData
.start
);
3697 std::string endTimeStr
= TimeToTimestampStr(eventData
.end
);
3699 uint32 delay
= gameeventmgr
.NextCheck(event_id
);
3700 time_t nextTime
= time(NULL
)+delay
;
3701 std::string nextStr
= nextTime
>= eventData
.start
&& nextTime
< eventData
.end
? TimeToTimestampStr(time(NULL
)+delay
) : "-";
3703 std::string occurenceStr
= secsToTimeString(eventData
.occurence
* MINUTE
);
3704 std::string lengthStr
= secsToTimeString(eventData
.length
* MINUTE
);
3706 PSendSysMessage(LANG_EVENT_INFO
,event_id
,eventData
.description
.c_str(),activeStr
,
3707 startTimeStr
.c_str(),endTimeStr
.c_str(),occurenceStr
.c_str(),lengthStr
.c_str(),
3712 bool ChatHandler::HandleEventStartCommand(const char* args
)
3717 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3718 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3722 int32 event_id
= atoi(cId
);
3724 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3726 if(event_id
< 1 || event_id
>=events
.size())
3728 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3729 SetSentErrorMessage(true);
3733 GameEventData
const& eventData
= events
[event_id
];
3734 if(!eventData
.isValid())
3736 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3737 SetSentErrorMessage(true);
3741 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3742 if(activeEvents
.find(event_id
) != activeEvents
.end())
3744 PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE
,event_id
);
3745 SetSentErrorMessage(true);
3749 gameeventmgr
.StartEvent(event_id
,true);
3753 bool ChatHandler::HandleEventStopCommand(const char* args
)
3758 // id or [name] Shift-click form |color|Hgameevent:id|h[name]|h|r
3759 char* cId
= extractKeyFromLink((char*)args
,"Hgameevent");
3763 int32 event_id
= atoi(cId
);
3765 GameEvent::GameEventDataMap
const& events
= gameeventmgr
.GetEventMap();
3767 if(event_id
< 1 || event_id
>=events
.size())
3769 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3770 SetSentErrorMessage(true);
3774 GameEventData
const& eventData
= events
[event_id
];
3775 if(!eventData
.isValid())
3777 SendSysMessage(LANG_EVENT_NOT_EXIST
);
3778 SetSentErrorMessage(true);
3782 GameEvent::ActiveEvents
const& activeEvents
= gameeventmgr
.GetActiveEventList();
3784 if(activeEvents
.find(event_id
) == activeEvents
.end())
3786 PSendSysMessage(LANG_EVENT_NOT_ACTIVE
,event_id
);
3787 SetSentErrorMessage(true);
3791 gameeventmgr
.StopEvent(event_id
,true);
3795 bool ChatHandler::HandleCombatStopCommand(const char* args
)
3801 std::string playername
= extractPlayerNameFromLink((char*)args
);
3802 if(playername
.empty())
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 // check online security
3827 if (HasLowerSecurity(player
, 0))
3830 player
->CombatStop();
3831 player
->getHostilRefManager().deleteReferences();
3835 bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
3837 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3839 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3841 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3845 if( skillInfo
->categoryId
== SKILL_CATEGORY_PROFESSION
|| skillInfo
->categoryId
== SKILL_CATEGORY_SECONDARY
)
3847 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3849 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3853 // skip racial skills
3854 if( skillLine
->racemask
!= 0 )
3857 // skip wrong class skills
3858 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3861 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3864 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3865 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3868 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
,false);
3873 SendSysMessage(LANG_COMMAND_LEARN_ALL_CRAFT
);
3877 bool ChatHandler::HandleLearnAllRecipesCommand(const char* args
)
3879 // Learns all recipes of specified profession and sets skill to max
3880 // Example: .learn all_recipes enchanting
3882 Player
* target
= getSelectedPlayer();
3885 SendSysMessage(LANG_PLAYER_NOT_FOUND
);
3892 std::wstring wnamepart
;
3894 if(!Utf8toWStr(args
,wnamepart
))
3897 // converting string that we try to find to lower case
3898 wstrToLower( wnamepart
);
3900 uint32 classmask
= m_session
->GetPlayer()->getClassMask();
3902 for (uint32 i
= 0; i
< sSkillLineStore
.GetNumRows(); ++i
)
3904 SkillLineEntry
const *skillInfo
= sSkillLineStore
.LookupEntry(i
);
3908 if( skillInfo
->categoryId
!= SKILL_CATEGORY_PROFESSION
&&
3909 skillInfo
->categoryId
!= SKILL_CATEGORY_SECONDARY
)
3912 int loc
= m_session
->GetSessionDbcLocale();
3913 std::string name
= skillInfo
->name
[loc
];
3915 if(Utf8FitTo(name
, wnamepart
))
3917 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
3919 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
3923 if( skillLine
->skillId
!= i
|| skillLine
->forward_spellid
)
3926 // skip racial skills
3927 if( skillLine
->racemask
!= 0 )
3930 // skip wrong class skills
3931 if( skillLine
->classmask
&& (skillLine
->classmask
& classmask
) == 0)
3934 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
3935 if(!spellInfo
|| !SpellMgr::IsSpellValid(spellInfo
,m_session
->GetPlayer(),false))
3938 if( !target
->HasSpell(spellInfo
->Id
) )
3939 m_session
->GetPlayer()->learnSpell(skillLine
->spellId
,false);
3942 uint16 maxLevel
= target
->GetPureMaxSkillValue(skillInfo
->id
);
3943 target
->SetSkill(skillInfo
->id
, maxLevel
, maxLevel
);
3944 PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES
, name
.c_str());
3952 bool ChatHandler::HandleLookupPlayerIpCommand(const char* args
)
3958 std::string ip
= strtok ((char*)args
, " ");
3959 char* limit_str
= strtok (NULL
, " ");
3960 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3962 loginDatabase
.escape_string (ip
);
3964 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip
.c_str ());
3966 return LookupPlayerSearchCommand (result
,limit
);
3969 bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args
)
3974 std::string account
= strtok ((char*)args
, " ");
3975 char* limit_str
= strtok (NULL
, " ");
3976 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3978 if (!AccountMgr::normilizeString (account
))
3981 loginDatabase
.escape_string (account
);
3983 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account
.c_str ());
3985 return LookupPlayerSearchCommand (result
,limit
);
3988 bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args
)
3994 std::string email
= strtok ((char*)args
, " ");
3995 char* limit_str
= strtok (NULL
, " ");
3996 int32 limit
= limit_str
? atoi (limit_str
) : -1;
3998 loginDatabase
.escape_string (email
);
4000 QueryResult
* result
= loginDatabase
.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email
.c_str ());
4002 return LookupPlayerSearchCommand (result
,limit
);
4005 bool ChatHandler::LookupPlayerSearchCommand(QueryResult
* result
, int32 limit
)
4009 PSendSysMessage(LANG_NO_PLAYERS_FOUND
);
4010 SetSentErrorMessage(true);
4017 Field
* fields
= result
->Fetch();
4018 uint32 acc_id
= fields
[0].GetUInt32();
4019 std::string acc_name
= fields
[1].GetCppString();
4021 QueryResult
* chars
= CharacterDatabase
.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id
);
4024 PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT
,acc_name
.c_str(),acc_id
);
4031 Field
* charfields
= chars
->Fetch();
4032 guid
= charfields
[0].GetUInt64();
4033 name
= charfields
[1].GetCppString();
4035 PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER
,name
.c_str(),guid
);
4038 } while( chars
->NextRow() && ( limit
== -1 || i
< limit
) );
4042 } while(result
->NextRow());
4049 /// Triggering corpses expire check in world
4050 bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
4056 bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
4058 Player
*target
= getSelectedPlayer();
4062 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4063 SetSentErrorMessage(true);
4067 // check online security
4068 if (HasLowerSecurity(target
, 0))
4072 target
->DurabilityRepairAll(false, 0, false);
4074 PSendSysMessage(LANG_YOU_REPAIR_ITEMS
, GetNameLink(target
).c_str());
4075 if(needReportToTarget(target
))
4076 ChatHandler(target
).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED
, GetNameLink().c_str());
4080 bool ChatHandler::HandleWaterwalkCommand(const char* args
)
4085 Player
*player
= getSelectedPlayer();
4089 PSendSysMessage(LANG_NO_CHAR_SELECTED
);
4090 SetSentErrorMessage(true);
4094 // check online security
4095 if (HasLowerSecurity(player
, 0))
4098 if (strncmp(args
, "on", 3) == 0)
4099 player
->SetMovement(MOVE_WATER_WALK
); // ON
4100 else if (strncmp(args
, "off", 4) == 0)
4101 player
->SetMovement(MOVE_LAND_WALK
); // OFF
4104 SendSysMessage(LANG_USE_BOL
);
4108 PSendSysMessage(LANG_YOU_SET_WATERWALK
, args
, GetNameLink(player
).c_str());
4109 if(needReportToTarget(player
))
4110 ChatHandler(player
).PSendSysMessage(LANG_YOUR_WATERWALK_SET
, args
, GetNameLink().c_str());
4114 bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
4116 Player
*player
= m_session
->GetPlayer();
4117 Creature
*creature
= getSelectedCreature();
4121 PSendSysMessage(LANG_SELECT_CREATURE
);
4122 SetSentErrorMessage(true);
4126 // Follow player - Using pet's default dist and angle
4127 creature
->GetMotionMaster()->MoveFollow(player
, PET_FOLLOW_DIST
, PET_FOLLOW_ANGLE
);
4129 PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW
, creature
->GetName());
4133 bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
4135 Player
*player
= m_session
->GetPlayer();
4136 Creature
*creature
= getSelectedCreature();
4140 PSendSysMessage(LANG_SELECT_CREATURE
);
4141 SetSentErrorMessage(true);
4145 if (creature
->GetMotionMaster()->empty() ||
4146 creature
->GetMotionMaster()->GetCurrentMovementGeneratorType ()!=TARGETED_MOTION_TYPE
)
4148 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4149 SetSentErrorMessage(true);
4153 TargetedMovementGenerator
<Creature
> const* mgen
4154 = static_cast<TargetedMovementGenerator
<Creature
> const*>((creature
->GetMotionMaster()->top()));
4156 if(mgen
->GetTarget()!=player
)
4158 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU
);
4159 SetSentErrorMessage(true);
4164 creature
->GetMotionMaster()->MovementExpired(true);
4166 PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW
, creature
->GetName());
4170 bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
4172 Creature
*creatureTarget
= getSelectedCreature ();
4173 if (!creatureTarget
|| creatureTarget
->isPet ())
4175 PSendSysMessage (LANG_SELECT_CREATURE
);
4176 SetSentErrorMessage (true);
4180 Player
*player
= m_session
->GetPlayer ();
4182 if(player
->GetPetGUID ())
4184 SendSysMessage (LANG_YOU_ALREADY_HAVE_PET
);
4185 SetSentErrorMessage (true);
4189 CreatureInfo
const* cInfo
= creatureTarget
->GetCreatureInfo();
4191 if (!cInfo
->isTameable ())
4193 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4194 SetSentErrorMessage (true);
4198 // Everything looks OK, create new pet
4199 Pet
* pet
= player
->CreateTamedPetFrom (creatureTarget
);
4202 PSendSysMessage (LANG_CREATURE_NON_TAMEABLE
,cInfo
->Entry
);
4203 SetSentErrorMessage (true);
4207 // place pet before player
4209 player
->GetClosePoint (x
,y
,z
,creatureTarget
->GetObjectSize (),CONTACT_DISTANCE
);
4210 pet
->Relocate (x
,y
,z
,M_PI
-player
->GetOrientation ());
4212 // set pet to defensive mode by default (some classes can't control controlled pets in fact).
4213 pet
->GetCharmInfo()->SetReactState(REACT_DEFENSIVE
);
4215 // calculate proper level
4216 uint32 level
= (creatureTarget
->getLevel() < (player
->getLevel() - 5)) ? (player
->getLevel() - 5) : creatureTarget
->getLevel();
4218 // prepare visual effect for levelup
4219 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
- 1);
4222 pet
->GetMap()->Add((Creature
*)pet
);
4224 // visual effect for levelup
4225 pet
->SetUInt32Value(UNIT_FIELD_LEVEL
, level
);
4227 // caster have pet now
4228 player
->SetPet(pet
);
4230 pet
->SavePetToDB(PET_SAVE_AS_CURRENT
);
4231 player
->PetSpellInitialize();
4236 //change phasemask of creature or pet
4237 bool ChatHandler::HandleNpcSetPhaseCommand(const char* args
)
4242 uint32 phasemask
= (uint32
) atoi((char*)args
);
4243 if ( phasemask
== 0 )
4245 SendSysMessage(LANG_BAD_VALUE
);
4246 SetSentErrorMessage(true);
4250 Creature
* pCreature
= getSelectedCreature();
4253 SendSysMessage(LANG_SELECT_CREATURE
);
4254 SetSentErrorMessage(true);
4258 pCreature
->SetPhaseMask(phasemask
,true);
4260 if(!pCreature
->isPet())
4261 pCreature
->SaveToDB();
4266 //set pahsemask for selected object
4267 bool ChatHandler::HandleGOPhaseCommand(const char* args
)
4269 // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r
4270 char* cId
= extractKeyFromLink((char*)args
,"Hgameobject");
4274 uint32 lowguid
= atoi(cId
);
4278 GameObject
* obj
= NULL
;
4281 if (GameObjectData
const* go_data
= objmgr
.GetGOData(lowguid
))
4282 obj
= GetObjectGlobalyWithGuidOrNearWithDbGuid(lowguid
,go_data
->id
);
4286 PSendSysMessage(LANG_COMMAND_OBJNOTFOUND
, lowguid
);
4287 SetSentErrorMessage(true);
4291 char* phaseStr
= strtok (NULL
, " ");
4292 uint32 phasemask
= phaseStr
? atoi(phaseStr
) : 0;
4293 if ( phasemask
== 0 )
4295 SendSysMessage(LANG_BAD_VALUE
);
4296 SetSentErrorMessage(true);
4300 obj
->SetPhaseMask(phasemask
,true);
4305 bool ChatHandler::HandleNpcSetDeathStateCommand(const char* args
)
4310 Creature
* pCreature
= getSelectedCreature();
4311 if(!pCreature
|| pCreature
->isPet())
4313 SendSysMessage(LANG_SELECT_CREATURE
);
4314 SetSentErrorMessage(true);
4318 if (strncmp(args
, "on", 3) == 0)
4319 pCreature
->SetDeadByDefault(true);
4320 else if (strncmp(args
, "off", 4) == 0)
4321 pCreature
->SetDeadByDefault(false);
4324 SendSysMessage(LANG_USE_BOL
);
4325 SetSentErrorMessage(true);
4329 pCreature
->SaveToDB();
4330 pCreature
->Respawn();