AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Loot Struct Reference

#include "LootMgr.h"

Public Member Functions

QuestItemMap const & GetPlayerQuestItems () const
 
QuestItemMap const & GetPlayerFFAItems () const
 
QuestItemMap const & GetPlayerNonQuestNonFFAConditionalItems () const
 
 Loot (uint32 _gold=0)
 
 ~Loot ()
 
void addLootValidatorRef (LootValidatorRef *pLootValidatorRef)
 
void clear ()
 
bool empty () const
 
bool isLooted () const
 
void NotifyItemRemoved (uint8 lootIndex)
 
void NotifyQuestItemRemoved (uint8 questIndex)
 
void NotifyMoneyRemoved ()
 
void AddLooter (ObjectGuid GUID)
 
void RemoveLooter (ObjectGuid GUID)
 
void generateMoneyLoot (uint32 minAmount, uint32 maxAmount)
 
bool FillLoot (uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT, WorldObject *lootSource=nullptr)
 
void AddItem (LootStoreItem const &item)
 
LootItemLootItemInSlot (uint32 lootslot, Player *player, QuestItem **qitem=nullptr, QuestItem **ffaitem=nullptr, QuestItem **conditem=nullptr)
 
uint32 GetMaxSlotInLootFor (Player *player) const
 
bool hasItemForAll () const
 
bool hasItemFor (Player *player) const
 
bool hasOverThresholdItem () const
 
void FillNotNormalLootFor (Player *player)
 

Public Attributes

std::vector< LootItemitems
 
std::vector< LootItemquest_items
 
uint32 gold
 
uint8 unlootedCount {0}
 
ObjectGuid roundRobinPlayer
 
ObjectGuid lootOwnerGUID
 
LootType loot_type {LOOT_NONE}
 
ObjectGuid containerGUID
 
ObjectGuid sourceWorldObjectGUID
 
GameObjectsourceGameObject {nullptr}
 

Private Types

typedef GuidSet PlayersLootingSet
 

Private Member Functions

QuestItemListFillFFALoot (Player *player)
 
QuestItemListFillQuestLoot (Player *player)
 
QuestItemListFillNonQuestNonFFAConditionalLoot (Player *player)
 

Private Attributes

PlayersLootingSet PlayersLooting
 
QuestItemMap PlayerQuestItems
 
QuestItemMap PlayerFFAItems
 
QuestItemMap PlayerNonQuestNonFFAConditionalItems
 
LootValidatorRefMgr i_LootValidatorRefMgr
 

Friends

ByteBufferoperator<< (ByteBuffer &b, LootView const &lv)
 

Detailed Description

Member Typedef Documentation

◆ PlayersLootingSet

Constructor & Destructor Documentation

◆ Loot()

Loot::Loot ( uint32  _gold = 0)
inline
333: gold(_gold) { }
uint32 gold
Definition: LootMgr.h:322

◆ ~Loot()

Loot::~Loot ( )
inline
334{ clear(); }
void clear()
Definition: LootMgr.h:343

References clear().

Member Function Documentation

◆ AddItem()

void Loot::AddItem ( LootStoreItem const &  item)
512{
513 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
514 if (!proto)
515 return;
516
517 uint32 count = urand(item.mincount, item.maxcount);
518 uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0);
519
520 std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items;
521 uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS;
522
523 for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i)
524 {
525 LootItem generatedLoot(item);
526 generatedLoot.count = std::min(count, proto->GetMaxStackSize());
527 generatedLoot.itemIndex = lootItems.size();
528 lootItems.push_back(generatedLoot);
529 count -= proto->GetMaxStackSize();
530
531 // In some cases, a dropped item should be visible/lootable only for some players in group
532 bool canSeeItemInLootWindow = false;
533 if (auto player = ObjectAccessor::FindPlayer(lootOwnerGUID))
534 {
535 if (auto group = player->GetGroup())
536 {
537 for (auto itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
538 {
539 if (auto member = itr->GetSource())
540 {
541 if (generatedLoot.AllowedForPlayer(member, sourceWorldObjectGUID))
542 {
543 canSeeItemInLootWindow = true;
544 break;
545 }
546 }
547 }
548 }
549 else if (generatedLoot.AllowedForPlayer(player, sourceWorldObjectGUID))
550 {
551 canSeeItemInLootWindow = true;
552 }
553 }
554
555 if (!canSeeItemInLootWindow)
556 {
557 LOG_DEBUG("loot", "Skipping ++unlootedCount for unlootable item: {}", item.itemid);
558 continue;
559 }
560
561 // non-conditional one-player only items are counted here,
562 // free for all items are counted in FillFFALoot(),
563 // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
564 if (!item.needs_quest && item.conditions.empty() && !proto->HasFlag(ITEM_FLAG_MULTI_DROP))
566 }
567}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:169
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
std::uint32_t uint32
Definition: Define.h:107
#define sObjectMgr
Definition: ObjectMgr.h:1635
@ ITEM_FLAG_MULTI_DROP
Definition: ItemTemplate.h:158
#define MAX_NR_QUEST_ITEMS
Definition: LootMgr.h:53
#define MAX_NR_LOOT_ITEMS
Definition: LootMgr.h:51
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:245
Definition: ItemTemplate.h:619
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
Definition: LootMgr.h:154
ObjectGuid sourceWorldObjectGUID
Definition: LootMgr.h:330
uint8 unlootedCount
Definition: LootMgr.h:323
ObjectGuid lootOwnerGUID
Definition: LootMgr.h:325
std::vector< LootItem > items
Definition: LootMgr.h:320
std::vector< LootItem > quest_items
Definition: LootMgr.h:321

