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)
506{
507 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
508 if (!proto)
509 return;
510
511 uint32 count = urand(item.mincount, item.maxcount);
512 uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0);
513
514 std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items;
515 uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS;
516
517 for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i)
518 {
519 LootItem generatedLoot(item);
520 generatedLoot.count = std::min(count, proto->GetMaxStackSize());
521 generatedLoot.itemIndex = lootItems.size();
522 lootItems.push_back(generatedLoot);
523 count -= proto->GetMaxStackSize();
524
525 // In some cases, a dropped item should be visible/lootable only for some players in group
526 bool canSeeItemInLootWindow = false;
527 if (auto player = ObjectAccessor::FindPlayer(lootOwnerGUID))
528 {
529 if (auto group = player->GetGroup())
530 {
531 for (auto itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
532 {
533 if (auto member = itr->GetSource())
534 {
535 if (generatedLoot.AllowedForPlayer(member, sourceWorldObjectGUID))
536 {
537 canSeeItemInLootWindow = true;
538 break;
539 }
540 }
541 }
542 }
543 else if (generatedLoot.AllowedForPlayer(player, sourceWorldObjectGUID))
544 {
545 canSeeItemInLootWindow = true;
546 }
547 }
548
549 if (!canSeeItemInLootWindow)
550 {
551 LOG_DEBUG("loot", "Skipping ++unlootedCount for unlootable item: {}", item.itemid);
552 continue;
553 }
554
555 // non-conditional one-player only items are counted here,
556 // free for all items are counted in FillFFALoot(),
557 // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
558 if (!item.needs_quest && item.conditions.empty() && !proto->HasFlag(ITEM_FLAG_MULTI_DROP))
560 }
561}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
std::uint32_t uint32
Definition: Define.h:107
#define sObjectMgr
Definition: ObjectMgr.h:1623
#define MAX_NR_QUEST_ITEMS
Definition: LootMgr.h:54
#define MAX_NR_LOOT_ITEMS
Definition: LootMgr.h:52
@ ITEM_FLAG_MULTI_DROP
Definition: ItemTemplate.h:158
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:248
Definition: ItemTemplate.h:619
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
Definition: LootMgr.h:155
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:79
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
658{
659 QuestItemList* ql = new QuestItemList();
660
661 for (uint8 i = 0; i < items.size(); ++i)
662 {
663 LootItem& item = items[i];
664 if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
665 {
666 ql->push_back(QuestItem(i));
668 }
669 }
670 if (ql->empty())
671 {
672 delete ql;
673 return nullptr;
674 }
675
676 PlayerFFAItems[player->GetGUID()] = ql;
677 return ql;
678}
std::uint8_t uint8
Definition: Define.h:109
std::vector< QuestItem > QuestItemList
Definition: LootMgr.h:199
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
bool AllowedForPlayer(Player const *player, ObjectGuid source) const
Definition: LootMgr.cpp:410
bool is_looted
Definition: LootMgr.h:164
bool freeforall
Definition: LootMgr.h:166
Definition: LootMgr.h:186
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 
)
565{
566 // Must be provided
567 if (!lootOwner)
568 return false;
569
570 lootOwnerGUID = lootOwner->GetGUID();
571
572 LootTemplate const* tab = store.GetLootFor(lootId);
573
574 if (!tab)
575 {
576 if (!noEmptyError)
577 LOG_ERROR("sql.sql", "Table '{}' loot id #{} used but it doesn't have records.", store.GetName(), lootId);
578 return false;
579 }
580
581 items.reserve(MAX_NR_LOOT_ITEMS);
583
584 // Initial group is 0, top level set to True
585 tab->Process(*this, store, lootMode, lootOwner, 0, true); // Processing is done there, callback via Loot::AddItem()
586
587 sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
588
589 // Setting access rights for group loot case
590 Group* group = lootOwner->GetGroup();
591 if (!personal && group)
592 {
593 roundRobinPlayer = lootOwner->GetGUID();
594
595 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
596 {
597 if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
598 {
599 if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
600 {
601 FillNotNormalLootFor(player);
602 }
603 }
604 }
605
606 for (uint8 i = 0; i < items.size(); ++i)
607 {
608 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid))
609 if (proto->Quality < uint32(group->GetLootThreshold()))
610 items[i].is_underthreshold = true;
611 }
612 }
613 // ... for personal loot
614 else
615 FillNotNormalLootFor(lootOwner);
616
617 return true;
618}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
#define sScriptMgr
Definition: ScriptMgr.h:708
Definition: Player.h:1064
Group * GetGroup()
Definition: Player.h:2448
Definition: Group.h:169
ItemQualities GetLootThreshold() const
Definition: Group.cpp:2331
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:1692
void FillNotNormalLootFor(Player *player)
Definition: LootMgr.cpp:620

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
730{
731 QuestItemList* ql = new QuestItemList();
732
733 for (uint8 i = 0; i < items.size(); ++i)
734 {
735 LootItem& item = items[i];
736
737 if (!item.is_looted && !item.freeforall && item.AllowedForPlayer(player, sourceWorldObjectGUID))
738 {
739 item.AddAllowedLooter(player);
740
741 if (!item.conditions.empty())
742 {
743 ql->push_back(QuestItem(i));
744 if (!item.is_counted)
745 {
747 item.is_counted = true;
748 }
749 }
750 }
751 }
752 if (ql->empty())
753 {
754 delete ql;
755 return nullptr;
756 }
757
759 return ql;
760}
void AddAllowedLooter(Player const *player)
Definition: LootMgr.cpp:495
ConditionList conditions
Definition: LootMgr.h:160
bool is_counted
Definition: LootMgr.h:168

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)
621{
622 ObjectGuid playerGuid = player->GetGUID();
623
624 QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(playerGuid);
625 if (qmapitr == PlayerQuestItems.end())
626 FillQuestLoot(player);
627
628 qmapitr = PlayerFFAItems.find(playerGuid);
629 if (qmapitr == PlayerFFAItems.end())
630 FillFFALoot(player);
631
632 qmapitr = PlayerNonQuestNonFFAConditionalItems.find(playerGuid);
633 if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
635
636 // Process currency items
637 uint32 max_slot = GetMaxSlotInLootFor(player);
638 LootItem const* item = nullptr;
639 uint32 itemsSize = uint32(items.size());
640 for (uint32 i = 0; i < max_slot; ++i)
641 {
642 if (i < items.size())
643 item = &items[i];
644 else
645 item = &quest_items[i - itemsSize];
646
647 if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player, sourceWorldObjectGUID))
648 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
649 if (proto->IsCurrencyToken())
650 {
651 InventoryResult msg;
652 player->StoreLootItem(i, this, msg);
653 }
654 }
655}
InventoryResult
Definition: Item.h:46
Definition: ObjectGuid.h:118
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition: Player.cpp:13515
uint32 itemid
Definition: LootMgr.h:156
QuestItemList * FillQuestLoot(Player *player)
Definition: LootMgr.cpp:680
uint32 GetMaxSlotInLootFor(Player *player) const
Definition: LootMgr.cpp:907
QuestItemList * FillFFALoot(Player *player)
Definition: LootMgr.cpp:657
QuestItemList * FillNonQuestNonFFAConditionalLoot(Player *player)
Definition: LootMgr.cpp:729

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

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 
)
830{
831 if (maxAmount > 0)
832 {
833 if (maxAmount <= minAmount)
834 gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY));
835 else if ((maxAmount - minAmount) < 32700)
836 gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY));
837 else
838 gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8;
839 }
840}
@ RATE_DROP_MONEY
Definition: IWorld.h:467
#define sWorld
Definition: World.h:444

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

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

