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)
482{
483 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
484 if (!proto)
485 return;
486
487 uint32 count = urand(item.mincount, item.maxcount);
488 uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0);
489
490 std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items;
491 uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS;
492
493 for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i)
494 {
495 LootItem generatedLoot(item);
496 generatedLoot.count = std::min(count, proto->GetMaxStackSize());
497 generatedLoot.itemIndex = lootItems.size();
498 lootItems.push_back(generatedLoot);
499 count -= proto->GetMaxStackSize();
500
501 // In some cases, a dropped item should be visible/lootable only for some players in group
502 bool canSeeItemInLootWindow = false;
503 if (auto player = ObjectAccessor::FindPlayer(lootOwnerGUID))
504 {
505 if (auto group = player->GetGroup())
506 {
507 for (auto itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
508 {
509 if (auto member = itr->GetSource())
510 {
511 if (generatedLoot.AllowedForPlayer(member, sourceWorldObjectGUID))
512 {
513 canSeeItemInLootWindow = true;
514 break;
515 }
516 }
517 }
518 }
519 else if (generatedLoot.AllowedForPlayer(player, sourceWorldObjectGUID))
520 {
521 canSeeItemInLootWindow = true;
522 }
523 }
524
525 if (!canSeeItemInLootWindow)
526 {
527 LOG_DEBUG("loot", "Skipping ++unlootedCount for unlootable item: {}", item.itemid);
528 continue;
529 }
530
531 // non-conditional one-player only items are counted here,
532 // free for all items are counted in FillFFALoot(),
533 // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
534 if (!item.needs_quest && item.conditions.empty() && !proto->HasFlag(ITEM_FLAG_MULTI_DROP))
536 }
537}
std::uint32_t uint32
Definition Define.h:107
@ ITEM_FLAG_MULTI_DROP
Definition ItemTemplate.h:158
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
#define MAX_NR_QUEST_ITEMS
Definition LootMgr.h:53
#define MAX_NR_LOOT_ITEMS
Definition LootMgr.h:51
#define sObjectMgr
Definition ObjectMgr.h:1723
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:245
Definition ItemTemplate.h:619
uint32 GetMaxStackSize() const
Definition ItemTemplate.h:727
bool HasFlag(ItemFlags flag) const
Definition ItemTemplate.h:825
Definition LootMgr.h:154
ObjectGuid sourceWorldObjectGUID
Definition LootMgr.h:330
uint8 unlootedCount
Definition LootMgr.h:323
ObjectGuid lootOwnerGUID
Definition LootMgr.h:325
std::vector< LootItem > items
Definition LootMgr.h:320
std::vector< LootItem > quest_items
Definition LootMgr.h:321

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

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

◆ AddLooter()

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

References PlayersLooting.

Referenced by Player::SendLoot().

◆ addLootValidatorRef()

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

References i_LootValidatorRefMgr, and LinkedListHead::insertFirst().

Referenced by Roll::targetObjectBuildLink().

◆ clear()

