void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recv_data) { uint8 itemSlot; // slot sent in LOOT_RESPONSE ObjectGuid lootguid; // the guid of the loot object owner ObjectGuid targetGuid; // the item receiver guid recv_data >> lootguid >> itemSlot >> targetGuid; Player* target = ObjectAccessor::FindPlayer(targetGuid); if (!target) { sLog.outError("WorldSession::HandleLootMasterGiveOpcode> Cannot retrieve target %s", targetGuid.GetString().c_str()); return; } DEBUG_LOG("WorldSession::HandleLootMasterGiveOpcode> Giver = %s, Target = %s.", _player->GetGuidStr().c_str(), targetGuid.GetString().c_str()); Loot* pLoot = sLootMgr.GetLoot(_player, lootguid); if (!pLoot) { sLog.outError("WorldSession::HandleLootMasterGiveOpcode> Cannot retrieve loot for player %s", _player->GetGuidStr().c_str()); return; } if (_player->GetObjectGuid() != pLoot->GetMasterLootGuid()) { sLog.outError("WorldSession::HandleLootMasterGiveOpcode> player %s is not the loot master!", _player->GetGuidStr().c_str()); return; } LootItem* lootItem = pLoot->GetLootItemInSlot(itemSlot); if (!lootItem) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } // item may be already looted or another cheating possibility if (lootItem->GetSlotTypeForSharedLoot(_player, pLoot) == MAX_LOOT_SLOT_TYPE) { sLog.outError("HandleAutostoreLootItemOpcode> %s have no right to loot itemId(%u)", _player->GetGuidStr().c_str(), lootItem->itemId); return; } InventoryResult result = pLoot->SendItem(target, lootItem); if (result != EQUIP_ERR_OK) { // send duplicate of error massage to master looter if (LootItem* lootItem = pLoot->GetLootItemInSlot(itemSlot)) _player->SendEquipError(result, nullptr, nullptr, lootItem->itemId); else _player->SendEquipError(result, nullptr, nullptr); return; } }
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data) { uint8 itemSlot; recv_data >> itemSlot; DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM > requesting item in slot %u", uint32(itemSlot)); Loot* loot = sLootMgr.GetLoot(_player); if (!loot) { sLog.outError("HandleAutostoreLootItemOpcode> Cannot retrieve loot for player %s", _player->GetGuidStr().c_str()); return; } ObjectGuid const& lguid = loot->GetLootGuid(); LootItem* lootItem = loot->GetLootItemInSlot(itemSlot); if (!lootItem) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } // item may be blocked by roll system or already looted or another cheating possibility if (lootItem->isBlocked || lootItem->GetSlotTypeForSharedLoot(_player, loot) == MAX_LOOT_SLOT_TYPE) { sLog.outError("HandleAutostoreLootItemOpcode> %s have no right to loot itemId(%u)", _player->GetGuidStr().c_str(), lootItem->itemId); return; } InventoryResult result = loot->SendItem(_player, lootItem); if (result == EQUIP_ERR_OK && lguid.IsItem()) { if (Item* item = _player->GetItemByGuid(lguid)) item->SetLootState(ITEM_LOOT_CHANGED); } if (result == EQUIP_ERR_OK) { if (sRaidStatsMgr.IsTrackingEnabled(RaidStatsEvent::LOOT_PICK, (Unit*)_player, (Unit*)_player) || (loot->GetLootTarget() && loot->GetLootTarget()->GetObjectGuid().IsCreature() && ((Creature*)loot->GetLootTarget())->GetCreatureInfo()->Rank == 3)) { const ItemPrototype* itemProto = ObjectMgr::GetItemPrototype(lootItem->itemId); if (itemProto->Quality >= ITEM_QUALITY_RARE || itemProto->Class == ITEM_CLASS_QUEST) { RaidStatsData raiddata(RaidStatsEvent::LOOT_PICK, _player->GetMap()->GetInstanceId(), _player->GetZoneId()); raiddata.lootpickup.item = lootItem->itemId; raiddata.lootpickup.looter = _player->GetObjectGuid().GetCounter(); raiddata.lootpickup.source = loot->GetLootTarget()->GetObjectGuid().GetCounter(); raiddata.lootpickup.sourceType = (uint32)sRaidStatsMgr.GetRaidStatsType(loot->GetLootTarget()->GetObjectGuid()); sRaidStatsMgr.AddRaidEvent(raiddata); } } } }
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data) { uint8 itemSlot; recv_data >> itemSlot; DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM > requesting item in slot %u", uint32(itemSlot)); Loot* loot = sLootMgr.GetLoot(_player); if (!loot) { sLog.outError("HandleAutostoreLootItemOpcode> Cannot retrieve loot for player %s", _player->GetGuidStr().c_str()); return; } ObjectGuid const& lguid = loot->GetLootGuid(); LootItem* lootItem = loot->GetLootItemInSlot(itemSlot); if (!lootItem) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } // item may be blocked by roll system or already looted or another cheating possibility if (lootItem->isBlocked || lootItem->GetSlotTypeForSharedLoot(_player, loot) == MAX_LOOT_SLOT_TYPE) { sLog.outError("HandleAutostoreLootItemOpcode> %s have no right to loot itemId(%u)", _player->GetGuidStr().c_str(), lootItem->itemId); return; } if (loot->GetLootType() == LOOTITEM_TYPE_CURRENCY) { if (CurrencyTypesEntry const* currencyEntry = sCurrencyTypesStore.LookupEntry(lootItem->itemId)) _player->ModifyCurrencyCount(lootItem->itemId, int32(lootItem->count * currencyEntry->GetPrecision())); loot->NotifyItemRemoved(itemSlot, true); // ToDo: fix this! // --loot->maxSlot; return; } InventoryResult result = loot->SendItem(_player, lootItem); if (result == EQUIP_ERR_OK && lguid.IsItem()) { if (Item* item = _player->GetItemByGuid(lguid)) item->SetLootState(ITEM_LOOT_CHANGED); } }
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data) { uint8 itemSlot; recv_data >> itemSlot; DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM > requesting item in slot %u", uint32(itemSlot)); Loot* loot = sLootMgr.GetLoot(_player); if (!loot) { sLog.outError("HandleAutostoreLootItemOpcode> Cannot retrieve loot for player %s", _player->GetGuidStr().c_str()); return; } ObjectGuid const& lguid = loot->GetLootGuid(); LootItem* lootItem = loot->GetLootItemInSlot(itemSlot); if (!lootItem) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } // item may be blocked by roll system or already looted or another cheating possibility if (lootItem->isBlocked || lootItem->GetSlotTypeForSharedLoot(_player, loot) == MAX_LOOT_SLOT_TYPE) { sLog.outError("HandleAutostoreLootItemOpcode> %s have no right to loot itemId(%u)", _player->GetGuidStr().c_str(), lootItem->itemId); return; } InventoryResult result = loot->SendItem(_player, lootItem); if (result == EQUIP_ERR_OK && lguid.IsItem()) { if (Item* item = _player->GetItemByGuid(lguid)) item->SetLootState(ITEM_LOOT_CHANGED); } }
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()); */ } } }
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()); */ } } }
void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recv_data) { uint8 itemSlot; // slot sent in LOOT_RESPONSE ObjectGuid lootguid; // the guid of the loot object owner ObjectGuid targetGuid; // the item receiver guid recv_data >> lootguid >> itemSlot >> targetGuid; Player* target = ObjectAccessor::FindPlayer(targetGuid); if (!target) { _player->SendLootError(lootguid, LOOT_ERROR_PLAYER_NOT_FOUND); sLog.outError("WorldSession::HandleLootMasterGiveOpcode> Cannot retrieve target %s", targetGuid.GetString().c_str()); return; } DEBUG_LOG("WorldSession::HandleLootMasterGiveOpcode> Giver = %s, Target = %s.", _player->GetGuidStr().c_str(), targetGuid.GetString().c_str()); Loot* pLoot = sLootMgr.GetLoot(_player, lootguid); if (!pLoot) { sLog.outError("WorldSession::HandleLootMasterGiveOpcode> Cannot retrieve loot for player %s", _player->GetGuidStr().c_str()); return; } if (_player->GetObjectGuid() != pLoot->GetMasterLootGuid()) { _player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL); sLog.outError("WorldSession::HandleLootMasterGiveOpcode> player %s is not the loot master!", _player->GetGuidStr().c_str()); return; } if (!_player->IsInGroup(target) || !_player->IsInMap(target)) { _player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER); sLog.outError("WorldSession::HandleLootMasterGiveOpcode> Player %s tried to give an item to ineligible player %s !", _player->GetGuidStr().c_str(), target->GetGuidStr().c_str()); return; } LootItem* lootItem = pLoot->GetLootItemInSlot(itemSlot); if (!lootItem) { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } // item may be already looted or another cheating possibility if (lootItem->GetSlotTypeForSharedLoot(_player, pLoot) == MAX_LOOT_SLOT_TYPE) { sLog.outError("HandleAutostoreLootItemOpcode> %s have no right to loot itemId(%u)", _player->GetGuidStr().c_str(), lootItem->itemId); return; } if (!lootItem->IsAllowed(target, pLoot)) { _player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM, nullptr, nullptr); return; } InventoryResult result = pLoot->SendItem(target, lootItem); if (result != EQUIP_ERR_OK) { if (result == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS) _player->SendLootError(lootguid, LOOT_ERROR_MASTER_UNIQUE_ITEM); else if (result == EQUIP_ERR_INVENTORY_FULL) _player->SendLootError(lootguid, LOOT_ERROR_MASTER_INV_FULL); else _player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER); } }