/* * Copyright (C) 2008-2011 TrinityCore * * 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, see . */ /* ScriptData Name: npc_commandscript %Complete: 100 Comment: All npc related commands Category: commandscripts EndScriptData */ #include "ScriptMgr.h" #include "ObjectMgr.h" #include "Chat.h" #include "Transport.h" #include "CreatureGroups.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand class npc_commandscript : public CommandScript { public: npc_commandscript() : CommandScript("npc_commandscript") { } ChatCommand* GetCommands() const { static ChatCommand npcAddCommandTable[] = { { "formation", SEC_MODERATOR, false, &HandleNpcAddFormationCommand, "", NULL }, { "item", SEC_GAMEMASTER, false, &HandleNpcAddVendorItemCommand, "", NULL }, { "move", SEC_GAMEMASTER, false, &HandleNpcAddMoveCommand, "", NULL }, { "temp", SEC_GAMEMASTER, false, &HandleNpcAddTempSpawnCommand, "", NULL }, //{ TODO: fix or remove this command { "weapon", SEC_ADMINISTRATOR, false, &HandleNpcAddWeaponCommand, "", NULL }, //} { "", SEC_GAMEMASTER, false, &HandleNpcAddCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand npcDeleteCommandTable[] = { { "item", SEC_GAMEMASTER, false, &HandleNpcDeleteVendorItemCommand, "", NULL }, { "", SEC_GAMEMASTER, false, &HandleNpcDeleteCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand npcFollowCommandTable[] = { { "stop", SEC_GAMEMASTER, false, &HandleNpcUnFollowCommand, "", NULL }, { "", SEC_GAMEMASTER, false, &HandleNpcFollowCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand npcSetCommandTable[] = { { "allowmove", SEC_ADMINISTRATOR, false, &HandleNpcSetAllowMovementCommand, "", NULL }, { "deathstate", SEC_GAMEMASTER, false, &HandleNpcSetDeathStateCommand, "", NULL }, { "entry", SEC_ADMINISTRATOR, false, &HandleNpcSetEntryCommand, "", NULL }, { "factionid", SEC_GAMEMASTER, false, &HandleNpcSetFactionIdCommand, "", NULL }, { "flag", SEC_GAMEMASTER, false, &HandleNpcSetFlagCommand, "", NULL }, { "level", SEC_GAMEMASTER, false, &HandleNpcSetLevelCommand, "", NULL }, { "link", SEC_GAMEMASTER, false, &HandleNpcSetLinkCommand, "", NULL }, { "model", SEC_GAMEMASTER, false, &HandleNpcSetModelCommand, "", NULL }, { "movetype", SEC_GAMEMASTER, false, &HandleNpcSetMoveTypeCommand, "", NULL }, { "phase", SEC_GAMEMASTER, false, &HandleNpcSetPhaseCommand, "", NULL }, { "spawndist", SEC_GAMEMASTER, false, &HandleNpcSetSpawnDistCommand, "", NULL }, { "spawntime", SEC_GAMEMASTER, false, &HandleNpcSetSpawnTimeCommand, "", NULL }, //{ TODO: fix or remove these commands { "name", SEC_GAMEMASTER, false, &HandleNpcSetNameCommand, "", NULL }, { "subname", SEC_GAMEMASTER, false, &HandleNpcSetSubNameCommand, "", NULL }, //} { NULL, 0, false, NULL, "", NULL } }; static ChatCommand npcCommandTable[] = { { "info", SEC_ADMINISTRATOR, false, &HandleNpcInfoCommand, "", NULL }, { "move", SEC_GAMEMASTER, false, &HandleNpcMoveCommand, "", NULL }, { "playemote", SEC_ADMINISTRATOR, false, &HandleNpcPlayEmoteCommand, "", NULL }, { "say", SEC_MODERATOR, false, &HandleNpcSayCommand, "", NULL }, { "textemote", SEC_MODERATOR, false, &HandleNpcTextEmoteCommand, "", NULL }, { "whisper", SEC_MODERATOR, false, &HandleNpcWhisperCommand, "", NULL }, { "yell", SEC_MODERATOR, false, &HandleNpcYellCommand, "", NULL }, { "tame", SEC_GAMEMASTER, false, &HandleNpcTameCommand, "", NULL }, { "add", SEC_GAMEMASTER, false, NULL, "", npcAddCommandTable }, { "delete", SEC_GAMEMASTER, false, NULL, "", npcDeleteCommandTable }, { "follow", SEC_GAMEMASTER, false, NULL, "", npcFollowCommandTable }, { "set", SEC_GAMEMASTER, false, NULL, "", npcSetCommandTable }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable }, { NULL, 0, false, NULL, "", NULL } }; return commandTable; } //add spawn of creature static bool HandleNpcAddCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* charID = handler->extractKeyFromLink((char*)args,"Hcreature_entry"); if (!charID) return false; char* team = strtok(NULL, " "); int32 teamval = 0; if (team) { teamval = atoi(team); } if (teamval < 0) { teamval = 0; } uint32 id = atoi(charID); Player *chr = handler->GetSession()->GetPlayer(); float x = chr->GetPositionX(); float y = chr->GetPositionY(); float z = chr->GetPositionZ(); float o = chr->GetOrientation(); Map *map = chr->GetMap(); if (chr->GetTransport()) { uint32 tguid = chr->GetTransport()->AddNPCPassenger(0, id, chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); if (tguid > 0) WorldDatabase.PQuery("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); return true; } Creature* pCreature = new Creature; if (!pCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o)) { delete pCreature; return false; } pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); uint32 db_guid = pCreature->GetDBTableGUIDLow(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); pCreature->LoadFromDB(db_guid, map); map->Add(pCreature); sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); return true; } //add item in vendorlist static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* pitem = handler->extractKeyFromLink((char*)args,"Hitem"); if (!pitem) { handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); handler->SetSentErrorMessage(true); return false; } uint32 itemId = atol(pitem); char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 uint32 maxcount = 0; if (fmaxcount) maxcount = atol(fmaxcount); char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0 uint32 incrtime = 0; if (fincrtime) incrtime = atol(fincrtime); char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; Creature* vendor = handler->getSelectedCreature(); if (!vendor) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } uint32 vendor_entry = vendor ? vendor->GetEntry() : 0; if (!sObjectMgr->IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,handler->GetSession()->GetPlayer())) { handler->SetSentErrorMessage(true); return false; } sObjectMgr->AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost); ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); handler->PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost); return true; } //add move for creature static bool HandleNpcAddMoveCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* guid_str = strtok((char*)args, " "); char* wait_str = strtok((char*)NULL, " "); uint32 lowguid = atoi((char*)guid_str); Creature* pCreature = NULL; /* FIXME: impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // attempt check creature existence by DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } } else { // obtain real GUID for DB operations lowguid = pCreature->GetDBTableGUIDLow(); } int wait = wait_str ? atoi(wait_str) : 0; if (wait < 0) wait = 0; //Player* player = handler->GetSession()->GetPlayer(); //WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0); // update movement type WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid); if (pCreature && pCreature->GetWaypointPath()) { pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE); pCreature->GetMotionMaster()->Initialize(); if (pCreature->isAlive()) // dead creature will reset movement generator at respawn { pCreature->setDeathState(JUST_DIED); pCreature->Respawn(true); } pCreature->SaveToDB(); } handler->SendSysMessage(LANG_WAYPOINT_ADDED); return true; } static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler, const char* /*args*/) { if (sWorld->getAllowMovement()) { sWorld->SetAllowMovement(false); handler->SendSysMessage(LANG_CREATURE_MOVE_DISABLED); } else { sWorld->SetAllowMovement(true); handler->SendSysMessage(LANG_CREATURE_MOVE_ENABLED); } return true; } static bool HandleNpcSetEntryCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 newEntryNum = atoi(args); if (!newEntryNum) return false; Unit* unit = handler->getSelectedUnit(); if (!unit || unit->GetTypeId() != TYPEID_UNIT) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } Creature* creature = unit->ToCreature(); if (creature->UpdateEntry(newEntryNum)) handler->SendSysMessage(LANG_DONE); else handler->SendSysMessage(LANG_ERROR); return true; } //change level of creature or pet static bool HandleNpcSetLevelCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint8 lvl = (uint8) atoi((char*)args); if (lvl < 1 || lvl > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + 3) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (pCreature->isPet()) { if (((Pet*)pCreature)->getPetType() == HUNTER_PET) { pCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, sObjectMgr->GetXPForLevel(lvl)/4); pCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); } ((Pet*)pCreature)->GivePetLevel(lvl); } else { pCreature->SetMaxHealth(100 + 30*lvl); pCreature->SetHealth(100 + 30*lvl); pCreature->SetLevel(lvl); pCreature->SaveToDB(); } return true; } static bool HandleNpcDeleteCommand(ChatHandler* handler, const char* args) { Creature* unit = NULL; if (*args) { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r char* cId = handler->extractKeyFromLink((char*)args,"Hcreature"); if (!cId) return false; uint32 lowguid = atoi(cId); if (!lowguid) return false; if (CreatureData const* cr_data = sObjectMgr->GetCreatureData(lowguid)) unit = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT)); } else unit = handler->getSelectedCreature(); if (!unit || unit->isPet() || unit->isTotem()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } // Delete the creature unit->CombatStop(); unit->DeleteFromDB(); unit->AddObjectToRemoveList(); handler->SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); return true; } //del item from vendor list static bool HandleNpcDeleteVendorItemCommand(ChatHandler* handler, const char* args) { if (!*args) return false; Creature* vendor = handler->getSelectedCreature(); if (!vendor || !vendor->isVendor()) { handler->SendSysMessage(LANG_COMMAND_VENDORSELECTION); handler->SetSentErrorMessage(true); return false; } char* pitem = handler->extractKeyFromLink((char*)args,"Hitem"); if (!pitem) { handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND); handler->SetSentErrorMessage(true); return false; } uint32 itemId = atol(pitem); if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(),itemId)) { handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); handler->SetSentErrorMessage(true); return false; } ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); handler->PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1); return true; } //set faction of creature static bool HandleNpcSetFactionIdCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 factionId = (uint32) atoi((char*)args); if (!sFactionTemplateStore.LookupEntry(factionId)) { handler->PSendSysMessage(LANG_WRONG_FACTION, factionId); handler->SetSentErrorMessage(true); return false; } Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->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)->faction_A = factionId; const_cast(cinfo)->faction_H = factionId; } // and DB WorldDatabase.PExecute("UPDATE creature_template SET faction_A = '%u', faction_H = '%u' WHERE entry = '%u'", factionId, factionId, pCreature->GetEntry()); return true; } //set npcflag of creature static bool HandleNpcSetFlagCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 npcFlags = (uint32) atoi((char*)args); Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->SetUInt32Value(UNIT_NPC_FLAGS, npcFlags); WorldDatabase.PExecute("UPDATE creature_template SET npcflag = '%u' WHERE entry = '%u'", npcFlags, pCreature->GetEntry()); handler->SendSysMessage(LANG_VALUE_SAVED_REJOIN); return true; } //npc follow handling static bool HandleNpcFollowCommand(ChatHandler* handler, const char* /*args*/) { Player *player = handler->GetSession()->GetPlayer(); Creature *creature = handler->getSelectedCreature(); if (!creature) { handler->PSendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } // Follow player - Using pet's default dist and angle creature->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, creature->GetFollowAngle()); handler->PSendSysMessage(LANG_CREATURE_FOLLOW_YOU_NOW, creature->GetName()); return true; } static bool HandleNpcInfoCommand(ChatHandler* handler, const char* /*args*/) { Creature* target = handler->getSelectedCreature(); if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->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(); int64 curRespawnDelay = target->GetRespawnTimeEx()-time(NULL); if (curRespawnDelay < 0) curRespawnDelay = 0; std::string curRespawnDelayStr = secsToTimeString(uint64(curRespawnDelay),true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(),true); handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), faction, npcflags, Entry, displayid, nativeid); handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); handler->PSendSysMessage(LANG_NPCINFO_HEALTH,target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); handler->PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction()); handler->PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(),curRespawnDelayStr.c_str()); handler->PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId); handler->PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId()); handler->PSendSysMessage(LANG_NPCINFO_PHASEMASK, target->GetPhaseMask()); handler->PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor()); handler->PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); if ((npcflags & UNIT_NPC_FLAG_VENDOR)) { handler->SendSysMessage(LANG_NPCINFO_VENDOR); } if ((npcflags & UNIT_NPC_FLAG_TRAINER)) { handler->SendSysMessage(LANG_NPCINFO_TRAINER); } return true; } //move selected creature static bool HandleNpcMoveCommand(ChatHandler* handler, const char* args) { uint32 lowguid = 0; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r char* cId = handler->extractKeyFromLink((char*)args,"Hcreature"); if (!cId) return false; lowguid = atoi(cId); /* FIXME: impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // Attempting creature load from DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } uint32 map_id = data->mapid; if (handler->GetSession()->GetPlayer()->GetMapId() != map_id) { handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); handler->SetSentErrorMessage(true); return false; } } else { lowguid = pCreature->GetDBTableGUIDLow(); } } else { lowguid = pCreature->GetDBTableGUIDLow(); } float x = handler->GetSession()->GetPlayer()->GetPositionX(); float y = handler->GetSession()->GetPlayer()->GetPositionY(); float z = handler->GetSession()->GetPlayer()->GetPositionZ(); float o = handler->GetSession()->GetPlayer()->GetOrientation(); if (pCreature) { if (CreatureData const* data = sObjectMgr->GetCreatureData(pCreature->GetDBTableGUIDLow())) { 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.PExecute("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; } //play npc emote static bool HandleNpcPlayEmoteCommand(ChatHandler* handler, const char* args) { uint32 emote = atoi((char*)args); Creature* target = handler->getSelectedCreature(); if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (target->GetTransport()) if (target->GetGUIDTransport()) WorldDatabase.PQuery("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport()); target->SetUInt32Value(UNIT_NPC_EMOTESTATE,emote); return true; } //set model of creature static bool HandleNpcSetModelCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 displayId = (uint32) atoi((char*)args); Creature *pCreature = handler->getSelectedCreature(); if (!pCreature || pCreature->isPet()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->SetDisplayId(displayId); pCreature->SetNativeDisplayId(displayId); pCreature->SaveToDB(); 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 */ static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // 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) char* guid_str = strtok((char*)args, " "); char* type_str = strtok((char*)NULL, " "); char* dontdel_str = strtok((char*)NULL, " "); bool doNotDelete = false; if (!guid_str) return false; uint32 lowguid = 0; Creature* pCreature = NULL; if (dontdel_str) { //sLog->outError("DEBUG: All 3 params are set"); // All 3 params are set // GUID // type // doNotDEL if (stricmp(dontdel_str, "NODEL") == 0) { //sLog->outError("DEBUG: doNotDelete = true;"); doNotDelete = true; } } else { // Only 2 params - but maybe NODEL is set if (type_str) { sLog->outError("DEBUG: Only 2 params "); if (stricmp(type_str, "NODEL") == 0) { //sLog->outError("DEBUG: type_str, NODEL "); doNotDelete = true; type_str = NULL; } } } if (!type_str) // case .setmovetype $move_type (with selected creature) { type_str = guid_str; pCreature = handler->getSelectedCreature(); if (!pCreature || pCreature->isPet()) return false; lowguid = pCreature->GetDBTableGUIDLow(); } else // case .setmovetype #creature_guid $move_type (with selected creature) { lowguid = atoi((char*)guid_str); /* impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // attempt check creature existence by DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } } else { lowguid = pCreature->GetDBTableGUIDLow(); } } // now lowguid is low guid really existed creature // and pCreature point (maybe) to this creature or NULL MovementGeneratorType move_type; std::string type = type_str; if (type == "stay") move_type = IDLE_MOTION_TYPE; else if (type == "random") move_type = RANDOM_MOTION_TYPE; else if (type == "way") move_type = WAYPOINT_MOTION_TYPE; else return false; // update movement type //if (doNotDelete == false) // WaypointMgr.DeletePath(lowguid); if (pCreature) { // update movement type if (doNotDelete == false) pCreature->LoadPath(0); 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 == false) { handler->PSendSysMessage(LANG_MOVE_TYPE_SET,type_str); } else { handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL,type_str); } return true; } //npc phasemask handling //change phasemask of creature or pet static bool HandleNpcSetPhaseCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 phasemask = (uint32) atoi((char*)args); if (phasemask == 0) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->SetPhaseMask(phasemask,true); if (!pCreature->isPet()) pCreature->SaveToDB(); return true; } //set spawn dist of creature static bool HandleNpcSetSpawnDistCommand(ChatHandler* handler, const char* args) { if (!*args) return false; float option = (float)(atof((char*)args)); if (option < 0.0f) { handler->SendSysMessage(LANG_BAD_VALUE); return false; } MovementGeneratorType mtype = IDLE_MOTION_TYPE; if (option >0.0f) mtype = RANDOM_MOTION_TYPE; Creature *pCreature = handler->getSelectedCreature(); uint32 u_guidlow = 0; if (pCreature) u_guidlow = pCreature->GetDBTableGUIDLow(); else 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.PExecute("UPDATE creature SET spawndist=%f, MovementType=%i WHERE guid=%u",option,mtype,u_guidlow); handler->PSendSysMessage(LANG_COMMAND_SPAWNDIST,option); return true; } //spawn time handling static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* stime = strtok((char*)args, " "); if (!stime) return false; int i_stime = atoi((char*)stime); if (i_stime < 0) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } Creature *pCreature = handler->getSelectedCreature(); uint32 u_guidlow = 0; if (pCreature) u_guidlow = pCreature->GetDBTableGUIDLow(); else return false; WorldDatabase.PExecute("UPDATE creature SET spawntimesecs=%i WHERE guid=%u",i_stime,u_guidlow); pCreature->SetRespawnDelay((uint32)i_stime); handler->PSendSysMessage(LANG_COMMAND_SPAWNTIME,i_stime); return true; } static bool HandleNpcSayCommand(ChatHandler* handler, const char* args) { if (!*args) return false; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->MonsterSay(args, LANG_UNIVERSAL, 0); // make some emotes char lastchar = args[strlen(args) - 1]; switch(lastchar) { case '?': pCreature->HandleEmoteCommand(EMOTE_ONESHOT_QUESTION); break; case '!': pCreature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break; default: pCreature->HandleEmoteCommand(EMOTE_ONESHOT_TALK); break; } return true; } //show text emote by creature in chat static bool HandleNpcTextEmoteCommand(ChatHandler* handler, const char* args) { if (!*args) return false; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->MonsterTextEmote(args, 0); return true; } //npc unfollow handling static bool HandleNpcUnFollowCommand(ChatHandler* handler, const char* /*args*/) { Player *player = handler->GetSession()->GetPlayer(); Creature *creature = handler->getSelectedCreature(); if (!creature) { handler->PSendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (/*creature->GetMotionMaster()->empty() ||*/ creature->GetMotionMaster()->GetCurrentMovementGeneratorType () != TARGETED_MOTION_TYPE) { handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); handler->SetSentErrorMessage(true); return false; } TargetedMovementGenerator const* mgen = static_cast const*>((creature->GetMotionMaster()->top())); if (mgen->GetTarget() != player) { handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); handler->SetSentErrorMessage(true); return false; } // reset movement creature->GetMotionMaster()->MovementExpired(true); handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName()); return true; } // make npc whisper to player static bool HandleNpcWhisperCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* receiver_str = strtok((char*)args, " "); char* text = strtok(NULL, ""); uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); Creature* pCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(guid); if (!pCreature || !receiver_str || !text) { return false; } uint64 receiver_guid= atol(receiver_str); // check online security if (handler->HasLowerSecurity(sObjectMgr->GetPlayer(receiver_guid), 0)) return false; pCreature->MonsterWhisper(text,receiver_guid); return true; } static bool HandleNpcYellCommand(ChatHandler* handler, const char* args) { if (!*args) return false; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pCreature->MonsterYell(args, LANG_UNIVERSAL, 0); // make an emote pCreature->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT); return true; } // add creature, temp only static bool HandleNpcAddTempSpawnCommand(ChatHandler* handler, const char* args) { if (!*args) return false; char* charID = strtok((char*)args, " "); if (!charID) return false; Player *chr = handler->GetSession()->GetPlayer(); uint32 id = atoi(charID); if (!id) return false; chr->SummonCreature(id, *chr, TEMPSUMMON_CORPSE_DESPAWN, 120); return true; } //npc tame handling static bool HandleNpcTameCommand(ChatHandler* handler, const char* /*args*/) { Creature *creatureTarget = handler->getSelectedCreature (); if (!creatureTarget || creatureTarget->isPet ()) { handler->PSendSysMessage (LANG_SELECT_CREATURE); handler->SetSentErrorMessage (true); return false; } Player *player = handler->GetSession()->GetPlayer (); if (player->GetPetGUID ()) { handler->SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); handler->SetSentErrorMessage (true); return false; } CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); if (!cInfo->isTameable (player->CanTameExoticPets())) { handler->PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); handler->SetSentErrorMessage (true); return false; } // Everything looks OK, create new pet Pet* pet = player->CreateTamedPetFrom (creatureTarget); if (!pet) { handler->PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); handler->SetSentErrorMessage (true); return false; } // place pet before player float x,y,z; player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); // set pet to defensive mode by default (some classes can't control controlled pets in fact). pet->SetReactState(REACT_DEFENSIVE); // calculate proper level uint8 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); // prepare visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); // add to world pet->GetMap()->Add(pet->ToCreature()); // visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); // caster have pet now player->SetMinion(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); return true; } //npc deathstate handling static bool HandleNpcSetDeathStateCommand(ChatHandler* handler, const char* args) { if (!*args) return false; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature || pCreature->isPet()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (strncmp(args, "on", 3) == 0) pCreature->SetDeadByDefault(true); else if (strncmp(args, "off", 4) == 0) pCreature->SetDeadByDefault(false); else { handler->SendSysMessage(LANG_USE_BOL); handler->SetSentErrorMessage(true); return false; } pCreature->SaveToDB(); pCreature->Respawn(); return true; } static bool HandleNpcAddFormationCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 leaderGUID = (uint32) atoi((char*)args); Creature *pCreature = handler->getSelectedCreature(); if (!pCreature || !pCreature->GetDBTableGUIDLow()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } uint32 lowguid = pCreature->GetDBTableGUIDLow(); if (pCreature->GetFormation()) { handler->PSendSysMessage("Selected creature is already member of group %u", pCreature->GetFormation()->GetId()); return false; } if (!lowguid) return false; Player *chr = handler->GetSession()->GetPlayer(); FormationInfo *group_member; group_member = new FormationInfo; group_member->follow_angle = (pCreature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI; group_member->follow_dist = sqrtf(pow(chr->GetPositionX() - pCreature->GetPositionX(),int(2))+pow(chr->GetPositionY()-pCreature->GetPositionY(),int(2))); group_member->leaderGUID = leaderGUID; group_member->groupAI = 0; CreatureGroupMap[lowguid] = group_member; pCreature->SearchFormation(); WorldDatabase.PExecute("INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES ('%u','%u','%f', '%f', '%u')", leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI); handler->PSendSysMessage("Creature %u added to formation with leader %u", lowguid, leaderGUID); return true; } static bool HandleNpcSetLinkCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 linkguid = (uint32) atoi((char*)args); Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } if (!pCreature->GetDBTableGUIDLow()) { handler->PSendSysMessage("Selected creature %u isn't in creature table", pCreature->GetGUIDLow()); handler->SetSentErrorMessage(true); return false; } if (!sObjectMgr->SetCreatureLinkedRespawn(pCreature->GetDBTableGUIDLow(), linkguid)) { handler->PSendSysMessage("Selected creature can't link with guid '%u'", linkguid); handler->SetSentErrorMessage(true); return false; } handler->PSendSysMessage("LinkGUID '%u' added to creature with DBTableGUID: '%u'", linkguid, pCreature->GetDBTableGUIDLow()); return true; } //TODO: NpcCommands that need to be fixed : static bool HandleNpcAddWeaponCommand(ChatHandler* /*handler*/, const char* /*args*/) { /*if (!*args) return false; uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); if (guid == 0) { handler->SendSysMessage(LANG_NO_SELECTION); return true; } Creature *pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); if (!pCreature) { handler->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: handler->PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST,SlotID); added = false; break; } if (added) handler->PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT,ItemID,tmpItem->Name1,SlotID); } else { handler->PSendSysMessage(LANG_ITEM_NOT_FOUND,ItemID); return true; } */ return true; } static bool HandleNpcSetNameCommand(ChatHandler* /*handler*/, const char* /*args*/) { /* Temp. disabled if (!*args) return false; if (strlen((char*)args)>75) { handler->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] != ' ') { handler->SendSysMessage(LANG_CHARS_ONLY); return false; } } uint64 guid; guid = handler->GetSession()->GetPlayer()->GetSelection(); if (guid == 0) { handler->SendSysMessage(LANG_NO_SELECTION); return true; } Creature* pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); if (!pCreature) { handler->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; } static bool HandleNpcSetSubNameCommand(ChatHandler* /*handler*/, const char* /*args*/) { /* Temp. disabled if (!*args) args = ""; if (strlen((char*)args)>75) { handler->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] != ' ') { handler->SendSysMessage(LANG_CHARS_ONLY); return false; } } uint64 guid; guid = handler->GetSession()->GetPlayer()->GetSelection(); if (guid == 0) { handler->SendSysMessage(LANG_NO_SELECTION); return true; } Creature* pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid); if (!pCreature) { handler->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; } }; void AddSC_npc_commandscript() { new npc_commandscript(); }