bool GossipHello_TeleportMaster(Player *player, Creature *Creature) { // Make sure we can access the Config file if(!SD2Config.SetSource(_SCRIPTDEV2_CONFIG)) { player->CLOSE_GOSSIP_MENU(); error_log("TeleportMaster: Unable to open configuration file"); Creature->MonsterWhisper("I'm sorry, we are having technical difficulties. Please check back later.",(Unit *)player->GetGUID()); return false; } // Make sure player is not in combat if(!player->getAttackers().empty()) { player->CLOSE_GOSSIP_MENU(); Creature->MonsterWhisper("You are in combat!",(Unit *)player->GetGUID()); return false; } // If enabled, make sure only GM can use TelePorts if(SD2Config.GetBoolDefault("TeleportMaster.OnlyGMs", false)) { if(player->GetSession()->GetSecurity() == SEC_PLAYER) { player->CLOSE_GOSSIP_MENU(); Creature->MonsterWhisper("Sorry, I am only allowed to teleport game masters.", (Unit *)player->GetGUID()); return false; } } ProcessMenu_TeleportMaster(player, Creature,0,0,0); return true; }
PlayerbotMgr::PlayerbotMgr(Player* const master) : m_master(master) { // load config variables m_confMaxNumBots = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); m_confDebugWhisper = botConfig.GetBoolDefault("PlayerbotAI.DebugWhisper", false); m_confFollowDistance[0] = botConfig.GetFloatDefault("PlayerbotAI.FollowDistanceMin", 0.5f); m_confFollowDistance[1] = botConfig.GetFloatDefault("PlayerbotAI.FollowDistanceMin", 1.0f); }
bool GossipHello_custom_npc_buffmaster(Player* pPlayer, Creature* pCreature) { Config CUSTOMConfig; if(!CUSTOMConfig.SetSource(_CUSTOM_CONFIG)) error_log("CUSTOM: Unable to open configuration file"); bool SmallBuffsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.SmallBuffsEnabled", true); bool GreatBuffsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.GreatBuffsEnabled", true); bool GameMasterBuffsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.GameMasterBuffsEnabled", true); bool PlayerToolsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.PlayerToolsEnabled", true); bool GoldSpellEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.GoldSpellEnabled", false); if (pPlayer->GetTeam() == ALLIANCE) { if(SmallBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Small Buffs ->" , GOSSIP_SENDER_MAIN, 1000); if(GreatBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Great Buffs ->" , GOSSIP_SENDER_MAIN, 2000); if(GameMasterBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "GM Buffs ->" , GOSSIP_SENDER_MAIN, 3000); if(PlayerToolsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Player Tools ->" , GOSSIP_SENDER_MAIN, 4000); pPlayer->ADD_GOSSIP_ITEM( 10, "Remove Resurrect Sickness" , GOSSIP_SENDER_MAIN, 5000); } else { if(SmallBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Small Buffs ->" , GOSSIP_SENDER_MAIN, 1000); if(GreatBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Great Buffs ->" , GOSSIP_SENDER_MAIN, 2000); if(GameMasterBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "GM Buffs ->" , GOSSIP_SENDER_MAIN, 3000); if(PlayerToolsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Player Tools ->" , GOSSIP_SENDER_MAIN, 4000); pPlayer->ADD_GOSSIP_ITEM( 10, "Remove Resurrect Sickness" , GOSSIP_SENDER_MAIN, 5000); } pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetObjectGuid()); return true; }
PlayerbotMgr::PlayerbotMgr(Player* const master) : m_master(master) { // load config variables m_confMaxNumBots = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); m_confDebugWhisper = botConfig.GetBoolDefault("PlayerbotAI.DebugWhisper", false); m_confFollowDistance[0] = botConfig.GetFloatDefault("PlayerbotAI.FollowDistanceMin", 0.5f); m_confFollowDistance[1] = botConfig.GetFloatDefault("PlayerbotAI.FollowDistanceMax", 1.0f); m_confCollectCombat = botConfig.GetBoolDefault("PlayerbotAI.Collect.Combat", true); m_confCollectQuest = botConfig.GetBoolDefault("PlayerbotAI.Collect.Quest", true); m_confCollectProfession = botConfig.GetBoolDefault("PlayerbotAI.Collect.Profession", true); m_confCollectLoot = botConfig.GetBoolDefault("PlayerbotAI.Collect.Loot", true); m_confCollectSkin = botConfig.GetBoolDefault("PlayerbotAI.Collect.Skin", true); m_confCollectObjects = botConfig.GetBoolDefault("PlayerbotAI.Collect.Objects", true); m_confCollectDistanceMax = botConfig.GetIntDefault("PlayerbotAI.Collect.DistanceMax", 50); gConfigSellLevelDiff = botConfig.GetIntDefault("PlayerbotAI.SellAll.LevelDiff", 10); if (m_confCollectDistanceMax > 100) { sLog.outError("Playerbot: PlayerbotAI.Collect.DistanceMax higher than allowed. Using 100"); m_confCollectDistanceMax = 100; } m_confCollectDistance = botConfig.GetIntDefault("PlayerbotAI.Collect.Distance", 25); if (m_confCollectDistance > m_confCollectDistanceMax) { sLog.outError("Playerbot: PlayerbotAI.Collect.Distance higher than PlayerbotAI.Collect.DistanceMax. Using DistanceMax value"); m_confCollectDistance = m_confCollectDistanceMax; } }
bool GossipHello_custom_npc_buffmaster(Player* pPlayer, Creature* pCreature) { Config HNConfig; if(!HNConfig.SetSource(_HELLSCREAM_CONFIG,true)) error_log("HN: Unable to open configuration file"); bool SmallBuffsEnabled = HNConfig.GetBoolDefault("BuffsMaster.SmallBuffsEnabled", true); bool GreatBuffsEnabled = HNConfig.GetBoolDefault("BuffsMaster.GreatBuffsEnabled", true); bool GameMasterBuffsEnabled = HNConfig.GetBoolDefault("BuffsMaster.GameMasterBuffsEnabled", true); bool PlayerToolsEnabled = HNConfig.GetBoolDefault("BuffsMaster.PlayerToolsEnabled", true); bool GoldSpellEnabled = HNConfig.GetBoolDefault("BuffsMaster.GoldSpellEnabled", false); if (pPlayer->GetTeam() == ALLIANCE) { if(SmallBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Small Buffs ->" , GOSSIP_SENDER_MAIN, 1000); if(GreatBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Great Buffs ->" , GOSSIP_SENDER_MAIN, 2000); if(GameMasterBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "GM Buffs ->" , GOSSIP_SENDER_MAIN, 3000); if(PlayerToolsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Player Tools ->" , GOSSIP_SENDER_MAIN, 4000); } else { if(SmallBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Small Buffs ->" , GOSSIP_SENDER_MAIN, 1000); if(GreatBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Great Buffs ->" , GOSSIP_SENDER_MAIN, 2000); if(GameMasterBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "GM Buffs ->" , GOSSIP_SENDER_MAIN, 3000); if(PlayerToolsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Player Tools ->" , GOSSIP_SENDER_MAIN, 4000); } pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetGUID()); return true; }
// Cooldown Removing Item bool ItemUse_custom_item_cooldownremover(Player* pPlayer, Item* pItem, const SpellCastTargets &pTargets) { Config DARKICEConfig; if(!DARKICEConfig.SetSource(_DARKICE_CONFIG)) error_log("DARKICE: Unable to open configuration file"); bool CooldownRemoverInfinte = DARKICEConfig.GetBoolDefault("Item_CooldownRemoverInfinte", true); if(CooldownRemoverInfinte) { pPlayer->RemoveAllSpellCooldown(); return false; } else { pPlayer->RemoveAllSpellCooldown(); return true; } }
PlayerbotMgr::PlayerbotMgr(Player* const master) : m_master(master) { // load config variables m_confMaxNumBots = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); m_confDebugWhisper = botConfig.GetBoolDefault("PlayerbotAI.DebugWhisper", false); m_confFollowDistance[0] = botConfig.GetFloatDefault("PlayerbotAI.FollowDistanceMin", 0.5f); m_confFollowDistance[1] = botConfig.GetFloatDefault("PlayerbotAI.FollowDistanceMax", 1.0f); m_confCollectCombat = botConfig.GetBoolDefault("PlayerbotAI.Collect.Combat", true); m_confCollectQuest = botConfig.GetBoolDefault("PlayerbotAI.Collect.Quest", true); m_confCollectProfession = botConfig.GetBoolDefault("PlayerbotAI.Collect.Profession", true); m_confCollectLoot = botConfig.GetBoolDefault("PlayerbotAI.Collect.Loot", true); m_confCollectSkin = botConfig.GetBoolDefault("PlayerbotAI.Collect.Skin", true); m_confCollectObjects = botConfig.GetBoolDefault("PlayerbotAI.Collect.Objects", true); }
void PlayerbotMgr::HandleMasterIncomingPacket(const WorldPacket& packet) { switch (packet.GetOpcode()) { case CMSG_OFFER_PETITION: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid petitionGuid; ObjectGuid playerGuid; uint32 junk; p >> junk; // this is not petition type! p >> petitionGuid; // petition guid p >> playerGuid; // player guid Player* player = ObjectAccessor::FindPlayer(playerGuid); if (!player) return; uint32 petitionLowGuid = petitionGuid.GetCounter(); QueryResult* result = CharacterDatabase.PQuery("SELECT * FROM petition_sign WHERE playerguid = '%u' AND petitionguid = '%u'", player->GetGUIDLow(), petitionLowGuid); if (result) { ChatHandler(m_master).PSendSysMessage("%s has already signed the petition", player->GetName()); delete result; return; } CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GetMaster()->GetGUIDLow(), petitionLowGuid, player->GetGUIDLow(), GetMaster()->GetSession()->GetAccountId()); p.Initialize(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4)); p << ObjectGuid(petitionGuid); p << ObjectGuid(playerGuid); p << uint32(PETITION_SIGN_OK); // close at signer side GetMaster()->GetSession()->SendPacket(p); return; } case CMSG_ACTIVATETAXI: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; std::vector<uint32> nodes; nodes.resize(2); uint8 delay = 9; p >> guid >> nodes[0] >> nodes[1]; // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_ACTIVATETAXI from %d to %d", nodes[0], nodes[1]); for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { delay = delay + 3; Player* const bot = it->second; if (!bot) return; Group* group = bot->GetGroup(); if (!group) continue; Unit* target = ObjectAccessor::GetUnit(*bot, guid); bot->GetPlayerbotAI()->SetIgnoreUpdateTime(delay); bot->GetMotionMaster()->Clear(true); bot->GetMotionMaster()->MoveFollow(target, INTERACTION_DISTANCE, bot->GetOrientation()); bot->GetPlayerbotAI()->GetTaxi(guid, nodes); } return; } case CMSG_ACTIVATETAXIEXPRESS: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; uint32 node_count; uint8 delay = 9; p >> guid; p.read_skip<uint32>(); p >> node_count; std::vector<uint32> nodes; for (uint32 i = 0; i < node_count; ++i) { uint32 node; p >> node; nodes.push_back(node); } if (nodes.empty()) return; // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_ACTIVATETAXIEXPRESS from %d to %d", nodes.front(), nodes.back()); for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { delay = delay + 3; Player* const bot = it->second; if (!bot) return; Group* group = bot->GetGroup(); if (!group) continue; Unit* target = ObjectAccessor::GetUnit(*bot, guid); bot->GetPlayerbotAI()->SetIgnoreUpdateTime(delay); bot->GetMotionMaster()->Clear(true); bot->GetMotionMaster()->MoveFollow(target, INTERACTION_DISTANCE, bot->GetOrientation()); bot->GetPlayerbotAI()->GetTaxi(guid, nodes); } return; } // if master is logging out, log out all bots case CMSG_LOGOUT_REQUEST: { LogoutAllBots(); return; } // If master inspects one of his bots, give the master useful info in chat window // such as inventory that can be equipped case CMSG_INSPECT: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; p >> guid; Player* const bot = GetPlayerBot(guid); if (bot) bot->GetPlayerbotAI()->SendNotEquipList(*bot); return; } // handle emotes from the master //case CMSG_EMOTE: case CMSG_TEXT_EMOTE: { WorldPacket p(packet); p.rpos(0); // reset reader uint32 emoteNum; p >> emoteNum; /* std::ostringstream out; out << "emote is: " << emoteNum; ChatHandler ch(m_master); ch.SendSysMessage(out.str().c_str()); */ switch (emoteNum) { case TEXTEMOTE_BOW: { // Buff anyone who bows before me. Useful for players not in bot's group // How do I get correct target??? //Player* const pPlayer = GetPlayerBot(m_master->GetSelection()); //if (pPlayer->GetPlayerbotAI()->GetClassAI()) // pPlayer->GetPlayerbotAI()->GetClassAI()->BuffPlayer(pPlayer); return; } /* case TEXTEMOTE_BONK: { Player* const pPlayer = GetPlayerBot(m_master->GetSelection()); if (!pPlayer || !pPlayer->GetPlayerbotAI()) return; PlayerbotAI* const pBot = pPlayer->GetPlayerbotAI(); ChatHandler ch(m_master); { std::ostringstream out; out << "CurrentTime: " << CurrentTime() << " m_ignoreAIUpdatesUntilTime: " << pBot->m_ignoreAIUpdatesUntilTime; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "m_CurrentlyCastingSpellId: " << pBot->m_CurrentlyCastingSpellId; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "IsBeingTeleported() " << pBot->GetPlayer()->IsBeingTeleported(); ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; bool tradeActive = (pBot->GetPlayer()->GetTrader()) ? true : false; out << "tradeActive: " << tradeActive; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "IsCharmed() " << pBot->getPlayer()->isCharmed(); ch.SendSysMessage(out.str().c_str()); } return; } */ case TEXTEMOTE_EAT: case TEXTEMOTE_DRINK: return; // emote to attack selected target case TEXTEMOTE_POINT: { ObjectGuid attackOnGuid = m_master->GetSelectionGuid(); if (!attackOnGuid) return; Unit* thingToAttack = ObjectAccessor::GetUnit(*m_master, attackOnGuid); if (!thingToAttack) return; Player* bot = 0; for (PlayerBotMap::iterator itr = m_playerBots.begin(); itr != m_playerBots.end(); ++itr) { bot = itr->second; if (bot->CanAttack(thingToAttack)) { if (!bot->IsWithinLOSInMap(thingToAttack)) bot->GetPlayerbotAI()->DoTeleport(*m_master); if (bot->IsWithinLOSInMap(thingToAttack)) bot->GetPlayerbotAI()->Attack(thingToAttack); } } return; } // emote to stay case TEXTEMOTE_STAND: { Player* const bot = GetPlayerBot(m_master->GetSelectionGuid()); if (bot) bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_STAY); else for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_STAY); } return; } // 324 is the followme emote (not defined in enum) // if master has bot selected then only bot follows, else all bots follow case 324: case TEXTEMOTE_WAVE: { Player* const bot = GetPlayerBot(m_master->GetSelectionGuid()); if (bot) bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_FOLLOW, m_master); else for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_FOLLOW, m_master); } return; } } return; } /* EMOTE ends here */ case CMSG_GAMEOBJ_USE: // Used by bots to turn in quest to GameObjects when also used by master { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid objGUID; p >> objGUID; for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; // If player and bot are on different maps: then player was teleported by GameObject // let's return and let playerbot summon do its job by teleporting bots if (bot->GetMap() != m_master->GetMap()) return; GameObject* obj = m_master->GetMap()->GetGameObject(objGUID); if (!obj) return; bot->GetPlayerbotAI()->FollowAutoReset(); if (obj->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) bot->GetPlayerbotAI()->TurnInQuests(obj); // add other go types here, i.e.: // GAMEOBJECT_TYPE_CHEST - loot quest items of chest } } break; case CMSG_QUESTGIVER_HELLO: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid npcGUID; p >> npcGUID; WorldObject* pNpc = m_master->GetMap()->GetWorldObject(npcGUID); if (!pNpc) return; // for all master's bots for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->FollowAutoReset(); bot->GetPlayerbotAI()->TurnInQuests(pNpc); } return; } // if master accepts a quest, bots should also try to accept quest case CMSG_QUESTGIVER_ACCEPT_QUEST: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; uint32 quest; // uint32 unk1; p >> guid >> quest; // >> unk1; // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u, unk1 = %u", guid.GetString().c_str(), quest, unk1); Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if (qInfo) for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->FollowAutoReset(); if (bot->GetQuestStatus(quest) == QUEST_STATUS_COMPLETE) bot->GetPlayerbotAI()->TellMaster("I already completed that quest."); else if (!bot->CanTakeQuest(qInfo, false)) { if (!bot->SatisfyQuestStatus(qInfo, false)) bot->GetPlayerbotAI()->TellMaster("I already have that quest."); else bot->GetPlayerbotAI()->TellMaster("I can't take that quest."); } else if (!bot->SatisfyQuestLog(false)) bot->GetPlayerbotAI()->TellMaster("My quest log is full."); else if (!bot->CanAddQuest(qInfo, false)) bot->GetPlayerbotAI()->TellMaster("I can't take that quest because it requires that I take items, but my bags are full!"); else { p.rpos(0); // reset reader bot->GetSession()->HandleQuestgiverAcceptQuestOpcode(p); bot->GetPlayerbotAI()->TellMaster("Got the quest."); // build needed items if quest contains any for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; i++) if (qInfo->ReqItemCount[i] > 0) { bot->GetPlayerbotAI()->SetQuestNeedItems(); break; } // build needed creatures if quest contains any for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) if (qInfo->ReqCreatureOrGOCount[i] > 0) { bot->GetPlayerbotAI()->SetQuestNeedCreatures(); break; } } } return; } case CMSG_AREATRIGGER: { WorldPacket p(packet); for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (!bot) continue; if (bot->IsWithinDistInMap(GetMaster(), 50)) { p.rpos(0); // reset reader bot->GetSession()->HandleAreaTriggerOpcode(p); } } return; } case CMSG_QUESTGIVER_COMPLETE_QUEST: { WorldPacket p(packet); p.rpos(0); // reset reader uint32 quest; ObjectGuid npcGUID; p >> npcGUID >> quest; // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %s, quest = %u", npcGUID.GetString().c_str(), quest); WorldObject* pNpc = m_master->GetMap()->GetWorldObject(npcGUID); if (!pNpc) return; // for all master's bots for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->FollowAutoReset(); bot->GetPlayerbotAI()->TurnInQuests(pNpc); } return; } case CMSG_LOOT_ROLL: { WorldPacket p(packet); //WorldPacket packet for CMSG_LOOT_ROLL, (8+4+1) ObjectGuid Guid; uint32 itemSlot; uint8 rollType; p.rpos(0); //reset packet pointer p >> Guid; //guid of the lootable target p >> itemSlot; //loot index p >> rollType; //need,greed or pass on roll for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { uint32 choice = 0; Player* const bot = it->second; if (!bot) return; Group* group = bot->GetGroup(); if (!group) return; // check that the bot did not already vote if (rollType >= ROLL_NOT_EMITED_YET) return; Loot* loot = sLootMgr.GetLoot(bot, Guid); if (!loot) { sLog.outError("LootMgr::PlayerVote> Error cannot get loot object info!"); return; } LootItem* lootItem = loot->GetLootItemInSlot(itemSlot); ItemPrototype const* pProto = lootItem->itemProto; if (!pProto) return; if (bot->GetPlayerbotAI()->CanStore()) { if (bot->CanUseItem(pProto) == EQUIP_ERR_OK && bot->GetPlayerbotAI()->IsItemUseful(lootItem->itemId)) choice = 1; // Need else if (bot->HasSkill(SKILL_ENCHANTING)) choice = 3; // Disenchant else choice = 2; // Greed } else choice = 0; // Pass sLootMgr.PlayerVote(bot, Guid, itemSlot, RollVote(choice)); } return; } // Handle GOSSIP activate actions, prior to GOSSIP select menu actions case CMSG_GOSSIP_HELLO: { // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO"); WorldPacket p(packet); //WorldPacket packet for CMSG_GOSSIP_HELLO, (8) ObjectGuid guid; p.rpos(0); //reset packet pointer p >> guid; for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (!bot) continue; bot->GetPlayerbotAI()->FollowAutoReset(); Creature* pCreature = bot->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!pCreature) { DEBUG_LOG("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO %s not found or you can't interact with him.", guid.GetString().c_str()); continue; } GossipMenuItemsMapBounds pMenuItemBounds = sObjectMgr.GetGossipMenuItemsMapBounds(pCreature->GetCreatureInfo()->GossipMenuId); for (GossipMenuItemsMap::const_iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr) { uint32 npcflags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS); if (!(itr->second.npc_option_npcflag & npcflags)) continue; switch (itr->second.option_id) { case GOSSIP_OPTION_TAXIVENDOR: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_TAXIVENDOR"); bot->GetSession()->SendLearnNewTaxiNode(pCreature); break; } case GOSSIP_OPTION_QUESTGIVER: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_QUESTGIVER"); bot->GetPlayerbotAI()->TurnInQuests(pCreature); break; } case GOSSIP_OPTION_VENDOR: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_VENDOR"); if (!botConfig.GetBoolDefault("PlayerbotAI.SellGarbage", true)) continue; // changed the SellGarbage() function to support ch.SendSysMessaage() bot->GetPlayerbotAI()->SellGarbage(*bot); break; } case GOSSIP_OPTION_STABLEPET: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_STABLEPET"); break; } case GOSSIP_OPTION_AUCTIONEER: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_AUCTIONEER"); break; } case GOSSIP_OPTION_BANKER: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_BANKER"); break; } case GOSSIP_OPTION_INNKEEPER: { // bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_INNKEEPER"); break; } } } } return; } case CMSG_SPIRIT_HEALER_ACTIVATE: { // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_SPIRIT_HEALER_ACTIVATE SpiritHealer is resurrecting the Player %s",m_master->GetName()); for (PlayerBotMap::iterator itr = m_playerBots.begin(); itr != m_playerBots.end(); ++itr) { Player* const bot = itr->second; Group* grp = bot->GetGroup(); if (grp) grp->RemoveMember(bot->GetObjectGuid(), 1); } return; } case CMSG_LIST_INVENTORY: { if (!botConfig.GetBoolDefault("PlayerbotAI.SellGarbage", true)) return; WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid npcGUID; p >> npcGUID; Object* const pNpc = (WorldObject*) m_master->GetObjectByTypeMask(npcGUID, TYPEMASK_CREATURE_OR_GAMEOBJECT); if (!pNpc) return; // for all master's bots for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (!bot->IsInMap(static_cast<WorldObject*>(pNpc))) { bot->GetPlayerbotAI()->TellMaster("I'm too far away to sell items!"); continue; } else { // changed the SellGarbage() function to support ch.SendSysMessaage() bot->GetPlayerbotAI()->FollowAutoReset(); bot->GetPlayerbotAI()->SellGarbage(*bot); } } return; } /* case CMSG_NAME_QUERY: case MSG_MOVE_START_FORWARD: case MSG_MOVE_STOP: case MSG_MOVE_SET_FACING: case MSG_MOVE_START_STRAFE_LEFT: case MSG_MOVE_START_STRAFE_RIGHT: case MSG_MOVE_STOP_STRAFE: case MSG_MOVE_START_BACKWARD: case MSG_MOVE_HEARTBEAT: case CMSG_STANDSTATECHANGE: case CMSG_QUERY_TIME: case CMSG_CREATURE_QUERY: case CMSG_GAMEOBJECT_QUERY: case MSG_MOVE_JUMP: case MSG_MOVE_FALL_LAND: return;*/ default: { /*const char* oc = LookupOpcodeName(packet.GetOpcode()); // ChatHandler ch(m_master); // ch.SendSysMessage(oc); std::ostringstream out; out << "masterin: " << oc; sLog.outError(out.str().c_str()); */ } } }
bool ChatHandler::HandlePlayerbotCommand(char* args) { if (!(m_session->GetSecurity() > SEC_PLAYER)) { if (botConfig.GetBoolDefault("PlayerbotAI.DisableBots", false)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char* cmd = strtok((char*) args, " "); char* charname = strtok(nullptr, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid == ObjectGuid() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 accountId = sObjectMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; } // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } QueryResult* resultchar = CharacterDatabase.PQuery("SELECT COUNT(*) FROM characters WHERE online = '1' AND account = '%u'", m_session->GetAccountId()); if (resultchar) { Field* fields = resultchar->Fetch(); int acctcharcount = fields[0].GetUInt32(); int maxnum = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (acctcharcount > maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)", maxnum); SetSentErrorMessage(true); delete resultchar; return false; } delete resultchar; } QueryResult* resultlvl = CharacterDatabase.PQuery("SELECT level, name, race FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field* fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); int maxlvl = botConfig.GetIntDefault("PlayerbotAI.RestrictBotLevel", 80); uint8 race = fields[2].GetUInt8(); uint32 team = 0; team = Player::TeamForRace(race); if (!(m_session->GetSecurity() > SEC_PLAYER)) { if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } // Opposing team bot if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP) && m_session->GetPlayer()->GetTeam() != team) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, a member of the enemy side", fields[1].GetString()); SetSentErrorMessage(true); delete resultlvl; return false; } } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); mgr->LoginPlayerBot(guid); PSendSysMessage("Bot added successfully."); } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); } return true; }
void PlayerbotMgr::HandleMasterIncomingPacket(const WorldPacket& packet) { switch (packet.GetOpcode()) { case CMSG_ACTIVATETAXI: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; std::vector<uint32> nodes; nodes.resize(2); uint8 delay = 9; p >> guid >> nodes[0] >> nodes[1]; DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_ACTIVATETAXI from %d to %d", nodes[0], nodes[1]); for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { delay = delay + 3; Player* const bot = it->second; if (!bot) return; Group* group = bot->GetGroup(); if (!group) continue; Unit *target = ObjectAccessor::GetUnit(*bot, guid); bot->GetPlayerbotAI()->SetIgnoreUpdateTime(delay); bot->GetMotionMaster()->Clear(true); bot->GetMotionMaster()->MoveFollow(target, INTERACTION_DISTANCE, bot->GetOrientation()); bot->GetPlayerbotAI()->GetTaxi(guid, nodes); } return; } case CMSG_ACTIVATETAXIEXPRESS: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; uint32 node_count; uint8 delay = 9; p >> guid; p.read_skip<uint32>(); p >> node_count; std::vector<uint32> nodes; for (uint32 i = 0; i < node_count; ++i) { uint32 node; p >> node; nodes.push_back(node); } if (nodes.empty()) return; DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_ACTIVATETAXIEXPRESS from %d to %d", nodes.front(), nodes.back()); for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { delay = delay + 3; Player* const bot = it->second; if (!bot) return; Group* group = bot->GetGroup(); if (!group) continue; Unit *target = ObjectAccessor::GetUnit(*bot, guid); bot->GetPlayerbotAI()->SetIgnoreUpdateTime(delay); bot->GetMotionMaster()->Clear(true); bot->GetMotionMaster()->MoveFollow(target, INTERACTION_DISTANCE, bot->GetOrientation()); bot->GetPlayerbotAI()->GetTaxi(guid, nodes); } return; } case CMSG_MOVE_SPLINE_DONE: { DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_MOVE_SPLINE_DONE"); WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; // used only for proper packet read MovementInfo movementInfo; // used only for proper packet read p >> guid.ReadAsPacked(); p >> movementInfo; p >> Unused<uint32>(); // unk for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (!bot) return; // in taxi flight packet received in 2 case: // 1) end taxi path in far (multi-node) flight // 2) switch from one map to other in case multi-map taxi path // we need process only (1) uint32 curDest = bot->m_taxi.GetTaxiDestination(); if (!curDest) return; TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest); // far teleport case if (curDestNode && curDestNode->map_id != bot->GetMapId()) { if (bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator *) (bot->GetMotionMaster()->top()); flight->Interrupt(*bot); // will reset at map landing flight->SetCurrentNodeAfterTeleport(); TaxiPathNodeEntry const& node = flight->GetPath()[flight->GetCurrentNode()]; flight->SkipCurrentNode(); bot->TeleportTo(curDestNode->map_id, node.x, node.y, node.z, bot->GetOrientation()); } return; } uint32 destinationnode = bot->m_taxi.NextTaxiDestination(); if (destinationnode > 0) // if more destinations to go { // current source node for next destination uint32 sourcenode = bot->m_taxi.GetTaxiSource(); // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path) if (bot->isTaxiCheater()) if (bot->m_taxi.SetTaximaskNode(sourcenode)) { WorldPacket data(SMSG_NEW_TAXI_PATH, 0); bot->GetSession()->SendPacket(&data); } DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_MOVE_SPLINE_DONE Taxi has to go from %u to %u", sourcenode, destinationnode); uint32 mountDisplayId = sObjectMgr.GetTaxiMountDisplayId(sourcenode, bot->GetTeam()); uint32 path, cost; sObjectMgr.GetTaxiPath(sourcenode, destinationnode, path, cost); if (path && mountDisplayId) bot->GetSession()->SendDoFlight(mountDisplayId, path, 1); // skip start fly node else bot->m_taxi.ClearTaxiDestinations(); // clear problematic path and next } else /* std::ostringstream out; out << "Destination reached" << bot->GetName(); ChatHandler ch(m_master); ch.SendSysMessage(out.str().c_str()); */ bot->m_taxi.ClearTaxiDestinations(); // Destination, clear source node } return; } // if master is logging out, log out all bots case CMSG_LOGOUT_REQUEST: { LogoutAllBots(); return; } // If master inspects one of his bots, give the master useful info in chat window // such as inventory that can be equipped case CMSG_INSPECT: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; p >> guid; Player* const bot = GetPlayerBot(guid); if (bot) bot->GetPlayerbotAI()->SendNotEquipList(*bot); return; } // handle emotes from the master //case CMSG_EMOTE: case CMSG_TEXT_EMOTE: { WorldPacket p(packet); p.rpos(0); // reset reader uint32 emoteNum; p >> emoteNum; /* std::ostringstream out; out << "emote is: " << emoteNum; ChatHandler ch(m_master); ch.SendSysMessage(out.str().c_str()); */ switch (emoteNum) { case TEXTEMOTE_BOW: { // Buff anyone who bows before me. Useful for players not in bot's group // How do I get correct target??? //Player* const pPlayer = GetPlayerBot(m_master->GetSelection()); //if (pPlayer->GetPlayerbotAI()->GetClassAI()) // pPlayer->GetPlayerbotAI()->GetClassAI()->BuffPlayer(pPlayer); return; } /* case TEXTEMOTE_BONK: { Player* const pPlayer = GetPlayerBot(m_master->GetSelection()); if (!pPlayer || !pPlayer->GetPlayerbotAI()) return; PlayerbotAI* const pBot = pPlayer->GetPlayerbotAI(); ChatHandler ch(m_master); { std::ostringstream out; out << "CurrentTime: " << CurrentTime() << " m_ignoreAIUpdatesUntilTime: " << pBot->m_ignoreAIUpdatesUntilTime; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "m_TimeDoneEating: " << pBot->m_TimeDoneEating << " m_TimeDoneDrinking: " << pBot->m_TimeDoneDrinking; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "m_CurrentlyCastingSpellId: " << pBot->m_CurrentlyCastingSpellId; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "IsBeingTeleported() " << pBot->GetPlayer()->IsBeingTeleported(); ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; bool tradeActive = (pBot->GetPlayer()->GetTrader()) ? true : false; out << "tradeActive: " << tradeActive; ch.SendSysMessage(out.str().c_str()); } { std::ostringstream out; out << "IsCharmed() " << pBot->getPlayer()->isCharmed(); ch.SendSysMessage(out.str().c_str()); } return; } */ case TEXTEMOTE_EAT: case TEXTEMOTE_DRINK: return; // emote to attack selected target case TEXTEMOTE_POINT: { ObjectGuid attackOnGuid = m_master->GetSelectionGuid(); if (!attackOnGuid) return; Unit* thingToAttack = ObjectAccessor::GetUnit(*m_master, attackOnGuid); if (!thingToAttack) return; Player* bot = 0; for (PlayerBotMap::iterator itr = m_playerBots.begin(); itr != m_playerBots.end(); ++itr) { bot = itr->second; if (!bot->IsFriendlyTo(thingToAttack)) { if (!bot->IsWithinLOSInMap(thingToAttack)) { bot->GetPlayerbotAI()->TellMaster("Trying to attack something, but I'm too far away!"); bot->GetPlayerbotAI()->DoTeleport(*m_master); } if (bot->IsWithinLOSInMap(thingToAttack)) bot->GetPlayerbotAI()->Attack(thingToAttack); } } return; } // emote to stay case TEXTEMOTE_STAND: { Player* const bot = GetPlayerBot(m_master->GetSelectionGuid()); if (bot) bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_STAY); else for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_STAY); } return; } // 324 is the followme emote (not defined in enum) // if master has bot selected then only bot follows, else all bots follow case 324: case TEXTEMOTE_WAVE: { Player* const bot = GetPlayerBot(m_master->GetSelectionGuid()); if (bot) bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_FOLLOW, m_master); else for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->SetMovementOrder(PlayerbotAI::MOVEMENT_FOLLOW, m_master); } return; } } return; } /* EMOTE ends here */ case CMSG_GAMEOBJ_USE: // not sure if we still need this one { DEBUG_LOG("PlayerbotMgr: CMSG_GAMEOBJ_USE"); WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid objGUID; p >> objGUID; for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; GameObject *obj = m_master->GetMap()->GetGameObject(objGUID); if (!obj) return; // add other go types here, i.e.: // GAMEOBJECT_TYPE_CHEST - loot quest items of chest if (obj->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) { bot->GetPlayerbotAI()->TurnInQuests(obj); // auto accept every available quest this NPC has bot->PrepareQuestMenu(objGUID); QuestMenu& questMenu = bot->PlayerTalkClass->GetQuestMenu(); for (uint32 iI = 0; iI < questMenu.MenuItemCount(); ++iI) { QuestMenuItem const& qItem = questMenu.GetItem(iI); uint32 questID = qItem.m_qId; if (!bot->GetPlayerbotAI()->AddQuest(questID, obj)) DEBUG_LOG("Couldn't take quest"); } } } } break; case CMSG_QUESTGIVER_HELLO: { DEBUG_LOG("PlayerbotMgr: CMSG_QUESTGIVER_HELLO"); WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid npcGUID; p >> npcGUID; WorldObject* pNpc = m_master->GetMap()->GetWorldObject(npcGUID); if (!pNpc) return; // for all master's bots for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->TurnInQuests(pNpc); } return; } // if master accepts a quest, bots should also try to accept quest case CMSG_QUESTGIVER_ACCEPT_QUEST: { WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid guid; uint32 quest; uint32 unk1; p >> guid >> quest; DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %s, quest = %u", guid.GetString().c_str(), quest); Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if (qInfo) for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (bot->GetQuestStatus(quest) == QUEST_STATUS_COMPLETE) bot->GetPlayerbotAI()->TellMaster("I already completed that quest."); else if (!bot->CanTakeQuest(qInfo, false)) { if (!bot->SatisfyQuestStatus(qInfo, false)) bot->GetPlayerbotAI()->TellMaster("I already have that quest."); else bot->GetPlayerbotAI()->TellMaster("I can't take that quest."); } else if (!bot->SatisfyQuestLog(false)) bot->GetPlayerbotAI()->TellMaster("My quest log is full."); else if (!bot->CanAddQuest(qInfo, false)) bot->GetPlayerbotAI()->TellMaster("I can't take that quest because it requires that I take items, but my bags are full!"); else { p.rpos(0); // reset reader bot->GetSession()->HandleQuestgiverAcceptQuestOpcode(p); bot->GetPlayerbotAI()->TellMaster("Got the quest."); // build needed items if quest contains any for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; i++) if (qInfo->ReqItemCount[i] > 0) { bot->GetPlayerbotAI()->SetQuestNeedItems(); break; } // build needed creatures if quest contains any for (int i = 0; i < QUEST_OBJECTIVES_COUNT; i++) if (qInfo->ReqCreatureOrGOCount[i] > 0) { bot->GetPlayerbotAI()->SetQuestNeedCreatures(); break; } } } return; } case CMSG_AREATRIGGER: { WorldPacket p(packet); for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; p.rpos(0); // reset reader bot->GetSession()->HandleAreaTriggerOpcode(p); } return; } case CMSG_QUESTGIVER_COMPLETE_QUEST: { WorldPacket p(packet); p.rpos(0); // reset reader uint32 quest; ObjectGuid npcGUID; p >> npcGUID >> quest; DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %s, quest = %u", npcGUID.GetString().c_str(), quest); WorldObject* pNpc = m_master->GetMap()->GetWorldObject(npcGUID); if (!pNpc) return; // for all master's bots for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; bot->GetPlayerbotAI()->TurnInQuests(pNpc); } return; } case CMSG_LOOT_ROLL: { WorldPacket p(packet); //WorldPacket packet for CMSG_LOOT_ROLL, (8+4+1) ObjectGuid Guid; uint32 itemSlot; uint8 rollType; p.rpos(0); //reset packet pointer p >> Guid; //guid of the lootable target p >> itemSlot; //loot index p >> rollType; //need,greed or pass on roll for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { uint32 choice = 0; Player* const bot = it->second; if (!bot) return; Group* group = bot->GetGroup(); if (!group) return; // check that the bot did not already vote if (rollType >= ROLL_NOT_EMITED_YET) return; Loot* loot = sLootMgr.GetLoot(bot, Guid); if (!loot) { sLog.outError("LootMgr::PlayerVote> Error cannot get loot object info!"); return; } LootItem* lootItem = loot->GetLootItemInSlot(itemSlot); ItemPrototype const *pProto = lootItem->itemProto; if (!pProto) return; if (bot->GetPlayerbotAI()->CanStore()) { if (bot->CanUseItem(pProto) == EQUIP_ERR_OK && bot->GetPlayerbotAI()->IsItemUseful(lootItem->itemId)) choice = 1; // Need else choice = 2; // Greed } else choice = 0; // Pass sLootMgr.PlayerVote(bot, Guid, itemSlot, RollVote(choice)); } return; } // Handle GOSSIP activate actions, prior to GOSSIP select menu actions case CMSG_GOSSIP_HELLO: { DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO"); WorldPacket p(packet); //WorldPacket packet for CMSG_GOSSIP_HELLO, (8) ObjectGuid guid; p.rpos(0); //reset packet pointer p >> guid; for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (!bot) continue; Creature *pCreature = bot->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!pCreature) { DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_GOSSIP_HELLO %s not found or you can't interact with him.", guid.GetString().c_str()); continue; } GossipMenuItemsMapBounds pMenuItemBounds = sObjectMgr.GetGossipMenuItemsMapBounds(pCreature->GetCreatureInfo()->GossipMenuId); for (GossipMenuItemsMap::const_iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr) { uint32 npcflags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS); if (!(itr->second.npc_option_npcflag & npcflags)) continue; switch (itr->second.option_id) { case GOSSIP_OPTION_TAXIVENDOR: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_TAXIVENDOR"); bot->GetSession()->SendLearnNewTaxiNode(pCreature); break; } case GOSSIP_OPTION_QUESTGIVER: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_QUESTGIVER"); bot->GetPlayerbotAI()->TurnInQuests(pCreature); break; } case GOSSIP_OPTION_VENDOR: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_VENDOR"); if (!botConfig.GetBoolDefault("PlayerbotAI.SellGarbage", true)) return; bot->GetPlayerbotAI()->SellGarbage(); break; } case GOSSIP_OPTION_STABLEPET: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_STABLEPET"); break; } case GOSSIP_OPTION_AUCTIONEER: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_AUCTIONEER"); break; } case GOSSIP_OPTION_BANKER: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_BANKER"); break; } case GOSSIP_OPTION_INNKEEPER: { //bot->GetPlayerbotAI()->TellMaster("PlayerbotMgr:GOSSIP_OPTION_INNKEEPER"); break; } } } } return; } case CMSG_SPIRIT_HEALER_ACTIVATE: { // DEBUG_LOG ("[PlayerbotMgr]: HandleMasterIncomingPacket - Received CMSG_SPIRIT_HEALER_ACTIVATE SpiritHealer is resurrecting the Player %s",m_master->GetName()); for (PlayerBotMap::iterator itr = m_playerBots.begin(); itr != m_playerBots.end(); ++itr) { Player* const bot = itr->second; Group *grp = bot->GetGroup(); if (grp) grp->RemoveMember(bot->GetObjectGuid(), 1); } return; } case CMSG_LIST_INVENTORY: { if (!botConfig.GetBoolDefault("PlayerbotAI.SellGarbage", true)) return; WorldPacket p(packet); p.rpos(0); // reset reader ObjectGuid npcGUID; p >> npcGUID; Object* const pNpc = (WorldObject *) m_master->GetObjectByTypeMask(npcGUID, TYPEMASK_CREATURE_OR_GAMEOBJECT); if (!pNpc) return; // for all master's bots for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) { Player* const bot = it->second; if (!bot->IsInMap(static_cast<WorldObject *>(pNpc))) { bot->GetPlayerbotAI()->TellMaster("I'm too far away to sell items!"); continue; } else bot->GetPlayerbotAI()->SellGarbage(); } return; } /* case CMSG_NAME_QUERY: case MSG_MOVE_START_FORWARD: case MSG_MOVE_STOP: case MSG_MOVE_SET_FACING: case MSG_MOVE_START_STRAFE_LEFT: case MSG_MOVE_START_STRAFE_RIGHT: case MSG_MOVE_STOP_STRAFE: case MSG_MOVE_START_BACKWARD: case MSG_MOVE_HEARTBEAT: case CMSG_STANDSTATECHANGE: case CMSG_QUERY_TIME: case CMSG_CREATURE_QUERY: case CMSG_GAMEOBJECT_QUERY: case MSG_MOVE_JUMP: case MSG_MOVE_FALL_LAND: return;*/ default: { /*const char* oc = LookupOpcodeName(packet.GetOpcode()); // ChatHandler ch(m_master); // ch.SendSysMessage(oc); std::ostringstream out; out << "masterin: " << oc; sLog.outError(out.str().c_str()); */ } } }
bool ChatHandler::HandlePlayerbotCommand(char* args) { if (!(m_session->GetSecurity() > SEC_PLAYER)) if (botConfig.GetBoolDefault("PlayerbotAI.DisableBots", false)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char *cmd = strtok ((char *) args, " "); char *charname = strtok (nullptr, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid == ObjectGuid() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } // Removed this restriction to accomodate 40 man raids teams of bots in vanilla /*uint32 accountId = sObjectMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; }*/ // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } QueryResult *resultchar = CharacterDatabase.PQuery("SELECT COUNT(*) FROM characters WHERE online = '1' AND account = '%u'", m_session->GetAccountId()); if (resultchar) { Field *fields = resultchar->Fetch(); int acctcharcount = fields[0].GetUInt32(); int maxnum = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (acctcharcount > maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)", maxnum); SetSentErrorMessage(true); delete resultchar; return false; } delete resultchar; } QueryResult *resultlvl = CharacterDatabase.PQuery("SELECT level,name FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field *fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); int maxlvl = botConfig.GetIntDefault("PlayerbotAI.RestrictBotLevel", 60); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); // Modified to allow bot to originate from an account not on the masters account mgr->LoginPlayerBot(guid, mgr->GetMaster()->GetSession()->GetAccountId()); PSendSysMessage("Bot added successfully."); } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); } else if (cmdStr == "co" || cmdStr == "combatorder") { Unit *target = nullptr; char *orderChar = strtok(nullptr, " "); if (!orderChar) { PSendSysMessage("|cffff0000Syntax error:|cffffffff .bot co <botName> <order=reset|tank|assist|heal|protect> [targetPlayer]"); SetSentErrorMessage(true); return false; } return true; } }
void SendDefaultMenu_custom_npc_buffmaster(Player* pPlayer, Creature* pCreature, uint32 uiAction) { //Combat Check if (pPlayer->isInCombat()) { pPlayer->CLOSE_GOSSIP_MENU(); pCreature->MonsterWhisper("You are in combat!", pPlayer, false); return; } Config CUSTOMConfig; if(!CUSTOMConfig.SetSource(_CUSTOM_CONFIG)) error_log("CUSTOM: Unable to open configuration file"); //Money Check if (pPlayer->GetMoney() < (CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))) { pPlayer->CLOSE_GOSSIP_MENU(); pCreature->MonsterWhisper("You don't have enough money.", pPlayer, false); return; } bool SmallBuffsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.SmallBuffsEnabled", true); bool GreatBuffsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.GreatBuffsEnabled", true); bool GameMasterBuffsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.GameMasterBuffsEnabled", true); bool PlayerToolsEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.PlayerToolsEnabled", true); bool GoldSpellEnabled = CUSTOMConfig.GetBoolDefault("BuffsMaster.GoldSpellEnabled", false); switch(uiAction) { case 1000: pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Mark of the Wild" , GOSSIP_SENDER_MAIN, 1001); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Amplify Magic" , GOSSIP_SENDER_MAIN, 1010); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Arcane Intellect" , GOSSIP_SENDER_MAIN, 1015); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Dalaran Intellect" , GOSSIP_SENDER_MAIN, 1020); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Dampen Magic" , GOSSIP_SENDER_MAIN, 1025); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Blessing of Kings" , GOSSIP_SENDER_MAIN, 1030); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Blessing of Might" , GOSSIP_SENDER_MAIN, 1035); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Blessing of Wisdom" , GOSSIP_SENDER_MAIN, 1040); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Divine Spirit" , GOSSIP_SENDER_MAIN, 1045); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Power Word: Fortitude" , GOSSIP_SENDER_MAIN, 1050); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Shadow Protection" , GOSSIP_SENDER_MAIN, 1055); pPlayer->ADD_GOSSIP_ITEM( 7, "<- Main Menu" , GOSSIP_SENDER_MAIN, 5005); pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetObjectGuid()); break; case 2000: pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Gift of the Wild" , GOSSIP_SENDER_MAIN, 2001); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Arcane Brilliance" , GOSSIP_SENDER_MAIN, 2005); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Dalaran Brilliance" , GOSSIP_SENDER_MAIN, 2010); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Greater Blessing of Kings" , GOSSIP_SENDER_MAIN, 2015); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Greater Blessing of Might" , GOSSIP_SENDER_MAIN, 2020); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Greater Blessing of Sanctuary" , GOSSIP_SENDER_MAIN, 2025); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Greater Blessing of Wisdom" , GOSSIP_SENDER_MAIN, 2030); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Prayer of Fortitude" , GOSSIP_SENDER_MAIN, 2035); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Prayer of Shadow Protection" , GOSSIP_SENDER_MAIN, 2040); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Prayer of Spirit" , GOSSIP_SENDER_MAIN, 2045); pPlayer->ADD_GOSSIP_ITEM( 7, "<- Main Menu" , GOSSIP_SENDER_MAIN, 5005); pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetObjectGuid()); break; case 3000: pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Agamaggan's Agility" , GOSSIP_SENDER_MAIN, 3001); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Agamaggan's Strength" , GOSSIP_SENDER_MAIN, 3005); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Armor Magic" , GOSSIP_SENDER_MAIN, 3010); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Armor Penetration" , GOSSIP_SENDER_MAIN, 3015); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Increased Stamina" , GOSSIP_SENDER_MAIN, 3020); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Razorhide" , GOSSIP_SENDER_MAIN, 3025); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Rising Spirit" , GOSSIP_SENDER_MAIN, 3030); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Spirit of the Wind" , GOSSIP_SENDER_MAIN, 3035); pPlayer->ADD_GOSSIP_ITEM( 5, "Buff me Wisdom of Agamaggan" , GOSSIP_SENDER_MAIN, 3040); pPlayer->ADD_GOSSIP_ITEM( 7, "<- Main Menu" , GOSSIP_SENDER_MAIN, 5005); pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetObjectGuid()); break; case 4000: if(GoldSpellEnabled) pPlayer->ADD_GOSSIP_ITEM( 5, "Give me Gold" , GOSSIP_SENDER_MAIN, 4001); pPlayer->ADD_GOSSIP_ITEM( 5, "Give me Soul Shards" , GOSSIP_SENDER_MAIN, 4005); pPlayer->ADD_GOSSIP_ITEM( 5, "Heal me Please" , GOSSIP_SENDER_MAIN, 4010); pPlayer->ADD_GOSSIP_ITEM( 5, "Heal me and party members Please" , GOSSIP_SENDER_MAIN, 4015); pPlayer->ADD_GOSSIP_ITEM( 7, "<- Main Menu" , GOSSIP_SENDER_MAIN, 5005); pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetObjectGuid()); break; case 5005: if (pPlayer->GetTeam() == ALLIANCE) { if(SmallBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Small Buffs ->" , GOSSIP_SENDER_MAIN, 1000); if(GreatBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Great Buffs ->" , GOSSIP_SENDER_MAIN, 2000); if(GameMasterBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "GM Buffs ->" , GOSSIP_SENDER_MAIN, 3000); if(PlayerToolsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Player Tools ->" , GOSSIP_SENDER_MAIN, 4000); pPlayer->ADD_GOSSIP_ITEM( 10, "Remove Resurrect Sickness" , GOSSIP_SENDER_MAIN, 5000); } else { if(SmallBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Small Buffs ->" , GOSSIP_SENDER_MAIN, 1000); if(GreatBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Great Buffs ->" , GOSSIP_SENDER_MAIN, 2000); if(GameMasterBuffsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "GM Buffs ->" , GOSSIP_SENDER_MAIN, 3000); if(PlayerToolsEnabled) pPlayer->ADD_GOSSIP_ITEM( 7, "Player Tools ->" , GOSSIP_SENDER_MAIN, 4000); pPlayer->ADD_GOSSIP_ITEM( 10, "Remove Resurrect Sickness" , GOSSIP_SENDER_MAIN, 5000); } pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE,pCreature->GetObjectGuid()); break; case 1001: // Buff me Mark of the Wild pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48469,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1010: // Buff me Amplify Magic pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,43017,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1015: // Buff me Arcane Intellect pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,42995,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1020: // Buff me Dalaran Intellect pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,61024,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1025: // Buff me Dampen Magic pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,43015,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1030: // Buff me Blessing of Kings pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,20217,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1035: // Buff me Blessing of Might pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48932,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1040: // Buff me Blessing of Wisdom pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48936,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1045: // Buff me Divine Spirit pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48073,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1050: // Buff me Power Word: Fortitude pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48161,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 1055: // Buff me Shadow Protection pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48169,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; //////////////////////////////////////////////////Great Buff/////////////////////////////////////////////////////////////// case 2001: // Buff me Gift of the Wild pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,48470,true); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2005: // Buff me Arcane Brilliance pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,43002,true); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2010: // Buff me Dalaran Brilliance pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,61316,true); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2015: // Buff me Greater Blessing of Kings pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,25898,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2020: // Buff me Greater Blessing of Might pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48934,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2025: // Buff me Greater Blessing of Sanctuary pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,25899,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2030: // Buff me Greater Blessing of Wisdom pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,48938,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2035: // Buff me Prayer of Fortitude pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,48162,true); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2040: // Buff me Prayer of Shadow Protection pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,48170,true); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 2045: // Buff me Prayer of Spirit pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,48074,true); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; //////////////////////////////////////////////////GM Buff/////////////////////////////////////////////////////////////// case 3001: // Buff me Agamaggan's Agility pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,17013,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3005: // Buff me Agamaggan's Strength pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,16612,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3010: // Buff me Armor Magic pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,58453,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3015: // Buff me Armor Penetration pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,34106,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3020: // Buff me Increased Stamina pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,25661,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3025: // Buff me Razorhide pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,16610,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3030: // Buff me Rising Spirit pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,10767,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3035: // Buff me Spirit of the Wind pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,16618,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 3040: // Buff me Wisdom of Agamaggan pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,7764,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; //////////////////////////////////////////////////Player Tools/////////////////////////////////////////////////////////////// case 4001://Give me Gold pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,46642,false); // 5000 gold break; case 4005://Give me Soul Shards pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,24827,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 4010: // Heal me please pPlayer->CLOSE_GOSSIP_MENU(); pCreature->CastSpell(pPlayer,38588,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 4015: // Heal me and party members Please pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,53251,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 4020: // Conjure Refreshment pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,42956,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 4025: // Conjure Mana Gem pPlayer->CLOSE_GOSSIP_MENU(); pPlayer->CastSpell(pPlayer,42985,false); pPlayer->ModifyMoney(-(CUSTOMConfig.GetFloatDefault("BuffsMaster.BuffCost",0))); break; case 5000://Remove Res Sickness if(!pPlayer->HasAura(15007)) { pCreature->MonsterWhisper("You don't have resurrection sickness.", pPlayer, false); pPlayer->CLOSE_GOSSIP_MENU(); return; } pCreature->CastSpell(pPlayer,38588,false); // Healing effect pPlayer->RemoveAurasDueToSpell(15007); pPlayer->CLOSE_GOSSIP_MENU(); break; pPlayer->CLOSE_GOSSIP_MENU(); } }
uint32 Group::RemoveMember(ObjectGuid guid, uint8 method) { //Playerbot mod - if master leaves group, all bots leave group if (!botConfig.GetBoolDefault("PlayerbotAI.DisableBots", false)) { Player* const player = sObjectMgr.GetPlayer(guid); if (player && player->GetPlayerbotMgr()) player->GetPlayerbotMgr()->RemoveAllBotsFromGroup(); } //END Playerbot mod // remove member and change leader (if need) only if strong more 2 members _before_ member remove if (GetMembersCount() > uint32(isBGGroup() ? 1 : 2)) // in BG group case allow 1 members group { bool leaderChanged = _removeMember(guid); if (Player* player = sObjectMgr.GetPlayer(guid)) { // quest related GO state dependent from raid membership if (isRaidGroup()) player->UpdateForQuestWorldObjects(); WorldPacket data; if (method == 1) { data.Initialize(SMSG_GROUP_UNINVITE, 0); player->GetSession()->SendPacket(&data); } // we already removed player from group and in player->GetGroup() is his original group! if (Group* group = player->GetGroup()) { group->SendUpdate(); } else { data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8); data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0); data << uint64(0) << uint32(0) << uint32(0) << uint64(0); player->GetSession()->SendPacket(&data); } _homebindIfInstance(player); } if (leaderChanged) { WorldPacket data(SMSG_GROUP_SET_LEADER, (m_memberSlots.front().name.size() + 1)); data << m_memberSlots.front().name; BroadcastPacket(&data, true); } SendUpdate(); } // if group before remove <= 2 disband it else Disband(true); return m_memberSlots.size(); }
bool ChatHandler::HandlePlayerbotCommand(char* args) { if (!(m_session->GetSecurity() > SEC_PLAYER)) if (botConfig.GetBoolDefault("PlayerbotAI.DisableBots", false)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char *cmd = strtok ((char *) args, " "); char *charname = strtok (NULL, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sAccountMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid == ObjectGuid() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 accountId = sAccountMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; } // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } QueryResult *resultchar = CharacterDatabase.PQuery("SELECT COUNT(*) FROM characters WHERE online = '1' AND account = '%u'", m_session->GetAccountId()); if (resultchar) { Field *fields = resultchar->Fetch(); int acctcharcount = fields[0].GetUInt32(); int maxnum = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (acctcharcount > maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)", maxnum); SetSentErrorMessage(true); delete resultchar; return false; } delete resultchar; } QueryResult *resultlvl = CharacterDatabase.PQuery("SELECT level,name FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field *fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); int maxlvl = botConfig.GetIntDefault("PlayerbotAI.RestrictBotLevel", 80); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); mgr->AddPlayerBot(guid); PSendSysMessage("Bot added successfully."); } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); } else if (cmdStr == "co" || cmdStr == "combatorder") { Unit *target = NULL; char *orderChar = strtok(NULL, " "); if (!orderChar) { PSendSysMessage("|cffff0000Syntax error:|cffffffff .bot co <botName> <order=reset|tank|assist|heal|protect> [targetPlayer]"); SetSentErrorMessage(true); return false; } std::string orderStr = orderChar; if (orderStr == "protect" || orderStr == "assist") { char *targetChar = strtok(NULL, " "); ObjectGuid targetGuid = m_session->GetPlayer()->GetSelectionGuid(); if (!targetChar && targetGuid.IsEmpty()) { PSendSysMessage("|cffff0000Combat orders protect and assist expect a target either by selection or by giving target player in command string!"); SetSentErrorMessage(true); return false; } if (targetChar) { std::string targetStr = targetChar; ObjectGuid targ_guid = sAccountMgr.GetPlayerGuidByName(targetStr.c_str()); targetGuid.Set(targ_guid.GetRawValue()); } target = ObjectAccessor::GetUnit(*m_session->GetPlayer(), targetGuid); if (!target) { PSendSysMessage("|cffff0000Invalid target for combat order protect or assist!"); SetSentErrorMessage(true); return false; } } if (mgr->GetPlayerBot(guid) == NULL) { PSendSysMessage("|cffff0000Bot can not receive combat order because bot does not exist in world."); SetSentErrorMessage(true); return false; } mgr->GetPlayerBot(guid)->GetPlayerbotAI()->SetCombatOrderByStr(orderStr, target); } return true; }