◆ GetMaxSlotInLootFor()

uint32 Loot::GetMaxSlotInLootFor ( Player player) const
908{
909 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
910 return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
911}

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
929{
930 QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems();
931 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID());
932 if (q_itr != lootPlayerQuestItems.end())
933 {
934 QuestItemList* q_list = q_itr->second;
935 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
936 {
937 const LootItem& item = quest_items[qi->index];
938 if (!qi->is_looted && !item.is_looted)
939 return true;
940 }
941 }
942
943 QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems();
944 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID());
945 if (ffa_itr != lootPlayerFFAItems.end())
946 {
947 QuestItemList* ffa_list = ffa_itr->second;
948 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
949 {
950 const LootItem& item = items[fi->index];
951 if (!fi->is_looted && !item.is_looted)
952 return true;
953 }
954 }
955
956 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
957 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
958 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
959 {
960 QuestItemList* conditional_list = nn_itr->second;
961 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
962 {
963 const LootItem& item = items[ci->index];
964 if (!ci->is_looted && !item.is_looted)
965 return true;
966 }
967 }
968
969 return false;
970}
std::map< ObjectGuid, QuestItemList * > QuestItemMap
Definition: LootMgr.h:201
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
914{
915 // Gold is always lootable
916 if (gold)
917 {
918 return true;
919 }
920
921 for (LootItem const& item : items)
922 if (!item.is_looted && !item.freeforall && item.conditions.empty())
923 return true;
924 return false;
925}

