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)
495{
496 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
497 if (!proto)
498 return;
499
500 uint32 count = urand(item.mincount, item.maxcount);
501 uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0);
502
503 std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items;
504 uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS;
505
506 for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i)
507 {
508 LootItem generatedLoot(item);
509 generatedLoot.count = std::min(count, proto->GetMaxStackSize());
510 generatedLoot.itemIndex = lootItems.size();
511 lootItems.push_back(generatedLoot);
512 count -= proto->GetMaxStackSize();
513
514 // In some cases, a dropped item should be visible/lootable only for some players in group
515 bool canSeeItemInLootWindow = false;
516 if (auto player = ObjectAccessor::FindPlayer(lootOwnerGUID))
517 {
518 if (auto group = player->GetGroup())
519 {
520 for (auto itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
521 {
522 if (auto member = itr->GetSource())
523 {
524 if (generatedLoot.AllowedForPlayer(member, sourceWorldObjectGUID))
525 {
526 canSeeItemInLootWindow = true;
527 break;
528 }
529 }
530 }
531 }
532 else if (generatedLoot.AllowedForPlayer(player, sourceWorldObjectGUID))
533 {
534 canSeeItemInLootWindow = true;
535 }
536 }
537
538 if (!canSeeItemInLootWindow)
539 {
540 LOG_DEBUG("loot", "Skipping ++unlootedCount for unlootable item: {}", item.itemid);
541 continue;
542 }
543
544 // non-conditional one-player only items are counted here,
545 // free for all items are counted in FillFFALoot(),
546 // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
547 if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_FLAG_MULTI_DROP))
549 }
550}
std::uint32_t uint32
Definition: Define.h:108
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:169
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ ITEM_FLAG_MULTI_DROP
Definition: ItemTemplate.h:159
#define sObjectMgr
Definition: ObjectMgr.h:1640
#define MAX_NR_QUEST_ITEMS
Definition: LootMgr.h:54
#define MAX_NR_LOOT_ITEMS
Definition: LootMgr.h:52
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:248
Definition: ItemTemplate.h:628
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:738
uint32 Flags
Definition: ItemTemplate.h:636
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(), ItemTemplate::Flags, Player::GetGroup(), ItemTemplate::GetMaxStackSize(), 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:140
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
647{
648 QuestItemList* ql = new QuestItemList();
649
650 for (uint8 i = 0; i < items.size(); ++i)
651 {
652 LootItem& item = items[i];
653 if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
654 {
655 ql->push_back(QuestItem(i));
657 }
658 }
659 if (ql->empty())
660 {
661 delete ql;
662 return nullptr;
663 }
664
665 PlayerFFAItems[player->GetGUID()] = ql;
666 return ql;
667}
std::uint8_t uint8
Definition: Define.h:110
std::vector< QuestItem > QuestItemList
Definition: LootMgr.h:199
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
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 
)
554{
555 // Must be provided
556 if (!lootOwner)
557 return false;
558
559 lootOwnerGUID = lootOwner->GetGUID();
560
561 LootTemplate const* tab = store.GetLootFor(lootId);
562
563 if (!tab)
564 {
565 if (!noEmptyError)
566 LOG_ERROR("sql.sql", "Table '{}' loot id #{} used but it doesn't have records.", store.GetName(), lootId);
567 return false;
568 }
569
570 items.reserve(MAX_NR_LOOT_ITEMS);
572
573 // Initial group is 0, top level set to True
574 tab->Process(*this, store, lootMode, lootOwner, 0, true); // Processing is done there, callback via Loot::AddItem()
575
576 sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
577
578 // Setting access rights for group loot case
579 Group* group = lootOwner->GetGroup();
580 if (!personal && group)
581 {
582 roundRobinPlayer = lootOwner->GetGUID();
583
584 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
585 {
586 if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
587 {
588 if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
589 {
590 FillNotNormalLootFor(player);
591 }
592 }
593 }
594
595 for (uint8 i = 0; i < items.size(); ++i)
596 {
597 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid))
598 if (proto->Quality < uint32(group->GetLootThreshold()))
599 items[i].is_underthreshold = true;
600 }
601 }
602 // ... for personal loot
603 else
604 FillNotNormalLootFor(lootOwner);
605
606 return true;
607}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
#define sScriptMgr
Definition: ScriptMgr.h:698
Definition: Player.h:1056
Group * GetGroup()
Definition: Player.h:2431
Definition: Group.h:169
ItemQualities GetLootThreshold() const
Definition: Group.cpp:2270
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:1681
void FillNotNormalLootFor(Player *player)
Definition: LootMgr.cpp:609

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
719{
720 QuestItemList* ql = new QuestItemList();
721
722 for (uint8 i = 0; i < items.size(); ++i)
723 {
724 LootItem& item = items[i];
725
726 if (!item.is_looted && !item.freeforall && item.AllowedForPlayer(player, sourceWorldObjectGUID))
727 {
728 item.AddAllowedLooter(player);
729
730 if (!item.conditions.empty())
731 {
732 ql->push_back(QuestItem(i));
733 if (!item.is_counted)
734 {
736 item.is_counted = true;
737 }
738 }
739 }
740 }
741 if (ql->empty())
742 {
743 delete ql;
744 return nullptr;
745 }
746
748 return ql;
749}
void AddAllowedLooter(Player const *player)
Definition: LootMgr.cpp:484
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)
610{
611 ObjectGuid playerGuid = player->GetGUID();
612
613 QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(playerGuid);
614 if (qmapitr == PlayerQuestItems.end())
615 FillQuestLoot(player);
616
617 qmapitr = PlayerFFAItems.find(playerGuid);
618 if (qmapitr == PlayerFFAItems.end())
619 FillFFALoot(player);
620
621 qmapitr = PlayerNonQuestNonFFAConditionalItems.find(playerGuid);
622 if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
624
625 // Process currency items
626 uint32 max_slot = GetMaxSlotInLootFor(player);
627 LootItem const* item = nullptr;
628 uint32 itemsSize = uint32(items.size());
629 for (uint32 i = 0; i < max_slot; ++i)
630 {
631 if (i < items.size())
632 item = &items[i];
633 else
634 item = &quest_items[i - itemsSize];
635
636 if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player, sourceWorldObjectGUID))
637 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
638 if (proto->IsCurrencyToken())
639 {
640 InventoryResult msg;
641 player->StoreLootItem(i, this, msg);
642 }
643 }
644}
InventoryResult
Definition: Item.h:40
Definition: ObjectGuid.h:120
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition: Player.cpp:13432
uint32 itemid
Definition: LootMgr.h:156
QuestItemList * FillQuestLoot(Player *player)
Definition: LootMgr.cpp:669
uint32 GetMaxSlotInLootFor(Player *player) const
Definition: LootMgr.cpp:896
QuestItemList * FillFFALoot(Player *player)
Definition: LootMgr.cpp:646
QuestItemList * FillNonQuestNonFFAConditionalLoot(Player *player)
Definition: LootMgr.cpp:718

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
670{
671 if (items.size() == MAX_NR_LOOT_ITEMS)
672 return nullptr;
673
674 QuestItemList* ql = new QuestItemList();
675
677
678 for (uint8 i = 0; i < quest_items.size(); ++i)
679 {
680 LootItem& item = quest_items[i];
681
682 sScriptMgr->OnBeforeFillQuestLootItem(player, item);
683
684 // Quest item is not free for all and is already assigned to another player
685 // or player doesn't need it
686 if (item.is_blocked || !item.AllowedForPlayer(player, sourceWorldObjectGUID))
687 {
688 continue;
689 }
690
691 // Player is not the loot owner, and loot owner still needs this quest item
692 if (!item.freeforall && lootOwner != player && item.AllowedForPlayer(lootOwner, sourceWorldObjectGUID))
693 {
694 continue;
695 }
696
697 ql->push_back(QuestItem(i));
699
700 if (!item.freeforall)
701 {
702 item.is_blocked = true;
703 }
704
705 if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
706 break;
707 }
708 if (ql->empty())
709 {
710 delete ql;
711 return nullptr;
712 }
713
714 PlayerQuestItems[player->GetGUID()] = ql;
715 return ql;
716}
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 
)
819{
820 if (maxAmount > 0)
821 {
822 if (maxAmount <= minAmount)
823 gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY));
824 else if ((maxAmount - minAmount) < 32700)
825 gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY));
826 else
827 gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8;
828 }
829}
@ RATE_DROP_MONEY
Definition: IWorld.h:462
#define sWorld
Definition: World.h:447

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

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

