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:171
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:250
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::boss_priestess_delrissaAI::SummonedCreatureDies(), GameObject::Update(), and ~Loot().

◆ empty()

bool Loot::empty ( ) const
inline

◆ FillFFALoot()

QuestItemList * Loot::FillFFALoot ( Player player)
private
646{
647 QuestItemList* ql = new QuestItemList();
648
649 for (uint8 i = 0; i < items.size(); ++i)
650 {
651 LootItem& item = items[i];
652 if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
653 {
654 ql->push_back(QuestItem(i));
656 }
657 }
658 if (ql->empty())
659 {
660 delete ql;
661 return nullptr;
662 }
663
664 PlayerFFAItems[player->GetGUID()] = ql;
665 return ql;
666}
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 tab->Process(*this, store, lootMode, lootOwner); // Processing is done there, callback via Loot::AddItem()
574
575 sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
576
577 // Setting access rights for group loot case
578 Group* group = lootOwner->GetGroup();
579 if (!personal && group)
580 {
581 roundRobinPlayer = lootOwner->GetGUID();
582
583 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
584 {
585 if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
586 {
587 if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
588 {
589 FillNotNormalLootFor(player);
590 }
591 }
592 }
593
594 for (uint8 i = 0; i < items.size(); ++i)
595 {
596 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid))
597 if (proto->Quality < uint32(group->GetLootThreshold()))
598 items[i].is_underthreshold = true;
599 }
600 }
601 // ... for personal loot
602 else
603 FillNotNormalLootFor(lootOwner);
604
605 return true;
606}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
#define sScriptMgr
Definition: ScriptMgr.h:2702
Definition: Player.h:1046
Group * GetGroup()
Definition: Player.h:2418
Definition: Group.h:168
ItemQualities GetLootThreshold() const
Definition: Group.cpp:2270
GroupReference * GetFirstMember()
Definition: Group.h:242
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) const
Definition: LootMgr.cpp:1668
void FillNotNormalLootFor(Player *player)
Definition: LootMgr.cpp:608

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::boss_priestess_delrissaAI::SummonedCreatureDies().

◆ FillNonQuestNonFFAConditionalLoot()

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

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
669{
670 if (items.size() == MAX_NR_LOOT_ITEMS)
671 return nullptr;
672
673 QuestItemList* ql = new QuestItemList();
674
676
677 for (uint8 i = 0; i < quest_items.size(); ++i)
678 {
679 LootItem& item = quest_items[i];
680
681 // Quest item is not free for all and is already assigned to another player
682 // or player doesn't need it
683 if (item.is_blocked || !item.AllowedForPlayer(player, sourceWorldObjectGUID))
684 {
685 continue;
686 }
687
688 // Player is not the loot owner, and loot owner still needs this quest item
689 if (!item.freeforall && lootOwner != player && item.AllowedForPlayer(lootOwner, sourceWorldObjectGUID))
690 {
691 continue;
692 }
693
694 ql->push_back(QuestItem(i));
696
697 if (!item.freeforall)
698 {
699 item.is_blocked = true;
700 }
701
702 if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
703 break;
704 }
705 if (ql->empty())
706 {
707 delete ql;
708 return nullptr;
709 }
710
711 PlayerQuestItems[player->GetGUID()] = ql;
712 return ql;
713}
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, and unlootedCount.

Referenced by FillNotNormalLootFor().

◆ generateMoneyLoot()

void Loot::generateMoneyLoot ( uint32  minAmount,
uint32  maxAmount 
)
816{
817 if (maxAmount > 0)
818 {
819 if (maxAmount <= minAmount)
820 gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY));
821 else if ((maxAmount - minAmount) < 32700)
822 gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY));
823 else
824 gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8;
825 }
826}
@ RATE_DROP_MONEY
Definition: IWorld.h:456
#define sWorld
Definition: World.h:451

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

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

◆ GetMaxSlotInLootFor()

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

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

References gold, and items.

Referenced by Player::isAllowedToLoot().

◆ hasOverThresholdItem()

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

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

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

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

◆ NotifyMoneyRemoved()

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

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

Referenced by WorldSession::HandleLootMoneyOpcode().

◆ NotifyQuestItemRemoved()

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

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