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 WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) { DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); Player *player = GetPlayer(); ObjectGuid lguid = player->GetLootGUID(); Loot *loot; uint8 lootSlot; Item* pItem = NULL; recv_data >> lootSlot; switch( lguid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject *go = player->GetMap()->GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || ((go->GetOwnerGuid() != _player->GetObjectGuid() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))) { player->SendLootRelease(lguid); return; } loot = &go->loot; break; } case HIGHGUID_ITEM: { pItem = player->GetItemByGuid( lguid ); if (!pItem || !pItem->HasGeneratedLoot()) { player->SendLootRelease(lguid); return; } loot = &pItem->loot; break; } case HIGHGUID_CORPSE: { Corpse *bones = player->GetMap()->GetCorpse(lguid); if (!bones) { player->SendLootRelease(lguid); return; } loot = &bones->loot; break; } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); if( !ok_loot || !pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) { player->SendLootRelease(lguid); return; } loot = &pCreature->loot; break; } default: { sLog.outError("%s is unsupported for looting.",lguid.GetString().c_str()); return; } } QuestItem *qitem = NULL; QuestItem *ffaitem = NULL; QuestItem *conditem = NULL; LootItem *item = loot->LootItemInSlot(lootSlot,player,&qitem,&ffaitem,&conditem); if(!item) { player->SendEquipError( EQUIP_ERR_ALREADY_LOOTED, NULL, NULL ); return; } // questitems use the blocked field for other purposes if (!qitem && item->is_blocked) { player->SendLootRelease(lguid); return; } if (pItem) pItem->SetLootState(ITEM_LOOT_CHANGED); ItemPosCountVec dest; uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count ); if ( msg == EQUIP_ERR_OK ) { AllowedLooterSet* looters = item->GetAllowedLooters(); Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId, (looters->size() > 1) ? looters : NULL); if (qitem) { qitem->is_looted = true; //freeforall is 1 if everyone's supposed to get the quest item. if (item->freeforall || loot->GetPlayerQuestItems().size() == 1) player->SendNotifyLootItemRemoved(lootSlot); else loot->NotifyQuestItemRemoved(qitem->index); } else { if (ffaitem) { //freeforall case, notify only one player of the removal ffaitem->is_looted=true; player->SendNotifyLootItemRemoved(lootSlot); } else { //not freeforall, notify everyone if(conditem) conditem->is_looted=true; loot->NotifyItemRemoved(lootSlot); } } //if only one person is supposed to loot the item, then set it to looted if (!item->freeforall) item->is_looted = true; --loot->unlootedCount; player->SendNewItem(newitem, uint32(item->count), false, false, true); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); } else player->SendEquipError( msg, NULL, NULL, item->itemid ); }
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); } }
void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: %s", LookupOpcodeName(recv_data.GetOpcode())); Player* player = GetPlayer(); ObjectGuid lguid = player->GetLootGuid(); Loot* loot; uint8 lootSlot; Item* pItem = NULL; recv_data >> lootSlot; switch (lguid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject* go = player->GetMap()->GetGameObject(lguid); // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO if (!go || ((go->GetOwnerGuid() != _player->GetObjectGuid() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player, INTERACTION_DISTANCE))) { player->SendLootRelease(lguid); return; } loot = &go->loot; break; } case HIGHGUID_ITEM: { pItem = player->GetItemByGuid(lguid); if (!pItem || !pItem->HasGeneratedLoot()) { player->SendLootRelease(lguid); return; } loot = &pItem->loot; break; } case HIGHGUID_CORPSE: { Corpse* bones = player->GetMap()->GetCorpse(lguid); if (!bones) { player->SendLootRelease(lguid); return; } loot = &bones->loot; break; } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass() == CLASS_ROGUE && pCreature->lootForPickPocketed); if (!ok_loot || !pCreature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { player->SendLootRelease(lguid); return; } loot = &pCreature->loot; break; } default: { sLog.outError("%s is unsupported for looting.", lguid.GetString().c_str()); return; } } QuestItem* qitem = NULL; QuestItem* ffaitem = NULL; QuestItem* conditem = NULL; QuestItem* currency = NULL; LootItem* item = loot->LootItemInSlot(lootSlot, player, &qitem, &ffaitem, &conditem, ¤cy); if (!item) { player->SendEquipError(EQUIP_ERR_ALREADY_LOOTED, NULL, NULL); return; } // questitems use the blocked field for other purposes if (!qitem && item->is_blocked) { player->SendLootRelease(lguid); return; } if (pItem) pItem->SetLootState(ITEM_LOOT_CHANGED); if (currency) { if (CurrencyTypesEntry const * currencyEntry = sCurrencyTypesStore.LookupEntry(item->itemid)) player->ModifyCurrencyCount(item->itemid, int32(item->count * currencyEntry->GetPrecision())); player->SendNotifyLootItemRemoved(lootSlot, true); currency->is_looted = true; --loot->unlootedCount; return; } ItemPosCountVec dest; InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item->itemid, item->count); if (msg == EQUIP_ERR_OK) { Item* newitem = player->StoreNewItem(dest, item->itemid, true, item->randomPropertyId, item->GetAllowedLooters()); if (qitem) { qitem->is_looted = true; // freeforall is 1 if everyone's supposed to get the quest item. if (item->freeforall || loot->GetPlayerQuestItems().size() == 1) player->SendNotifyLootItemRemoved(lootSlot); else loot->NotifyQuestItemRemoved(qitem->index); } else { if (ffaitem) { // freeforall case, notify only one player of the removal ffaitem->is_looted = true; player->SendNotifyLootItemRemoved(lootSlot); } else { // not freeforall, notify everyone if (conditem) conditem->is_looted = true; loot->NotifyItemRemoved(lootSlot); } } // if only one person is supposed to loot the item, then set it to looted if (!item->freeforall) item->is_looted = true; --loot->unlootedCount; player->SendNewItem(newitem, uint32(item->count), false, false, true); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); if (ItemPrototype const* proto = sObjectMgr.GetItemPrototype(item->itemid)) if (proto->Quality > ITEM_QUALITY_EPIC || (proto->Quality == ITEM_QUALITY_EPIC && proto->ItemLevel >= MinNewsItemLevel[sWorld.getConfig(CONFIG_UINT32_EXPANSION)])) if (Guild* guild = sGuildMgr.GetGuildById(player->GetGuildId())) guild->LogNewsEvent(GUILD_NEWS_ITEM_LOOTED, time(NULL), player->GetObjectGuid(), 0, item->itemid); } else player->SendEquipError(msg, NULL, NULL, item->itemid); }