References LootItem::AllowedForPlayer(), LootStoreItem::conditions, LootItem::count, ObjectAccessor::FindPlayer(), Player::GetGroup(), ItemTemplate::GetMaxStackSize(), ItemTemplate::HasFlag(), ITEM_FLAG_MULTI_DROP, LootStoreItem::itemid, LootItem::itemIndex, items, LOG_DEBUG, lootOwnerGUID, MAX_NR_LOOT_ITEMS, MAX_NR_QUEST_ITEMS, LootStoreItem::maxcount, LootStoreItem::mincount, LootStoreItem::needs_quest, quest_items, sObjectMgr, sourceWorldObjectGUID, unlootedCount, and urand().

Referenced by LootTemplate::Process(), and LootTemplate::LootGroup::Process().

◆ AddLooter()

void Loot::AddLooter ( ObjectGuid  GUID)
inline
373{ PlayersLooting.insert(GUID); }
PlayersLootingSet PlayersLooting
Definition: LootMgr.h:395

References PlayersLooting.

Referenced by Player::SendLoot().

◆ addLootValidatorRef()

void Loot::addLootValidatorRef ( LootValidatorRef pLootValidatorRef)
inline
338 {
339 i_LootValidatorRefMgr.insertFirst(pLootValidatorRef);
340 }
void insertFirst(LinkedListElement *pElem)
Definition: LinkedList.h:105
LootValidatorRefMgr i_LootValidatorRefMgr
Definition: LootMgr.h:401

References i_LootValidatorRefMgr, and LinkedListHead::insertFirst().

Referenced by Roll::targetObjectBuildLink().

◆ clear()