References gold, and items.

Referenced by Player::isAllowedToLoot().

◆ hasOverThresholdItem()

bool Loot::hasOverThresholdItem ( ) const
974{
975 for (uint8 i = 0; i < items.size(); ++i)
976 {
977 if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall)
978 return true;
979 }
980
981 return false;
982}

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 
)
843{
844 LootItem* item = nullptr;
845 bool is_looted = true;
846 if (lootSlot >= items.size())
847 {
848 uint32 questSlot = lootSlot - items.size();
849 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
850 if (itr != PlayerQuestItems.end() && questSlot < itr->second->size())
851 {
852 QuestItem* qitem2 = &itr->second->at(questSlot);
853 if (qitem)
854 *qitem = qitem2;
855 item = &quest_items[qitem2->index];
856 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
857 return nullptr;
858 is_looted = qitem2->is_looted;
859 }
860 }
861 else
862 {
863 item = &items[lootSlot];
864 is_looted = item->is_looted;
865 if (item->freeforall)
866 {
867 QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID());
868 if (itr != PlayerFFAItems.end())
869 {
870 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
871 if (iter->index == lootSlot)
872 {
873 QuestItem* ffaitem2 = (QuestItem*) & (*iter);
874 if (ffaitem)
875 *ffaitem = ffaitem2;
876 is_looted = ffaitem2->is_looted;
877 break;
878 }
879 }
880 }
881 else if (!item->conditions.empty())
882 {
883 QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
885 {
886 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
887 {
888 if (iter->index == lootSlot)
889 {
890 QuestItem* conditem2 = (QuestItem*) & (*iter);
891 if (conditem)
892 *conditem = conditem2;
893 is_looted = conditem2->is_looted;
894 break;
895 }
896 }
897 }
898 }
899 }
900
901 if (is_looted)
902 return nullptr;
903
904 return item;
905}
bool follow_loot_rules
Definition: LootMgr.h:170
uint8 index
Definition: LootMgr.h:187
bool is_looted
Definition: LootMgr.h:188

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)
765{
766 // notify all players that are looting this that the item was removed
767 // convert the index to the slot the player sees
768 PlayersLootingSet::iterator i_next;
769 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
770 {
771 i_next = i;
772 ++i_next;
773 if (Player* player = ObjectAccessor::FindPlayer(*i))
774 player->SendNotifyLootItemRemoved(lootIndex);
775 else
776 PlayersLooting.erase(i);
777 }
778}

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

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

◆ NotifyMoneyRemoved()

void Loot::NotifyMoneyRemoved ( )
781{
782 // notify all players that are looting this that the money was removed
783 PlayersLootingSet::iterator i_next;
784 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
785 {
786 i_next = i;
787 ++i_next;
788 if (Player* player = ObjectAccessor::FindPlayer(*i))
789 player->SendNotifyLootMoneyRemoved();
790 else
791 PlayersLooting.erase(i);
792 }
793}

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

Referenced by WorldSession::HandleLootMoneyOpcode().

◆ NotifyQuestItemRemoved()

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

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