void Loot::clear ( )
inline
344 {
345 for (QuestItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr)
346 delete itr->second;
347 PlayerQuestItems.clear();
348
349 for (QuestItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr)
350 delete itr->second;
351 PlayerFFAItems.clear();
352
353 for (QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr)
354 delete itr->second;
356
357 PlayersLooting.clear();
358 items.clear();
359 quest_items.clear();
360 gold = 0;
361 unlootedCount = 0;
365 }
@ LOOT_NONE
Definition LootMgr.h:78
void Clear()
Definition ObjectGuid.h:138
void clearReferences()
Definition RefMgr.h:42
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(), debug_commandscript::GenerateLoot(), GameObject::GetFishLoot(), 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
634{
635 QuestItemList* ql = new QuestItemList();
636
637 for (uint8 i = 0; i < items.size(); ++i)
638 {
639 LootItem& item = items[i];
640 if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
641 {
642 ql->push_back(QuestItem(i));
644 }
645 }
646 if (ql->empty())
647 {
648 delete ql;
649 return nullptr;
650 }
651
652 PlayerFFAItems[player->GetGUID()] = ql;
653 return ql;
654}
std::uint8_t uint8
Definition Define.h:109
std::vector< QuestItem > QuestItemList
Definition LootMgr.h:198
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:114
bool AllowedForPlayer(Player const *player, ObjectGuid source) const
Definition LootMgr.cpp:417
bool is_looted
Definition LootMgr.h:163
bool freeforall
Definition LootMgr.h:165
ObjectGuid containerGUID
Definition LootMgr.h:329
Definition LootMgr.h:185

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 
)
541{
542 // Must be provided
543 if (!lootOwner)
544 return false;
545
546 lootOwnerGUID = lootOwner->GetGUID();
547
548 LootTemplate const* tab = store.GetLootFor(lootId);
549
550 if (!tab)
551 {
552 if (!noEmptyError)
553 LOG_ERROR("sql.sql", "Table '{}' loot id #{} used but it doesn't have records.", store.GetName(), lootId);
554 return false;
555 }
556
557 items.reserve(MAX_NR_LOOT_ITEMS);
559
560 // Initial group is 0, top level set to True
561 tab->Process(*this, store, lootMode, lootOwner, 0, true); // Processing is done there, callback via Loot::AddItem()
562
563 sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
564
565 // Setting access rights for group loot case
566 Group* group = lootOwner->GetGroup();
567 if (!personal && group)
568 {
569 roundRobinPlayer = lootOwner->GetGUID();
570
571 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
572 {
573 if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
574 {
575 if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
576 {
577 FillNotNormalLootFor(player);
578 }
579 }
580 }
581
582 for (uint8 i = 0; i < items.size(); ++i)
583 {
584 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid))
585 if (proto->Quality < uint32(group->GetLootThreshold()))
586 items[i].is_underthreshold = true;
587 }
588 }
589 // ... for personal loot
590 else
591 FillNotNormalLootFor(lootOwner);
592
593 return true;
594}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
#define sScriptMgr
Definition ScriptMgr.h:737
Definition GroupReference.h:27
Definition Group.h:169
ItemQualities GetLootThreshold() const
Definition Group.cpp:2344
GroupReference * GetFirstMember()
Definition Group.h:243
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:1667
Definition Player.h:1084
Group * GetGroup()
Definition Player.h:2505
void FillNotNormalLootFor(Player *player)
Definition LootMgr.cpp:596

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, LootTemplate::Process(), quest_items, roundRobinPlayer, sObjectMgr, and sScriptMgr.

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

◆ FillNonQuestNonFFAConditionalLoot()

QuestItemList * Loot::FillNonQuestNonFFAConditionalLoot ( Player player)
private
709{
710 QuestItemList* ql = new QuestItemList();
711
712 for (uint8 i = 0; i < items.size(); ++i)
713 {
714 LootItem& item = items[i];
715
716 if (!item.is_looted && !item.freeforall && item.AllowedForPlayer(player, sourceWorldObjectGUID))
717 {
718 item.AddAllowedLooter(player);
719
720 if (!item.conditions.empty())
721 {
722 ql->push_back(QuestItem(i));
723 if (!item.is_counted)
724 {
726 item.is_counted = true;
727 }
728 }
729 }
730 }
731 if (ql->empty())
732 {
733 delete ql;
734 return nullptr;
735 }
736
738 return ql;
739}
void AddAllowedLooter(Player const *player)
Definition LootMgr.cpp:471
ConditionList conditions
Definition LootMgr.h:159
bool is_counted
Definition LootMgr.h:167

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

Referenced by FillNotNormalLootFor().

◆ FillNotNormalLootFor()