void Loot::clear ( )
inline
344 {
345 for (QuestItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
346 delete itr->second;
347 PlayerQuestItems.clear();
348
349 for (QuestItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
350 delete itr->second;
351 PlayerFFAItems.clear();
352
353 for (QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
354 delete itr->second;
356
357 PlayersLooting.clear();
358 items.clear();
359 quest_items.clear();
360 gold = 0;
361 unlootedCount = 0;
365 }
@ LOOT_NONE
Definition: LootMgr.h:78
void clearReferences()
Definition: RefMgr.h:42
void Clear()
Definition: ObjectGuid.h:138
QuestItemMap PlayerNonQuestNonFFAConditionalItems
Definition: LootMgr.h:398
QuestItemMap PlayerQuestItems
Definition: LootMgr.h:396
ObjectGuid roundRobinPlayer
Definition: LootMgr.h:324
QuestItemMap PlayerFFAItems
Definition: LootMgr.h:397
LootType loot_type
Definition: LootMgr.h:326

References ObjectGuid::Clear(), RefMgr< TO, FROM >::clearReferences(), gold, i_LootValidatorRefMgr, items, LOOT_NONE, loot_type, PlayerFFAItems, PlayerNonQuestNonFFAConditionalItems, PlayerQuestItems, PlayersLooting, quest_items, roundRobinPlayer, and unlootedCount.

Referenced by NPCStaveQuestAI::ClearLootIfUnfair(), boss_high_king_maulgar::DoAction(), WorldSession::DoLootRelease(), GameObject::GetFishLoot(), GameObject::GetFishLootJunk(), Unit::Kill(), Creature::RemoveCorpse(), Creature::Respawn(), Player::SendLoot(), boss_priestess_delrissa::SummonedCreatureDies(), GameObject::Update(), and ~Loot().

◆ empty()

bool Loot::empty ( ) const
inline

◆ FillFFALoot()

QuestItemList * Loot::FillFFALoot ( Player player)
private
664{
665 QuestItemList* ql = new QuestItemList();
666
667 for (uint8 i = 0; i < items.size(); ++i)
668 {
669 LootItem& item = items[i];
670 if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
671 {
672 ql->push_back(QuestItem(i));
674 }
675 }
676 if (ql->empty())
677 {
678 delete ql;
679 return nullptr;
680 }
681
682 PlayerFFAItems[player->GetGUID()] = ql;
683 return ql;
684}
std::uint8_t uint8
Definition: Define.h:109
std::vector< QuestItem > QuestItemList
Definition: LootMgr.h:198
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:112
bool AllowedForPlayer(Player const *player, ObjectGuid source) const
Definition: LootMgr.cpp:416
bool is_looted
Definition: LootMgr.h:163
bool freeforall
Definition: LootMgr.h:165
Definition: LootMgr.h:185
ObjectGuid containerGUID
Definition: LootMgr.h:329

References LootItem::AllowedForPlayer(), containerGUID, LootItem::freeforall, Object::GetGUID(), LootItem::is_looted, items, PlayerFFAItems, and unlootedCount.

Referenced by FillNotNormalLootFor().

◆ FillLoot()

bool Loot::FillLoot ( uint32  lootId,
LootStore const &  store,
Player lootOwner,
bool  personal,
bool  noEmptyError = false,
uint16  lootMode = LOOT_MODE_DEFAULT,
WorldObject lootSource = nullptr 
)
571{
572 // Must be provided
573 if (!lootOwner)
574 return false;
575
576 lootOwnerGUID = lootOwner->GetGUID();
577
578 LootTemplate const* tab = store.GetLootFor(lootId);
579
580 if (!tab)
581 {
582 if (!noEmptyError)
583 LOG_ERROR("sql.sql", "Table '{}' loot id #{} used but it doesn't have records.", store.GetName(), lootId);
584 return false;
585 }
586
587 items.reserve(MAX_NR_LOOT_ITEMS);
589
590 // Initial group is 0, top level set to True
591 tab->Process(*this, store, lootMode, lootOwner, 0, true); // Processing is done there, callback via Loot::AddItem()
592
593 sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
594
595 // Setting access rights for group loot case
596 Group* group = lootOwner->GetGroup();
597 if (!personal && group)
598 {
599 roundRobinPlayer = lootOwner->GetGUID();
600
601 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
602 {
603 if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
604 {
605 if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
606 {
607 FillNotNormalLootFor(player);
608 }
609 }
610 }
611
612 for (uint8 i = 0; i < items.size(); ++i)
613 {
614 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid))
615 if (proto->Quality < uint32(group->GetLootThreshold()))
616 items[i].is_underthreshold = true;
617 }
618 }
619 // ... for personal loot
620 else
621 FillNotNormalLootFor(lootOwner);
622
623 return true;
624}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
#define sScriptMgr
Definition: ScriptMgr.h:709
Definition: Player.h:1081
Group * GetGroup()
Definition: Player.h:2468
Definition: Group.h:169
ItemQualities GetLootThreshold() const
Definition: Group.cpp:2327
GroupReference * GetFirstMember()
Definition: Group.h:243
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: LootMgr.h:245
void Process(Loot &loot, LootStore const &store, uint16 lootMode, Player const *player, uint8 groupId=0, bool isTopLevel=true) const
Definition: LootMgr.cpp:1698
void FillNotNormalLootFor(Player *player)
Definition: LootMgr.cpp:626

References FillNotNormalLootFor(), Group::GetFirstMember(), Player::GetGroup(), Object::GetGUID(), LootStore::GetLootFor(), Group::GetLootThreshold(), LootStore::GetName(), Player::IsAtLootRewardDistance(), items, LOG_ERROR, lootOwnerGUID, MAX_NR_LOOT_ITEMS, MAX_NR_QUEST_ITEMS, GroupReference::next(), LootTemplate::Process(), quest_items, roundRobinPlayer, sObjectMgr, and sScriptMgr.

Referenced by Player::AutoStoreLoot(), Group::CountTheRoll(), boss_high_king_maulgar::DoAction(), GameObject::GetFishLoot(), GameObject::GetFishLootJunk(), Unit::Kill(), MailDraft::prepareItems(), Player::SendLoot(), and boss_priestess_delrissa::SummonedCreatureDies().

◆ FillNonQuestNonFFAConditionalLoot()

QuestItemList * Loot::FillNonQuestNonFFAConditionalLoot ( Player player)
private
738{
739 QuestItemList* ql = new QuestItemList();
740
741 for (uint8 i = 0; i < items.size(); ++i)
742 {
743 LootItem& item = items[i];
744
745 if (!item.is_looted && !item.freeforall && item.AllowedForPlayer(player, sourceWorldObjectGUID))
746 {
747 item.AddAllowedLooter(player);
748
749 if (!item.conditions.empty())
750 {
751 ql->push_back(QuestItem(i));
752 if (!item.is_counted)
753 {
755 item.is_counted = true;
756 }
757 }
758 }
759 }
760 if (ql->empty())
761 {
762 delete ql;
763 return nullptr;
764 }
765
767 return ql;
768}
void AddAllowedLooter(Player const *player)
Definition: LootMgr.cpp:501
ConditionList conditions
Definition: LootMgr.h:159
bool is_counted
Definition: LootMgr.h:167

References LootItem::AddAllowedLooter(), LootItem::AllowedForPlayer(), LootItem::conditions, LootItem::freeforall, Object::GetGUID(), LootItem::is_counted, LootItem::is_looted, items, PlayerNonQuestNonFFAConditionalItems, sourceWorldObjectGUID, and unlootedCount.

Referenced by FillNotNormalLootFor().

◆ FillNotNormalLootFor()

void Loot::FillNotNormalLootFor ( Player player)
627{
628 ObjectGuid playerGuid = player->GetGUID();
629
630 QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(playerGuid);
631 if (qmapitr == PlayerQuestItems.end())
632 FillQuestLoot(player);
633
634 qmapitr = PlayerFFAItems.find(playerGuid);
635 if (qmapitr == PlayerFFAItems.end())
636 FillFFALoot(player);
637
638 qmapitr = PlayerNonQuestNonFFAConditionalItems.find(playerGuid);
639 if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
641
642 // Process currency items
643 uint32 max_slot = GetMaxSlotInLootFor(player);
644 LootItem const* item = nullptr;
645 uint32 itemsSize = uint32(items.size());
646 for (uint32 i = 0; i < max_slot; ++i)
647 {
648 if (i < items.size())
649 item = &items[i];
650 else
651 item = &quest_items[i - itemsSize];
652
653 if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player, sourceWorldObjectGUID))
654 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
655 if (proto->IsCurrencyToken())
656 {
657 InventoryResult msg;
658 player->StoreLootItem(i, this, msg);
659 }
660 }
661}
InventoryResult
Definition: Item.h:46
Definition: ObjectGuid.h:118
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition: Player.cpp:13551
uint32 itemid
Definition: LootMgr.h:155
QuestItemList * FillQuestLoot(Player *player)
Definition: LootMgr.cpp:686
uint32 GetMaxSlotInLootFor(Player *player) const
Definition: LootMgr.cpp:915
QuestItemList * FillFFALoot(Player *player)
Definition: LootMgr.cpp:663
QuestItemList * FillNonQuestNonFFAConditionalLoot(Player *player)
Definition: LootMgr.cpp:737

References LootItem::AllowedForPlayer(), FillFFALoot(), FillNonQuestNonFFAConditionalLoot(), FillQuestLoot(), LootItem::freeforall, Object::GetGUID(), GetMaxSlotInLootFor(), LootItem::is_looted, LootItem::itemid, items, PlayerFFAItems, PlayerNonQuestNonFFAConditionalItems, PlayerQuestItems, quest_items, sObjectMgr, sourceWorldObjectGUID, and Player::StoreLootItem().

Referenced by FillLoot(), and LootItemStorage::LoadStoredLoot().

◆ FillQuestLoot()

QuestItemList * Loot::FillQuestLoot ( Player player)
private
687{
688 if (items.size() == MAX_NR_LOOT_ITEMS)
689 return nullptr;
690
691 QuestItemList* ql = new QuestItemList();
692
694
695 for (uint8 i = 0; i < quest_items.size(); ++i)
696 {
697 LootItem& item = quest_items[i];
698
699 sScriptMgr->OnBeforeFillQuestLootItem(player, item);
700
701 // Quest item is not free for all and is already assigned to another player
702 // or player doesn't need it
703 if (item.is_blocked || !item.AllowedForPlayer(player, sourceWorldObjectGUID))
704 {
705 continue;
706 }
707
708 // Player is not the loot owner, and loot owner still needs this quest item
709 if (!item.freeforall &&
710 lootOwner && lootOwner != player &&
712 {
713 continue;
714 }
715
716 ql->push_back(QuestItem(i));
718
719 if (!item.freeforall)
720 {
721 item.is_blocked = true;
722 }
723
724 if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
725 break;
726 }
727 if (ql->empty())
728 {
729 delete ql;
730 return nullptr;
731 }
732
733 PlayerQuestItems[player->GetGUID()] = ql;
734 return ql;
735}
bool is_blocked
Definition: LootMgr.h:164

References LootItem::AllowedForPlayer(), ObjectAccessor::FindPlayer(), LootItem::freeforall, Object::GetGUID(), LootItem::is_blocked, items, MAX_NR_LOOT_ITEMS, PlayerQuestItems, quest_items, roundRobinPlayer, sourceWorldObjectGUID, sScriptMgr, and unlootedCount.

Referenced by FillNotNormalLootFor().

◆ generateMoneyLoot()

void Loot::generateMoneyLoot ( uint32  minAmount,
uint32  maxAmount 
)
838{
839 if (maxAmount > 0)
840 {
841 if (maxAmount <= minAmount)
842 gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY));
843 else if ((maxAmount - minAmount) < 32700)
844 gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY));
845 else
846 gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8;
847 }
848}
@ RATE_DROP_MONEY
Definition: IWorld.h:465
#define sWorld
Definition: World.h:443