◆ GetMaxSlotInLootFor()

uint32 Loot::GetMaxSlotInLootFor ( Player player) const
897{
898 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
899 return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
900}

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
918{
919 QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems();
920 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID());
921 if (q_itr != lootPlayerQuestItems.end())
922 {
923 QuestItemList* q_list = q_itr->second;
924 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
925 {
926 const LootItem& item = quest_items[qi->index];
927 if (!qi->is_looted && !item.is_looted)
928 return true;
929 }
930 }
931
932 QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems();
933 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID());
934 if (ffa_itr != lootPlayerFFAItems.end())
935 {
936 QuestItemList* ffa_list = ffa_itr->second;
937 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
938 {
939 const LootItem& item = items[fi->index];
940 if (!fi->is_looted && !item.is_looted)
941 return true;
942 }
943 }
944
945 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
946 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
947 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
948 {
949 QuestItemList* conditional_list = nn_itr->second;
950 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
951 {
952 const LootItem& item = items[ci->index];
953 if (!ci->is_looted && !item.is_looted)
954 return true;
955 }
956 }
957
958 return false;
959}
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
903{
904 // Gold is always lootable
905 if (gold)
906 {
907 return true;
908 }
909
910 for (LootItem const& item : items)
911 if (!item.is_looted && !item.freeforall && item.conditions.empty())
912 return true;
913 return false;
914}