void Loot::FillNotNormalLootFor ( Player player)
597{
598 ObjectGuid playerGuid = player->GetGUID();
599
600 QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(playerGuid);
601 if (qmapitr == PlayerQuestItems.end())
602 FillQuestLoot(player);
603
604 qmapitr = PlayerFFAItems.find(playerGuid);
605 if (qmapitr == PlayerFFAItems.end())
606 FillFFALoot(player);
607
608 qmapitr = PlayerNonQuestNonFFAConditionalItems.find(playerGuid);
609 if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
611
612 // Process currency items
613 uint32 max_slot = GetMaxSlotInLootFor(player);
614 LootItem const* item = nullptr;
615 uint32 itemsSize = uint32(items.size());
616 for (uint32 i = 0; i < max_slot; ++i)
617 {
618 if (i < items.size())
619 item = &items[i];
620 else
621 item = &quest_items[i - itemsSize];
622
623 if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player, sourceWorldObjectGUID))
624 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
625 if (proto->IsCurrencyToken())
626 {
627 InventoryResult msg;
628 player->StoreLootItem(i, this, msg);
629 }
630 }
631}
InventoryResult
Definition Item.h:46
Definition ObjectGuid.h:118
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition Player.cpp:13570
uint32 itemid
Definition LootMgr.h:155
QuestItemList * FillQuestLoot(Player *player)
Definition LootMgr.cpp:656
uint32 GetMaxSlotInLootFor(Player *player) const
Definition LootMgr.cpp:886
QuestItemList * FillFFALoot(Player *player)
Definition LootMgr.cpp:633
QuestItemList * FillNonQuestNonFFAConditionalLoot(Player *player)
Definition LootMgr.cpp:708

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
657{
658 if (items.size() == MAX_NR_LOOT_ITEMS)
659 return nullptr;
660
661 QuestItemList* ql = new QuestItemList();
662
663 bool isMasterLooter = player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID();
664
665 for (uint8 i = 0; i < quest_items.size(); ++i)
666 {
667 LootItem& item = quest_items[i];
668
669 sScriptMgr->OnPlayerBeforeFillQuestLootItem(player, item);
670
671 bool allowed = item.AllowedForPlayer(player, sourceWorldObjectGUID);
672
673 if (!allowed && !isMasterLooter)
674 continue;
675
676 ql->push_back(QuestItem(i));
677
678 // Only add "allowed looter" if you are actually allowed to loot.
679 if (allowed)
680 {
681 item.AddAllowedLooter(player);
682
683 if (item.freeforall)
684 {
686 }
687 else if (!item.is_counted)
688 {
690 item.is_counted = true;
691 }
692 }
693
694 if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
695 break;
696 }
697
698 if (ql->empty())
699 {
700 delete ql;
701 return nullptr;
702 }
703
704 PlayerQuestItems[player->GetGUID()] = ql;
705 return ql;
706}
@ MASTER_LOOT
Definition LootMgr.h:60
ObjectGuid GetMasterLooterGuid() const
Definition Group.cpp:2339
LootMethod GetLootMethod() const
Definition Group.cpp:2329

References LootItem::AddAllowedLooter(), LootItem::AllowedForPlayer(), LootItem::freeforall, Player::GetGroup(), Object::GetGUID(), Group::GetLootMethod(), Group::GetMasterLooterGuid(), LootItem::is_counted, items, MASTER_LOOT, MAX_NR_LOOT_ITEMS, PlayerQuestItems, quest_items, sourceWorldObjectGUID, sScriptMgr, and unlootedCount.

Referenced by FillNotNormalLootFor().

◆ generateMoneyLoot()

void Loot::generateMoneyLoot ( uint32  minAmount,
uint32  maxAmount 
)
809{
810 if (maxAmount > 0)
811 {
812 if (maxAmount <= minAmount)
813 gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY));
814 else if ((maxAmount - minAmount) < 32700)
815 gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY));
816 else
817 gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8;
818 }
819}
@ RATE_DROP_MONEY
Definition WorldConfig.h:426
#define sWorld
Definition World.h:317

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

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

◆ GetMaxSlotInLootFor()

uint32 Loot::GetMaxSlotInLootFor ( Player player) const
887{
888 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
889 return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
890}

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
908{
909 QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems();
910 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID());
911 if (q_itr != lootPlayerQuestItems.end())
912 {
913 QuestItemList* q_list = q_itr->second;
914 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
915 {
916 const LootItem& item = quest_items[qi->index];
917 if (!qi->is_looted && !item.is_looted)
918 return true;
919 }
920 }
921
922 QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems();
923 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID());
924 if (ffa_itr != lootPlayerFFAItems.end())
925 {
926 QuestItemList* ffa_list = ffa_itr->second;
927 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
928 {
929 const LootItem& item = items[fi->index];
930 if (!fi->is_looted && !item.is_looted)
931 return true;
932 }
933 }
934
935 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
936 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
937 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
938 {
939 QuestItemList* conditional_list = nn_itr->second;
940 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
941 {
942 const LootItem& item = items[ci->index];
943 if (!ci->is_looted && !item.is_looted)
944 return true;
945 }
946 }
947
948 return false;
949}
std::map< ObjectGuid, QuestItemList * > QuestItemMap
Definition LootMgr.h:200
QuestItemMap const & GetPlayerQuestItems() const
Definition LootMgr.h:316
QuestItemMap const & GetPlayerFFAItems() const
Definition LootMgr.h:317
QuestItemMap const & GetPlayerNonQuestNonFFAConditionalItems() const
Definition LootMgr.h:318

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