References gold, RATE_DROP_MONEY, sWorld, and urand().

Referenced by Unit::Kill(), and Player::SendLoot().

◆ GetMaxSlotInLootFor()

uint32 Loot::GetMaxSlotInLootFor ( Player player) const
916{
917 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
918 return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
919}

References Object::GetGUID(), items, and PlayerQuestItems.

Referenced by Player::AutoStoreLoot(), Group::CountTheRoll(), FillNotNormalLootFor(), and MailDraft::prepareItems().

◆ GetPlayerFFAItems()

QuestItemMap const & Loot::GetPlayerFFAItems ( ) const
inline
317{ return PlayerFFAItems; }

References PlayerFFAItems.

Referenced by hasItemFor().

◆ GetPlayerNonQuestNonFFAConditionalItems()

QuestItemMap const & Loot::GetPlayerNonQuestNonFFAConditionalItems ( ) const
inline

◆ GetPlayerQuestItems()

QuestItemMap const & Loot::GetPlayerQuestItems ( ) const
inline
316{ return PlayerQuestItems; }

References PlayerQuestItems.

Referenced by hasItemFor(), and Player::StoreLootItem().

◆ hasItemFor()

bool Loot::hasItemFor ( Player player) const
937{
938 QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems();
939 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID());
940 if (q_itr != lootPlayerQuestItems.end())
941 {
942 QuestItemList* q_list = q_itr->second;
943 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
944 {
945 const LootItem& item = quest_items[qi->index];
946 if (!qi->is_looted && !item.is_looted)
947 return true;
948 }
949 }
950
951 QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems();
952 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID());
953 if (ffa_itr != lootPlayerFFAItems.end())
954 {
955 QuestItemList* ffa_list = ffa_itr->second;
956 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
957 {
958 const LootItem& item = items[fi->index];
959 if (!fi->is_looted && !item.is_looted)
960 return true;
961 }
962 }
963
964 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
965 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
966 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
967 {
968 QuestItemList* conditional_list = nn_itr->second;
969 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
970 {
971 const LootItem& item = items[ci->index];
972 if (!ci->is_looted && !item.is_looted)
973 return true;
974 }
975 }
976
977 return false;
978}
std::map< ObjectGuid, QuestItemList * > QuestItemMap
Definition: LootMgr.h:200
QuestItemMap const & GetPlayerQuestItems() const
Definition: LootMgr.h:316
QuestItemMap const & GetPlayerFFAItems() const
Definition: LootMgr.h:317
QuestItemMap const & GetPlayerNonQuestNonFFAConditionalItems() const
Definition: LootMgr.h:318

References Object::GetGUID(), GetPlayerFFAItems(), GetPlayerNonQuestNonFFAConditionalItems(), GetPlayerQuestItems(), LootItem::is_looted, items, and quest_items.

Referenced by Player::isAllowedToLoot().

◆ hasItemForAll()

bool Loot::hasItemForAll ( ) const
922{
923 // Gold is always lootable
924 if (gold)
925 {
926 return true;
927 }
928
929 for (LootItem const& item : items)
930 if (!item.is_looted && !item.freeforall && item.conditions.empty())
931 return true;
932 return false;
933}

References gold, and items.

Referenced by Player::isAllowedToLoot().

◆ hasOverThresholdItem()

bool Loot::hasOverThresholdItem ( ) const
982{
983 for (uint8 i = 0; i < items.size(); ++i)
984 {
985 if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall)
986 return true;
987 }
988
989 return false;
990}

References items.

Referenced by Player::isAllowedToLoot(), and Group::SendLooter().

◆ isLooted()

◆ LootItemInSlot()

LootItem * Loot::LootItemInSlot ( uint32  lootslot,
Player player,
QuestItem **  qitem = nullptr,
QuestItem **  ffaitem = nullptr,
QuestItem **  conditem = nullptr 
)
851{
852 LootItem* item = nullptr;
853 bool is_looted = true;
854 if (lootSlot >= items.size())
855 {
856 uint32 questSlot = lootSlot - items.size();
857 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
858 if (itr != PlayerQuestItems.end() && questSlot < itr->second->size())
859 {
860 QuestItem* qitem2 = &itr->second->at(questSlot);
861 if (qitem)
862 *qitem = qitem2;
863 item = &quest_items[qitem2->index];
864 if (item->follow_loot_rules && !item->AllowedForPlayer(player, sourceWorldObjectGUID)) // pussywizard: such items (follow_loot_rules) are added to every player, but not everyone is allowed, check it here
865 return nullptr;
866 is_looted = qitem2->is_looted;
867 }
868 }
869 else
870 {
871 item = &items[lootSlot];
872 is_looted = item->is_looted;
873 if (item->freeforall)
874 {
875 QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID());
876 if (itr != PlayerFFAItems.end())
877 {
878 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
879 if (iter->index == lootSlot)
880 {
881 QuestItem* ffaitem2 = (QuestItem*) & (*iter);
882 if (ffaitem)
883 *ffaitem = ffaitem2;
884 is_looted = ffaitem2->is_looted;
885 break;
886 }
887 }
888 }
889 else if (!item->conditions.empty())
890 {
891 QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
893 {
894 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
895 {
896 if (iter->index == lootSlot)
897 {
898 QuestItem* conditem2 = (QuestItem*) & (*iter);
899 if (conditem)
900 *conditem = conditem2;
901 is_looted = conditem2->is_looted;
902 break;
903 }
904 }
905 }
906 }
907 }
908
909 if (is_looted)
910 return nullptr;
911
912 return item;
913}
bool follow_loot_rules
Definition: LootMgr.h:169
uint8 index
Definition: LootMgr.h:186
bool is_looted
Definition: LootMgr.h:187

References LootItem::AllowedForPlayer(), LootItem::conditions, LootItem::follow_loot_rules, LootItem::freeforall, Object::GetGUID(), QuestItem::index, LootItem::is_looted, QuestItem::is_looted, items, PlayerFFAItems, PlayerNonQuestNonFFAConditionalItems, PlayerQuestItems, quest_items, and sourceWorldObjectGUID.

Referenced by Player::AutoStoreLoot(), Group::CountTheRoll(), MailDraft::prepareItems(), and Player::StoreLootItem().

◆ NotifyItemRemoved()

void Loot::NotifyItemRemoved ( uint8  lootIndex)
773{
774 // notify all players that are looting this that the item was removed
775 // convert the index to the slot the player sees
776 PlayersLootingSet::iterator i_next;
777 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
778 {
779 i_next = i;
780 ++i_next;
781 if (Player* player = ObjectAccessor::FindPlayer(*i))
782 player->SendNotifyLootItemRemoved(lootIndex);
783 else
784 PlayersLooting.erase(i);
785 }
786}

References ObjectAccessor::FindPlayer(), PlayersLooting, and Player::SendNotifyLootItemRemoved().

Referenced by Group::CountTheRoll(), WorldSession::HandleAutostoreLootItemOpcode(), WorldSession::HandleLootMasterGiveOpcode(), and Player::StoreLootItem().

◆ NotifyMoneyRemoved()

void Loot::NotifyMoneyRemoved ( )
789{
790 // notify all players that are looting this that the money was removed
791 PlayersLootingSet::iterator i_next;
792 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
793 {
794 i_next = i;
795 ++i_next;
796 if (Player* player = ObjectAccessor::FindPlayer(*i))
797 player->SendNotifyLootMoneyRemoved();
798 else
799 PlayersLooting.erase(i);
800 }
801}

References ObjectAccessor::FindPlayer(), PlayersLooting, and Player::SendNotifyLootMoneyRemoved().

Referenced by WorldSession::HandleLootMoneyOpcode().

◆ NotifyQuestItemRemoved()

void Loot::NotifyQuestItemRemoved ( uint8  questIndex)
804{
805 // when a free for all questitem is looted
806 // all players will get notified of it being removed
807 // (other questitems can be looted by each group member)
808 // bit inefficient but isn't called often
809
810 PlayersLootingSet::iterator i_next;
811 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
812 {
813 i_next = i;
814 ++i_next;
815 if (Player* player = ObjectAccessor::FindPlayer(*i))
816 {
817 QuestItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID());
818 if (pq != PlayerQuestItems.end() && pq->second)
819 {
820 // find where/if the player has the given item in it's vector
821 QuestItemList& pql = *pq->second;
822
823 uint8 j;
824 for (j = 0; j < pql.size(); ++j)
825 if (pql[j].index == questIndex)
826 break;
827
828 if (j < pql.size())
829 player->SendNotifyLootItemRemoved(items.size() + j);
830 }
831 }
832 else
833 PlayersLooting.erase(i);
834 }
835}