References gold, and items.

Referenced by Player::isAllowedToLoot().

◆ hasOverThresholdItem()

bool Loot::hasOverThresholdItem ( ) const
963{
964 for (uint8 i = 0; i < items.size(); ++i)
965 {
966 if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall)
967 return true;
968 }
969
970 return false;
971}

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 
)
832{
833 LootItem* item = nullptr;
834 bool is_looted = true;
835 if (lootSlot >= items.size())
836 {
837 uint32 questSlot = lootSlot - items.size();
838 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
839 if (itr != PlayerQuestItems.end() && questSlot < itr->second->size())
840 {
841 QuestItem* qitem2 = &itr->second->at(questSlot);
842 if (qitem)
843 *qitem = qitem2;
844 item = &quest_items[qitem2->index];
845 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
846 return nullptr;
847 is_looted = qitem2->is_looted;
848 }
849 }
850 else
851 {
852 item = &items[lootSlot];
853 is_looted = item->is_looted;
854 if (item->freeforall)
855 {
856 QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID());
857 if (itr != PlayerFFAItems.end())
858 {
859 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
860 if (iter->index == lootSlot)
861 {
862 QuestItem* ffaitem2 = (QuestItem*) & (*iter);
863 if (ffaitem)
864 *ffaitem = ffaitem2;
865 is_looted = ffaitem2->is_looted;
866 break;
867 }
868 }
869 }
870 else if (!item->conditions.empty())
871 {
872 QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
874 {
875 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
876 {
877 if (iter->index == lootSlot)
878 {
879 QuestItem* conditem2 = (QuestItem*) & (*iter);
880 if (conditem)
881 *conditem = conditem2;
882 is_looted = conditem2->is_looted;
883 break;
884 }
885 }
886 }
887 }
888 }
889
890 if (is_looted)
891 return nullptr;
892
893 return item;
894}
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)
754{
755 // notify all players that are looting this that the item was removed
756 // convert the index to the slot the player sees
757 PlayersLootingSet::iterator i_next;
758 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
759 {
760 i_next = i;
761 ++i_next;
762 if (Player* player = ObjectAccessor::FindPlayer(*i))
763 player->SendNotifyLootItemRemoved(lootIndex);
764 else
765 PlayersLooting.erase(i);
766 }
767}

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

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

◆ NotifyMoneyRemoved()

void Loot::NotifyMoneyRemoved ( )
770{
771 // notify all players that are looting this that the money was removed
772 PlayersLootingSet::iterator i_next;
773 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
774 {
775 i_next = i;
776 ++i_next;
777 if (Player* player = ObjectAccessor::FindPlayer(*i))
778 player->SendNotifyLootMoneyRemoved();
779 else
780 PlayersLooting.erase(i);
781 }
782}

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

Referenced by WorldSession::HandleLootMoneyOpcode().

◆ NotifyQuestItemRemoved()

void Loot::NotifyQuestItemRemoved ( uint8  questIndex)
785{
786 // when a free for all questitem is looted
787 // all players will get notified of it being removed
788 // (other questitems can be looted by each group member)
789 // bit inefficient but isn't called often
790
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 {
798 QuestItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID());
799 if (pq != PlayerQuestItems.end() && pq->second)
800 {
801 // find where/if the player has the given item in it's vector
802 QuestItemList& pql = *pq->second;
803
804 uint8 j;
805 for (j = 0; j < pql.size(); ++j)
806 if (pql[j].index == questIndex)
807 break;
808
809 if (j < pql.size())
810 player->SendNotifyLootItemRemoved(items.size() + j);
811 }
812 }
813 else
814 PlayersLooting.erase(i);
815 }
816}

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