void MailDraft::prepareItems(Player* receiver, SQLTransaction& trans) { if (!m_mailTemplateId || !m_mailTemplateItemsNeed) return; m_mailTemplateItemsNeed = false; Loot mailLoot; // can be empty mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver, true, true); uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver); for (uint32 i = 0; _items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i) { if (LootItem* lootitem = mailLoot.LootItemInSlot(i, receiver)) { if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, receiver)) { item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted AddItem(item); } } } }
void Mail::prepareTemplateItems( Player* receiver ) { if (!mailTemplateId || !items.empty()) return; has_items = true; Loot mailLoot; // can be empty mailLoot.FillLoot(mailTemplateId, LootTemplates_Mail, receiver, true, true); CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("UPDATE mail SET has_items = 1 WHERE id = %u", messageID); uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver); for(uint32 i = 0; items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i) { if (LootItem* lootitem = mailLoot.LootItemInSlot(i, receiver)) { if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, receiver)) { item->SaveToDB(); AddItem(item->GetGUIDLow(), item->GetEntry()); receiver->AddMItem(item); CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", messageID, item->GetGUIDLow(), item->GetEntry(), receiver->GetGUIDLow()); } } } CharacterDatabase.CommitTransaction(); }
void WorldSession::SendMailTemplateTo(Player* receiver, Object* sender, uint8 stationery, uint16 mailTemplateId, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay) { Loot mailLoot; mailLoot.FillLoot(mailTemplateId, LootTemplates_Mail, receiver,true); // fill mail MailItemsInfo mi; // item list preparing uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver); for(uint32 i = 0; mi.size() < MAX_MAIL_ITEMS && i < max_slot; ++i) { if (LootItem* lootitem = mailLoot.LootItemInSlot(i,receiver)) { if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,receiver)) { item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted mi.AddItem(item); } } } WorldSession::SendMailTo(receiver, sender, stationery, receiver->GetGUIDLow(), "", 0, &mi, money, COD, checked,deliver_delay,mailTemplateId); }
void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) { DEBUG_LOG("WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); Player *player = GetPlayer(); ObjectGuid lguid = player->GetLootGUID(); Loot *loot; uint8 lootSlot; 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->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))) { player->SendLootRelease(lguid); return; } loot = &go->loot; break; } case HIGHGUID_ITEM: { Item *pItem = player->GetItemByGuid( lguid ); if (!pItem) { 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: { 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; } ItemPosCountVec dest; uint8 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); 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::HandleAutostoreLootItemOpcode(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data,1); sLog.outDebug("WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); Player *player = GetPlayer(); uint64 lguid = player->GetLootGUID(); Loot *loot; uint8 lootSlot; recv_data >> lootSlot; if (IS_GAMEOBJECT_GUID(lguid)) { 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->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) { player->SendLootRelease(lguid); return; } loot = &go->loot; } else if (IS_ITEM_GUID(lguid)) { Item *pItem = player->GetItemByGuid(lguid); if (!pItem) { player->SendLootRelease(lguid); return; } loot = &pItem->loot; } else if (IS_CORPSE_GUID(lguid)) { Corpse *bones = ObjectAccessor::GetCorpse(*player, lguid); if (!bones) { player->SendLootRelease(lguid); return; } loot = &bones->loot; } else { 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; } 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; } ItemPosCountVec dest; uint8 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); 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) loot->setItemLooted(item, player); --loot->unlootedCount; player->SendNewItem(newitem, uint32(item->count), false, false, true); } else player->SendEquipError(msg, NULL, NULL); }
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: { 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; } Group * group = player->GetGroup(); /* Checking group conditions to be sure the player has the permissions to loot. */ if(group) { Creature * pCreature = player->GetMap()->GetCreature(lguid); switch(group->GetLootMethod()) { case GROUP_LOOT: case NEED_BEFORE_GREED: { if(item->winner && item->winner != player->GetObjectGuid() && !item->is_underthreshold && group->IsRollDoneForItem(pCreature, item)) { player->SendEquipError(EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW, NULL, NULL, item->itemid); return; } break; } case MASTER_LOOT: { if((item->winner && item->winner != player->GetObjectGuid()) || (!item->winner && !item->is_underthreshold && !item->freeforall)) { player->SendEquipError(EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW, NULL, NULL, item->itemid); return; } break; } } } // 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; 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); 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); } else { player->SendEquipError(msg, NULL, NULL, item->itemid); } }
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); }