References ObjectAccessor::FindPlayer(), Object::GetGUID(), items, PlayerQuestItems, PlayersLooting, and Player::SendNotifyLootItemRemoved().

Referenced by Player::StoreLootItem().

◆ RemoveLooter()

void Loot::RemoveLooter ( ObjectGuid  GUID)
inline
374{ PlayersLooting.erase(GUID); }

References PlayersLooting.

Referenced by WorldSession::DoLootRelease().

Friends And Related Function Documentation

◆ operator<<

ByteBuffer & operator<< ( ByteBuffer b,
LootView const &  lv 
)
friend
1004{
1005 if (lv.permission == NONE_PERMISSION)
1006 {
1007 b << uint32(0); //gold
1008 b << uint8(0); // item count
1009 return b; // nothing output more
1010 }
1011
1012 Loot& l = lv.loot;
1013
1014 uint8 itemsShown = 0;
1015
1016 b << uint32(l.gold); //gold
1017
1018 std::size_t count_pos = b.wpos(); // pos of item count byte
1019 b << uint8(0); // item count placeholder
1020
1021 switch (lv.permission)
1022 {
1023 case GROUP_PERMISSION:
1024 case MASTER_PERMISSION:
1026 {
1027 bool isMasterLooter = lv.viewer->GetGroup() && lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID();
1028
1029 // if you are not the round-robin group looter, you can only see
1030 // blocked rolled items and quest items, and !ffa items
1031 for (uint8 i = 0; i < l.items.size(); ++i)
1032 {
1033 if (!l.items[i].is_looted && !l.items[i].freeforall && (l.items[i].conditions.empty() || isMasterLooter) && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1034 {
1035 uint8 slot_type = 0;
1036
1037 if (l.items[i].is_blocked) // for ML & restricted is_blocked = !is_underthreshold
1038 {
1039 switch (lv.permission)
1040 {
1041 case GROUP_PERMISSION:
1042 slot_type = LOOT_SLOT_TYPE_ROLL_ONGOING;
1043 break;
1044 case MASTER_PERMISSION:
1045 {
1046 if (lv.viewer->GetGroup())
1047 {
1048 if (lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID())
1049 slot_type = LOOT_SLOT_TYPE_MASTER;
1050 else
1051 slot_type = LOOT_SLOT_TYPE_LOCKED;
1052 }
1053 break;
1054 }
1056 slot_type = LOOT_SLOT_TYPE_LOCKED;
1057 break;
1058 default:
1059 continue;
1060 }
1061 }
1062 else if (l.items[i].rollWinnerGUID)
1063 {
1064 if (l.items[i].rollWinnerGUID == lv.viewer->GetGUID())
1065 slot_type = LOOT_SLOT_TYPE_OWNER;
1066 else
1067 continue;
1068 }
1069 else if (!l.roundRobinPlayer || lv.viewer->GetGUID() == l.roundRobinPlayer || !l.items[i].is_underthreshold)
1070 {
1071 // no round robin owner or he has released the loot
1072 // or it IS the round robin group owner
1073 // => item is lootable
1074 slot_type = LOOT_SLOT_TYPE_ALLOW_LOOT;
1075 }
1076 else
1077 // item shall not be displayed.
1078 continue;
1079
1080 b << uint8(i) << l.items[i];
1081 b << uint8(slot_type);
1082 ++itemsShown;
1083 }
1084 }
1085 break;
1086 }
1088 {
1089 for (uint8 i = 0; i < l.items.size(); ++i)
1090 {
1091 if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1092 {
1093 if (l.roundRobinPlayer && lv.viewer->GetGUID() != l.roundRobinPlayer)
1094 // item shall not be displayed.
1095 continue;
1096
1097 b << uint8(i) << l.items[i];
1099 ++itemsShown;
1100 }
1101 }
1102 break;
1103 }
1104 case ALL_PERMISSION:
1105 case OWNER_PERMISSION:
1106 {
1108 for (uint8 i = 0; i < l.items.size(); ++i)
1109 {
1110 if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
1111 {
1112 b << uint8(i) << l.items[i];
1113 b << uint8(slot_type);
1114 ++itemsShown;
1115 }
1116 }
1117 break;
1118 }
1119 default:
1120 return b;
1121 }
1122
1124
1125 // Xinef: items that do not follow loot rules need this
1126 LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : slotType;
1127
1128 QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
1129 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID());
1130 if (q_itr != lootPlayerQuestItems.end())
1131 {
1132 QuestItemList* q_list = q_itr->second;
1133 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
1134 {
1135 LootItem& item = l.quest_items[qi->index];
1136 if (!qi->is_looted && !item.is_looted)
1137 {
1138 bool showInLoot = true;
1139 bool hasQuestForItem = lv.viewer->HasQuestForItem(item.itemid, 0, false, &showInLoot);
1140 if (!hasQuestForItem)
1141 {
1142 if (!showInLoot)
1143 {
1144 const_cast<QuestItem*>(&(*qi))->is_looted = true;
1145 if (!item.freeforall)
1146 {
1147 item.is_looted = true;
1148 }
1149 continue;
1150 }
1151
1152 b << uint8(l.items.size() + (qi - q_list->begin()));
1153 b << item;
1155 }
1156 else
1157 {
1158 b << uint8(l.items.size() + (qi - q_list->begin()));
1159 b << item;
1160
1161 if (item.follow_loot_rules)
1162 {
1163 switch (lv.permission)
1164 {
1165 case MASTER_PERMISSION:
1167 break;
1169 b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
1170 break;
1171 case GROUP_PERMISSION:
1173 if (!item.is_blocked)
1175 else
1177 break;
1178 default:
1179 b << uint8(slotType);
1180 break;
1181 }
1182 }
1183 else if (!item.freeforall)
1184 b << uint8(partySlotType);
1185 else
1186 b << uint8(slotType);
1187 }
1188
1189 ++itemsShown;
1190 }
1191 }
1192 }
1193
1194 QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems();
1195 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID());
1196 if (ffa_itr != lootPlayerFFAItems.end())
1197 {
1198 QuestItemList* ffa_list = ffa_itr->second;
1199 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
1200 {
1201 LootItem& item = l.items[fi->index];
1202 if (!fi->is_looted && !item.is_looted)
1203 {
1204 b << uint8(fi->index);
1205 b << item;
1206 // Xinef: Here are FFA items, so dont use owner permision
1207 b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT /*slotType*/);
1208 ++itemsShown;
1209 }
1210 }
1211 }
1212
1213 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems();
1214 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID());
1215 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
1216 {
1217 QuestItemList* conditional_list = nn_itr->second;
1218 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
1219 {
1220 LootItem& item = l.items[ci->index];
1221 if (!ci->is_looted && !item.is_looted)
1222 {
1223 b << uint8(ci->index);
1224 b << item;
1225 if (item.follow_loot_rules)
1226 {
1227 switch (lv.permission)
1228 {
1229 case MASTER_PERMISSION:
1231 break;
1233 b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
1234 break;
1235 case GROUP_PERMISSION:
1237 if (!item.is_blocked)
1239 else
1241 break;
1242 default:
1243 b << uint8(slotType);
1244 break;
1245 }
1246 }
1247 else if (!item.freeforall)
1248 b << uint8(partySlotType);
1249 else
1250 b << uint8(slotType);
1251 ++itemsShown;
1252 }
1253 }
1254 }
1255
1256 //update number of items shown
1257 b.put<uint8>(count_pos, itemsShown);
1258
1259 return b;
1260}
@ OWNER_PERMISSION
Definition: LootMgr.h:72
@ ALL_PERMISSION
Definition: LootMgr.h:67
@ RESTRICTED_PERMISSION
Definition: LootMgr.h:70
@ NONE_PERMISSION
Definition: LootMgr.h:73
@ ROUND_ROBIN_PERMISSION
Definition: LootMgr.h:71
@ MASTER_PERMISSION
Definition: LootMgr.h:69
@ GROUP_PERMISSION
Definition: LootMgr.h:68
LootSlotType
Definition: LootMgr.h:113
@ LOOT_SLOT_TYPE_MASTER
Definition: LootMgr.h:116
@ LOOT_SLOT_TYPE_ROLL_ONGOING
Definition: LootMgr.h:115
@ LOOT_SLOT_TYPE_ALLOW_LOOT
Definition: LootMgr.h:114
@ LOOT_SLOT_TYPE_OWNER
Definition: LootMgr.h:118
@ LOOT_SLOT_TYPE_LOCKED
Definition: LootMgr.h:117
Definition: LootMgr.h:313
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

Member Data Documentation

◆ containerGUID

◆ gold

◆ i_LootValidatorRefMgr

LootValidatorRefMgr Loot::i_LootValidatorRefMgr
private

Referenced by addLootValidatorRef(), and clear().

◆ items

◆ loot_type

◆ lootOwnerGUID

ObjectGuid Loot::lootOwnerGUID

Referenced by AddItem(), and FillLoot().

◆ PlayerFFAItems

◆ PlayerNonQuestNonFFAConditionalItems

◆ PlayerQuestItems

◆ PlayersLooting

◆ quest_items

◆ roundRobinPlayer

◆ sourceGameObject

GameObject* Loot::sourceGameObject {nullptr}

Referenced by GameObject::GameObject().

◆ sourceWorldObjectGUID

◆ unlootedCount