Referenced by Player::isAllowedToLoot().

◆ hasItemForAll()

bool Loot::hasItemForAll ( ) const
893{
894 // Gold is always lootable
895 if (gold)
896 {
897 return true;
898 }
899
900 for (LootItem const& item : items)
901 if (!item.is_looted && !item.freeforall && item.conditions.empty())
902 return true;
903 return false;
904}
bool empty() const
Definition LootMgr.h:367

References gold, and items.

Referenced by Player::isAllowedToLoot().

◆ hasOverThresholdItem()

bool Loot::hasOverThresholdItem ( ) const
953{
954 for (uint8 i = 0; i < items.size(); ++i)
955 {
956 if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall)
957 return true;
958 }
959
960 return false;
961}

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 
)
822{
823 LootItem* item = nullptr;
824 bool is_looted = true;
825 if (lootSlot >= items.size())
826 {
827 uint32 questSlot = lootSlot - items.size();
828 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
829 if (itr != PlayerQuestItems.end() && questSlot < itr->second->size())
830 {
831 QuestItem* qitem2 = &itr->second->at(questSlot);
832 if (qitem)
833 *qitem = qitem2;
834 item = &quest_items[qitem2->index];
835 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
836 return nullptr;
837 is_looted = qitem2->is_looted;
838 }
839 }
840 else
841 {
842 item = &items[lootSlot];
843 is_looted = item->is_looted;
844 if (item->freeforall)
845 {
846 QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID());
847 if (itr != PlayerFFAItems.end())
848 {
849 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
850 if (iter->index == lootSlot)
851 {
852 QuestItem* ffaitem2 = (QuestItem*) & (*iter);
853 if (ffaitem)
854 *ffaitem = ffaitem2;
855 is_looted = ffaitem2->is_looted;
856 break;
857 }
858 }
859 }
860 else if (!item->conditions.empty())
861 {
862 QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
864 {
865 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
866 {
867 if (iter->index == lootSlot)
868 {
869 QuestItem* conditem2 = (QuestItem*) & (*iter);
870 if (conditem)
871 *conditem = conditem2;
872 is_looted = conditem2->is_looted;
873 break;
874 }
875 }
876 }
877 }
878 }
879
880 if (is_looted)
881 return nullptr;
882
883 return item;
884}
bool follow_loot_rules
Definition LootMgr.h:169
uint8 index
Definition LootMgr.h:186
bool is_looted
Definition LootMgr.h:187

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

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

◆ NotifyItemRemoved()

void Loot::NotifyItemRemoved ( uint8  lootIndex)
744{
745 // notify all players that are looting this that the item was removed
746 // convert the index to the slot the player sees
747 PlayersLootingSet::iterator i_next;
748 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
749 {
750 i_next = i;
751 ++i_next;
752 if (Player* player = ObjectAccessor::FindPlayer(*i))
753 player->SendNotifyLootItemRemoved(lootIndex);
754 else
755 PlayersLooting.erase(i);
756 }
757}

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

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

◆ NotifyMoneyRemoved()

void Loot::NotifyMoneyRemoved ( )
760{
761 // notify all players that are looting this that the money was removed
762 PlayersLootingSet::iterator i_next;
763 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
764 {
765 i_next = i;
766 ++i_next;
767 if (Player* player = ObjectAccessor::FindPlayer(*i))
768 player->SendNotifyLootMoneyRemoved();
769 else
770 PlayersLooting.erase(i);
771 }
772}

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

Referenced by WorldSession::HandleLootMoneyOpcode().

◆ NotifyQuestItemRemoved()

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

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 Symbol Documentation

◆ operator<<

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

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}
331{nullptr};

Referenced by GameObject::GameObject().

◆ sourceWorldObjectGUID

◆ unlootedCount


The documentation for this struct was generated from the following files: