/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2021 MaNGOS * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #include "Chat.h" #include "Language.h" #include "World.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand #include "TemporarySummon.h" #include "WaypointManager.h" #include "PathFinder.h" // for mmap commands #include "Totem.h" #ifdef _DEBUG_VMAPS #include "VMapFactory.h" #endif /********************************************************************** CommandTable : commandTable /***********************************************************************/ /* ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator Without this function 3rd party scripting library will get linking errors (unresolved external) when attempting to use the PointMovementGenerator */ bool ChatHandler::HandleComeToMeCommand(char* /*args*/) { Creature* caster = getSelectedCreature(); if (!caster) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } Player* pl = m_session->GetPlayer(); caster->GetMotionMaster()->MovePoint(0, pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ()); return true; } bool ChatHandler::HandleRespawnCommand(char* /*args*/) { Player* pl = m_session->GetPlayer(); // accept only explicitly selected target (not implicitly self targeting case) Unit* target = getSelectedUnit(); if (pl->GetSelectionGuid() && target) { if (target->GetTypeId() != TYPEID_UNIT) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } if (target->IsDead()) { ((Creature*)target)->Respawn(); } return true; } MaNGOS::RespawnDo u_do; MaNGOS::WorldObjectWorker worker(u_do); Cell::VisitGridObjects(pl, worker, pl->GetMap()->GetVisibilityDistance()); return true; } // Edit Creature Faction bool ChatHandler::HandleModifyFactionCommand(char* args) { Creature* chr = getSelectedCreature(); if (!chr) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } if (!*args) { if (chr) { uint32 factionid = chr->getFaction(); uint32 flag = chr->GetUInt32Value(UNIT_FIELD_FLAGS); uint32 npcflag = chr->GetUInt32Value(UNIT_NPC_FLAGS); uint32 dyflag = chr->GetUInt32Value(UNIT_DYNAMIC_FLAGS); PSendSysMessage(LANG_CURRENT_FACTION, chr->GetGUIDLow(), factionid, flag, npcflag, dyflag); } return true; } if (!chr) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } uint32 factionid; if (!ExtractUint32KeyFromLink(&args, "Hfaction", factionid)) { return false; } if (!sFactionTemplateStore.LookupEntry(factionid)) { PSendSysMessage(LANG_WRONG_FACTION, factionid); SetSentErrorMessage(true); return false; } uint32 flag; if (!ExtractOptUInt32(&args, flag, chr->GetUInt32Value(UNIT_FIELD_FLAGS))) { return false; } uint32 npcflag; if (!ExtractOptUInt32(&args, npcflag, chr->GetUInt32Value(UNIT_NPC_FLAGS))) { return false; } uint32 dyflag; if (!ExtractOptUInt32(&args, dyflag, chr->GetUInt32Value(UNIT_DYNAMIC_FLAGS))) { return false; } PSendSysMessage(LANG_YOU_CHANGE_FACTION, chr->GetGUIDLow(), factionid, flag, npcflag, dyflag); chr->setFaction(factionid); chr->SetUInt32Value(UNIT_FIELD_FLAGS, flag); chr->SetUInt32Value(UNIT_NPC_FLAGS, npcflag); chr->SetUInt32Value(UNIT_DYNAMIC_FLAGS, dyflag); return true; } //-----------------------Npc Commands----------------------- // add spawn of creature bool ChatHandler::HandleNpcAddCommand(char* args) { if (!*args) { return false; } uint32 id; if (!ExtractUint32KeyFromLink(&args, "Hcreature_entry", id)) { return false; } CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(id); if (!cinfo) { PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, id); SetSentErrorMessage(true); return false; } Player* chr = m_session->GetPlayer(); CreatureCreatePos pos(chr, chr->GetOrientation()); Map* map = chr->GetMap(); Creature* pCreature = new Creature; // used guids from specially reserved range (can be 0 if no free values) uint32 lowguid = sObjectMgr.GenerateStaticCreatureLowGuid(); if (!lowguid) { SendSysMessage(LANG_NO_FREE_STATIC_GUID_FOR_SPAWN); SetSentErrorMessage(true); return false; } if (!pCreature->Create(lowguid, pos, cinfo)) { delete pCreature; return false; } pCreature->SaveToDB(map->GetId()); uint32 db_guid = pCreature->GetGUIDLow(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); pCreature->LoadFromDB(db_guid, map); return true; } // add item in vendorlist bool ChatHandler::HandleNpcAddVendorItemCommand(char* args) { uint32 itemId; if (!ExtractUint32KeyFromLink(&args, "Hitem", itemId)) { SendSysMessage(LANG_COMMAND_NEEDITEMSEND); SetSentErrorMessage(true); return false; } uint32 maxcount; if (!ExtractOptUInt32(&args, maxcount, 0)) { return false; } uint32 incrtime; if (!ExtractOptUInt32(&args, incrtime, 0)) { return false; } Creature* vendor = getSelectedCreature(); uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; if (!sObjectMgr.IsVendorItemValid(false, "npc_vendor", vendor_entry, itemId, maxcount, incrtime, 0, m_session->GetPlayer())) { SetSentErrorMessage(true); return false; } sObjectMgr.AddVendorItem(vendor_entry, itemId, maxcount, incrtime); ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); PSendSysMessage(LANG_ITEM_ADDED_TO_LIST, itemId, pProto->Name1, maxcount, incrtime); return true; } // del item from vendor list bool ChatHandler::HandleNpcDelVendorItemCommand(char* args) { if (!*args) { return false; } Creature* vendor = getSelectedCreature(); if (!vendor || !vendor->IsVendor()) { SendSysMessage(LANG_COMMAND_VENDORSELECTION); SetSentErrorMessage(true); return false; } uint32 itemId; if (!ExtractUint32KeyFromLink(&args, "Hitem", itemId)) { SendSysMessage(LANG_COMMAND_NEEDITEMSEND); SetSentErrorMessage(true); return false; } if (!sObjectMgr.RemoveVendorItem(vendor->GetEntry(), itemId)) { PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId); SetSentErrorMessage(true); return false; } ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST, itemId, pProto->Name1); return true; } // show info about AI bool ChatHandler::HandleNpcAIInfoCommand(char* /*args*/) { Creature* pTarget = getSelectedCreature(); if (!pTarget) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } PSendSysMessage(LANG_NPC_AI_HEADER, pTarget->GetEntry()); std::string strScript = pTarget->GetScriptName(); std::string strAI = pTarget->GetAIName(); char const* cstrAIClass = pTarget->AI() ? typeid(*pTarget->AI()).name() : " - "; PSendSysMessage(LANG_NPC_AI_NAMES, strAI.empty() ? " - " : strAI.c_str(), cstrAIClass ? cstrAIClass : " - ", strScript.empty() ? " - " : strScript.c_str()); PSendSysMessage("Motion Type: %u", pTarget->GetMotionMaster()->GetCurrentMovementGeneratorType()); PSendSysMessage("Casting Spell: %s", pTarget->IsNonMeleeSpellCasted(true) ? "yes" : "no"); if (pTarget->AI()) { pTarget->AI()->GetAIInformation(*this); } return true; } // change level of creature or pet bool ChatHandler::HandleNpcChangeLevelCommand(char* args) { if (!*args) { return false; } uint8 lvl = (uint8)atoi(args); if (lvl < 1 || lvl > sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL) + 3) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); return false; } Creature* pCreature = getSelectedCreature(); if (!pCreature) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } if (pCreature->IsPet()) { ((Pet*)pCreature)->GivePetLevel(lvl); } else { pCreature->SetMaxHealth(100 + 30 * lvl); pCreature->SetHealth(100 + 30 * lvl); pCreature->SetLevel(lvl); if (pCreature->HasStaticDBSpawnData()) { pCreature->SaveToDB(); } } return true; } // set npcflag of creature bool ChatHandler::HandleNpcFlagCommand(char* args) { if (!*args) { return false; } uint32 npcFlags = (uint32)atoi(args); Creature* pCreature = getSelectedCreature(); if (!pCreature) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); WorldDatabase.PExecuteLog("UPDATE `creature_template` SET `NpcFlags` = '%u' WHERE `entry` = '%u'", npcFlags, pCreature->GetEntry()); SendSysMessage(LANG_VALUE_SAVED_REJOIN); return true; } bool ChatHandler::HandleNpcDeleteCommand(char* args) { Creature* unit = NULL; if (*args) { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r uint32 lowguid; if (!ExtractUint32KeyFromLink(&args, "Hcreature", lowguid)) { return false; } if (!lowguid) { return false; } if (CreatureData const* data = sObjectMgr.GetCreatureData(lowguid)) { unit = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid)); } } else { unit = getSelectedCreature(); } if (!unit) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } switch (unit->GetSubtype()) { case CREATURE_SUBTYPE_GENERIC: { unit->CombatStop(); if (CreatureData const* data = sObjectMgr.GetCreatureData(unit->GetGUIDLow())) { Creature::AddToRemoveListInMaps(unit->GetGUIDLow(), data); Creature::DeleteFromDB(unit->GetGUIDLow(), data); } else { unit->AddObjectToRemoveList(); } break; } case CREATURE_SUBTYPE_PET: ((Pet*)unit)->Unsummon(PET_SAVE_AS_CURRENT); break; case CREATURE_SUBTYPE_TOTEM: ((Totem*)unit)->UnSummon(); break; case CREATURE_SUBTYPE_TEMPORARY_SUMMON: ((TemporarySummon*)unit)->UnSummon(); break; default: return false; } SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); return true; } // move selected creature bool ChatHandler::HandleNpcMoveCommand(char* args) { uint32 lowguid = 0; Player* player = m_session->GetPlayer(); Creature* pCreature = getSelectedCreature(); if (!pCreature) { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r if (!ExtractUint32KeyFromLink(&args, "Hcreature", lowguid)) { return false; } CreatureData const* data = sObjectMgr.GetCreatureData(lowguid); if (!data) { PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); SetSentErrorMessage(true); return false; } if (player->GetMapId() != data->mapid) { PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); SetSentErrorMessage(true); return false; } pCreature = player->GetMap()->GetCreature(data->GetObjectGuid(lowguid)); } else { lowguid = pCreature->GetGUIDLow(); } float x = player->GetPositionX(); float y = player->GetPositionY(); float z = player->GetPositionZ(); float o = player->GetOrientation(); if (pCreature) { if (CreatureData const* data = sObjectMgr.GetCreatureData(pCreature->GetGUIDLow())) { const_cast(data)->posX = x; const_cast(data)->posY = y; const_cast(data)->posZ = z; const_cast(data)->orientation = o; } pCreature->GetMap()->CreatureRelocation(pCreature, x, y, z, o); pCreature->GetMotionMaster()->Initialize(); if (pCreature->IsAlive()) // dead creature will reset movement generator at respawn { pCreature->SetDeathState(JUST_DIED); pCreature->Respawn(); } } WorldDatabase.PExecuteLog("UPDATE `creature` SET `position_x` = '%f', `position_y` = '%f', `position_z` = '%f', `orientation` = '%f' WHERE `guid` = '%u'", x, y, z, o, lowguid); PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; } /**HandleNpcSetMoveTypeCommand * Set the movement type for an NPC.
*
* Valid movement types are: *
    *
  • stay - NPC wont move
  • *
  • random - NPC will move randomly according to the spawndist
  • *
  • way - NPC will move with given waypoints set
  • *
* additional parameter: NODEL - so no waypoints are deleted, if you * change the movement type */ bool ChatHandler::HandleNpcSetMoveTypeCommand(char* args) { // 3 arguments: // GUID (optional - you can also select the creature) // stay|random|way (determines the kind of movement) // NODEL (optional - tells the system NOT to delete any waypoints) // this is very handy if you want to do waypoints, that are // later switched on/off according to special events (like escort // quests, etc) uint32 lowguid; Creature* pCreature; if (!ExtractUInt32(&args, lowguid)) // case .setmovetype $move_type (with selected creature) { pCreature = getSelectedCreature(); if (!pCreature || !pCreature->HasStaticDBSpawnData()) { return false; } lowguid = pCreature->GetGUIDLow(); } else // case .setmovetype #creature_guid $move_type (with guid) { CreatureData const* data = sObjectMgr.GetCreatureData(lowguid); if (!data) { PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); SetSentErrorMessage(true); return false; } Player* player = m_session->GetPlayer(); if (player->GetMapId() != data->mapid) { PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); SetSentErrorMessage(true); return false; } pCreature = player->GetMap()->GetCreature(data->GetObjectGuid(lowguid)); } MovementGeneratorType move_type; char* type_str = ExtractLiteralArg(&args); if (!type_str) { return false; } if (strncmp(type_str, "stay", strlen(type_str)) == 0) { move_type = IDLE_MOTION_TYPE; } else if (strncmp(type_str, "random", strlen(type_str)) == 0) { move_type = RANDOM_MOTION_TYPE; } else if (strncmp(type_str, "way", strlen(type_str)) == 0) { move_type = WAYPOINT_MOTION_TYPE; } else { return false; } bool doNotDelete = ExtractLiteralArg(&args, "NODEL") != NULL; if (!doNotDelete && *args) // need fail if false in result wrong literal { return false; } // now lowguid is low guid really existing creature // and pCreature point (maybe) to this creature or NULL // update movement type if (!doNotDelete) { sWaypointMgr.DeletePath(lowguid); } if (pCreature) { pCreature->SetDefaultMovementType(move_type); pCreature->GetMotionMaster()->Initialize(); if (pCreature->IsAlive()) // dead creature will reset movement generator at respawn { pCreature->SetDeathState(JUST_DIED); pCreature->Respawn(); } pCreature->SaveToDB(); } if (doNotDelete) { PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL, type_str); } else { PSendSysMessage(LANG_MOVE_TYPE_SET, type_str); } return true; } // set model of creature bool ChatHandler::HandleNpcSetModelCommand(char* args) { if (!*args) { return false; } uint32 displayId = (uint32)atoi(args); Creature* pCreature = getSelectedCreature(); if (!pCreature || pCreature->IsPet()) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } if (!sCreatureDisplayInfoStore.LookupEntry(displayId)) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); return false; } pCreature->SetDisplayId(displayId); pCreature->SetNativeDisplayId(displayId); if (pCreature->HasStaticDBSpawnData()) { pCreature->SaveToDB(); } return true; } // set faction of creature bool ChatHandler::HandleNpcFactionIdCommand(char* args) { if (!*args) { return false; } uint32 factionId = (uint32)atoi(args); if (!sFactionTemplateStore.LookupEntry(factionId)) { PSendSysMessage(LANG_WRONG_FACTION, factionId); SetSentErrorMessage(true); return false; } Creature* pCreature = getSelectedCreature(); if (!pCreature) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } pCreature->setFaction(factionId); // faction is set in creature_template - not inside creature // update in memory if (CreatureInfo const* cinfo = pCreature->GetCreatureInfo()) { const_cast(cinfo)->FactionAlliance = factionId; const_cast(cinfo)->FactionHorde = factionId; } // and DB WorldDatabase.PExecuteLog("UPDATE `creature_template` SET `FactionAlliance` = '%u', `FactionHorde` = '%u' WHERE `entry` = '%u'", factionId, factionId, pCreature->GetEntry()); return true; } // set spawn dist of creature bool ChatHandler::HandleNpcSpawnDistCommand(char* args) { if (!*args) { return false; } float option = (float)atof(args); if (option < 0.0f) { SendSysMessage(LANG_BAD_VALUE); return false; } MovementGeneratorType mtype = IDLE_MOTION_TYPE; if (option > 0.0f) { mtype = RANDOM_MOTION_TYPE; } Creature* pCreature = getSelectedCreature(); if (!pCreature) { return false; } pCreature->SetRespawnRadius((float)option); pCreature->SetDefaultMovementType(mtype); pCreature->GetMotionMaster()->Initialize(); if (pCreature->IsAlive()) // dead creature will reset movement generator at respawn { pCreature->SetDeathState(JUST_DIED); pCreature->Respawn(); } WorldDatabase.PExecuteLog("UPDATE `creature` SET `spawndist`=%f, `MovementType`=%i WHERE `guid`=%u", option, mtype, pCreature->GetGUIDLow()); PSendSysMessage(LANG_COMMAND_SPAWNDIST, option); return true; } // spawn time handling bool ChatHandler::HandleNpcSpawnTimeCommand(char* args) { uint32 stime; if (!ExtractUInt32(&args, stime)) { return false; } Creature* pCreature = getSelectedCreature(); if (!pCreature) { PSendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } uint32 u_guidlow = pCreature->GetGUIDLow(); WorldDatabase.PExecuteLog("UPDATE `creature` SET `spawntimesecs`=%i WHERE `guid`=%u", stime, u_guidlow); pCreature->SetRespawnDelay(stime); PSendSysMessage(LANG_COMMAND_SPAWNTIME, stime); return true; } // npc follow handling bool ChatHandler::HandleNpcFollowCommand(char* /*args*/) { Player* player = m_session->GetPlayer(); Creature* creature = getSelectedCreature(); if (!creature) { PSendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } // Follow player - Using pet's default dist and angle creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); return true; } // npc unfollow handling bool ChatHandler::HandleNpcUnFollowCommand(char* /*args*/) { Player* player = m_session->GetPlayer(); Creature* creature = getSelectedCreature(); if (!creature) { PSendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } MotionMaster* creatureMotion = creature->GetMotionMaster(); if (creatureMotion->empty() || creatureMotion->GetCurrentMovementGeneratorType() != FOLLOW_MOTION_TYPE) { PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); SetSentErrorMessage(true); return false; } FollowMovementGenerator const* mgen = static_cast const*>(creatureMotion->top()); if (mgen->GetTarget() != player) { PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); SetSentErrorMessage(true); return false; } // reset movement creatureMotion->MovementExpired(true); PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName()); return true; } // npc tame handling bool ChatHandler::HandleNpcTameCommand(char* /*args*/) { Creature* creatureTarget = getSelectedCreature(); if (!creatureTarget || creatureTarget->IsPet()) { PSendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } Player* player = m_session->GetPlayer(); if (player->GetPetGuid()) { SendSysMessage(LANG_YOU_ALREADY_HAVE_PET); SetSentErrorMessage(true); return false; } player->CastSpell(creatureTarget, 13481, true); // Tame Beast, triggered effect return true; } // npc deathstate handling bool ChatHandler::HandleNpcSetDeathStateCommand(char* args) { bool value; if (!ExtractOnOff(&args, value)) { SendSysMessage(LANG_USE_BOL); SetSentErrorMessage(true); return false; } Creature* pCreature = getSelectedCreature(); if (!pCreature || !pCreature->HasStaticDBSpawnData()) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } if (value) { pCreature->SetDeadByDefault(true); } else { pCreature->SetDeadByDefault(false); } pCreature->SaveToDB(); pCreature->Respawn(); return true; } // TODO: NpcCommands that need to be fixed : bool ChatHandler::HandleNpcNameCommand(char* /*args*/) { /* Temp. disabled if (!*args) { return false; } if (strlen((char*)args)>75) { PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75); return true; } for (uint8 i = 0; i < strlen(args); ++i) { if (!isalpha(args[i]) && args[i]!=' ') { SendSysMessage(LANG_CHARS_ONLY); return false; } } ObjectGuid guid = m_session->GetPlayer()->GetSelectionGuid(); if (guid.IsEmpty()) { SendSysMessage(LANG_NO_SELECTION); return true; } Creature* pCreature = sObjectAccessor.GetCreature(*m_session->GetPlayer(), guid); if (!pCreature) { SendSysMessage(LANG_SELECT_CREATURE); return true; } pCreature->SetName(args); uint32 idname = sObjectMgr.AddCreatureTemplate(pCreature->GetName()); pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); pCreature->SaveToDB(); */ return true; } bool ChatHandler::HandleNpcSubNameCommand(char* /*args*/) { /* Temp. disabled if (!*args) { args = ""; } if (strlen((char*)args)>75) { PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75); return true; } for (uint8 i = 0; i < strlen(args); ++i) { if (!isalpha(args[i]) && args[i]!=' ') { SendSysMessage(LANG_CHARS_ONLY); return false; } } ObjectGuid guid = m_session->GetPlayer()->GetSelectionGuid(); if (guid.IsEmpty()) { SendSysMessage(LANG_NO_SELECTION); return true; } Creature* pCreature = sObjectAccessor.GetCreature(*m_session->GetPlayer(), guid); if (!pCreature) { SendSysMessage(LANG_SELECT_CREATURE); return true; } uint32 idname = sObjectMgr.AddCreatureSubName(pCreature->GetName(),args,pCreature->GetUInt32Value(UNIT_FIELD_DISPLAYID)); pCreature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname); pCreature->SaveToDB(); */ return true; } //-----------------------Npc Commands----------------------- bool ChatHandler::HandleNpcAllowMovementCommand(char* /*args*/) { if (sWorld.getAllowMovement()) { sWorld.SetAllowMovement(false); SendSysMessage(LANG_CREATURE_MOVE_DISABLED); } else { sWorld.SetAllowMovement(true); SendSysMessage(LANG_CREATURE_MOVE_ENABLED); } return true; } bool ChatHandler::HandleNpcChangeEntryCommand(char* args) { if (!*args) { return false; } uint32 newEntryNum = atoi(args); if (!newEntryNum) { return false; } Unit* unit = getSelectedUnit(); if (!unit || unit->GetTypeId() != TYPEID_UNIT) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } Creature* creature = (Creature*)unit; if (creature->UpdateEntry(newEntryNum)) { SendSysMessage(LANG_DONE); } else { SendSysMessage(LANG_ERROR); } return true; } bool ChatHandler::HandleNpcInfoCommand(char* /*args*/) { Creature* target = getSelectedCreature(); if (!target) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } uint32 faction = target->getFaction(); uint32 npcflags = target->GetUInt32Value(UNIT_NPC_FLAGS); uint32 displayid = target->GetDisplayId(); uint32 nativeid = target->GetNativeDisplayId(); uint32 Entry = target->GetEntry(); CreatureInfo const* cInfo = target->GetCreatureInfo(); time_t curRespawnDelay = target->GetRespawnTimeEx() - time(NULL); if (curRespawnDelay < 0) { curRespawnDelay = 0; } std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, TimeFormat::ShortText); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), TimeFormat::ShortText); PSendSysMessage(LANG_NPCINFO_CHAR, target->GetGuidStr().c_str(), faction, npcflags, Entry, displayid, nativeid); PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str()); PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->LootId, cInfo->PickpocketLootId, cInfo->SkinningLootId); PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); if ((npcflags & UNIT_NPC_FLAG_VENDOR)) { SendSysMessage(LANG_NPCINFO_VENDOR); } if ((npcflags & UNIT_NPC_FLAG_TRAINER)) { SendSysMessage(LANG_NPCINFO_TRAINER); } ShowNpcOrGoSpawnInformation(target->GetGUIDLow()); return true; } // play npc emote bool ChatHandler::HandleNpcPlayEmoteCommand(char* args) { uint32 emote = atoi(args); Creature* target = getSelectedCreature(); if (!target) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } target->HandleEmote(emote); return true; } // TODO: NpcCommands that needs to be fixed : bool ChatHandler::HandleNpcAddWeaponCommand(char* /*args*/) { /*if (!*args) return false; ObjectGuid guid = m_session->GetPlayer()->GetSelectionGuid(); if (guid.IsEmpty()) { SendSysMessage(LANG_NO_SELECTION); return true; } Creature *pCreature = sObjectAccessor.GetCreature(*m_session->GetPlayer(), guid); if(!pCreature) { SendSysMessage(LANG_SELECT_CREATURE); return true; } char* pSlotID = strtok((char*)args, " "); if (!pSlotID) { return false; } char* pItemID = strtok(NULL, " "); if (!pItemID) { return false; } uint32 ItemID = atoi(pItemID); uint32 SlotID = atoi(pSlotID); ItemPrototype* tmpItem = ObjectMgr::GetItemPrototype(ItemID); bool added = false; if(tmpItem) { switch(SlotID) { case 1: pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID); added = true; break; case 2: pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID); added = true; break; case 3: pCreature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID); added = true; break; default: PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); added = false; break; } if(added) { PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); } } else { PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); return true; } */ return true; } //----------------------------------------------------------