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)
464{
465 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
466 if (!proto)
467 return;
468
469 uint32 count = urand(item.mincount, item.maxcount);
470 uint32 stacks = count / proto->GetMaxStackSize() + (count % proto->GetMaxStackSize() ? 1 : 0);
471
472 std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items;
473 uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS;
474
475 for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i)
476 {
477 LootItem generatedLoot(item);
478 generatedLoot.count = std::min(count, proto->GetMaxStackSize());
479 generatedLoot.itemIndex = lootItems.size();
480 lootItems.push_back(generatedLoot);
481 count -= proto->GetMaxStackSize();
482
483 // In some cases, a dropped item should be visible/lootable only for some players in group
484 bool canSeeItemInLootWindow = false;
485 if (auto player = ObjectAccessor::FindPlayer(lootOwnerGUID))
486 {
487 if (auto group = player->GetGroup())
488 {
489 for (auto itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
490 {
491 if (auto member = itr->GetSource())
492 {
493 if (generatedLoot.AllowedForPlayer(member, sourceWorldObjectGUID))
494 {
495 canSeeItemInLootWindow = true;
496 break;
497 }
498 }
499 }
500 }
501 else if (generatedLoot.AllowedForPlayer(player, sourceWorldObjectGUID))
502 {
503 canSeeItemInLootWindow = true;
504 }
505 }
506
507 if (!canSeeItemInLootWindow)
508 {
509 LOG_DEBUG("loot", "Skipping ++unlootedCount for unlootable item: {}", item.itemid);
510 continue;
511 }
512
513 // non-conditional one-player only items are counted here,
514 // free for all items are counted in FillFFALoot(),
515 // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
516 if (!item.needs_quest && item.conditions.empty() && !proto->HasFlag(ITEM_FLAG_MULTI_DROP))
518 }
519}
std::uint32_t uint32
Definition Define.h:107
@ ITEM_FLAG_MULTI_DROP
Definition ItemTemplate.h:158
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
#define MAX_NR_QUEST_ITEMS
Definition LootMgr.h:53
#define MAX_NR_LOOT_ITEMS
Definition LootMgr.h:51
#define sObjectMgr
Definition ObjectMgr.h:1712
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
616{
617 QuestItemList* ql = new QuestItemList();
618
619 for (uint8 i = 0; i < items.size(); ++i)
620 {
621 LootItem& item = items[i];
622 if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
623 {
624 ql->push_back(QuestItem(i));
626 }
627 }
628 if (ql->empty())
629 {
630 delete ql;
631 return nullptr;
632 }
633
634 PlayerFFAItems[player->GetGUID()] = ql;
635 return ql;
636}
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 
)
523{
524 // Must be provided
525 if (!lootOwner)
526 return false;
527
528 lootOwnerGUID = lootOwner->GetGUID();
529
530 LootTemplate const* tab = store.GetLootFor(lootId);
531
532 if (!tab)
533 {
534 if (!noEmptyError)
535 LOG_ERROR("sql.sql", "Table '{}' loot id #{} used but it doesn't have records.", store.GetName(), lootId);
536 return false;
537 }
538
539 items.reserve(MAX_NR_LOOT_ITEMS);
541
542 // Initial group is 0, top level set to True
543 tab->Process(*this, store, lootMode, lootOwner, 0, true); // Processing is done there, callback via Loot::AddItem()
544
545 sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
546
547 // Setting access rights for group loot case
548 Group* group = lootOwner->GetGroup();
549 if (!personal && group)
550 {
551 roundRobinPlayer = lootOwner->GetGUID();
552
553 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
554 {
555 if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
556 {
557 if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
558 {
559 FillNotNormalLootFor(player);
560 }
561 }
562 }
563
564 for (uint8 i = 0; i < items.size(); ++i)
565 {
566 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid))
567 if (proto->Quality < uint32(group->GetLootThreshold()))
568 items[i].is_underthreshold = true;
569 }
570 }
571 // ... for personal loot
572 else
573 FillNotNormalLootFor(lootOwner);
574
575 return true;
576}
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
#define sScriptMgr
Definition ScriptMgr.h:734
Definition GroupReference.h:27
Definition Group.h:169
ItemQualities GetLootThreshold() const
Definition Group.cpp:2341
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:1649
Definition Player.h:1084
Group * GetGroup()
Definition Player.h:2504
void FillNotNormalLootFor(Player *player)
Definition LootMgr.cpp:578

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
691{
692 QuestItemList* ql = new QuestItemList();
693
694 for (uint8 i = 0; i < items.size(); ++i)
695 {
696 LootItem& item = items[i];
697
698 if (!item.is_looted && !item.freeforall && item.AllowedForPlayer(player, sourceWorldObjectGUID))
699 {
700 item.AddAllowedLooter(player);
701
702 if (!item.conditions.empty())
703 {
704 ql->push_back(QuestItem(i));
705 if (!item.is_counted)
706 {
708 item.is_counted = true;
709 }
710 }
711 }
712 }
713 if (ql->empty())
714 {
715 delete ql;
716 return nullptr;
717 }
718
720 return ql;
721}
void AddAllowedLooter(Player const *player)
Definition LootMgr.cpp:453
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)
579{
580 ObjectGuid playerGuid = player->GetGUID();
581
582 QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(playerGuid);
583 if (qmapitr == PlayerQuestItems.end())
584 FillQuestLoot(player);
585
586 qmapitr = PlayerFFAItems.find(playerGuid);
587 if (qmapitr == PlayerFFAItems.end())
588 FillFFALoot(player);
589
590 qmapitr = PlayerNonQuestNonFFAConditionalItems.find(playerGuid);
591 if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
593
594 // Process currency items
595 uint32 max_slot = GetMaxSlotInLootFor(player);
596 LootItem const* item = nullptr;
597 uint32 itemsSize = uint32(items.size());
598 for (uint32 i = 0; i < max_slot; ++i)
599 {
600 if (i < items.size())
601 item = &items[i];
602 else
603 item = &quest_items[i - itemsSize];
604
605 if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player, sourceWorldObjectGUID))
606 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
607 if (proto->IsCurrencyToken())
608 {
609 InventoryResult msg;
610 player->StoreLootItem(i, this, msg);
611 }
612 }
613}
InventoryResult
Definition Item.h:46
Definition ObjectGuid.h:118
LootItem * StoreLootItem(uint8 lootSlot, Loot *loot, InventoryResult &msg)
Definition Player.cpp:13535
uint32 itemid
Definition LootMgr.h:155
QuestItemList * FillQuestLoot(Player *player)
Definition LootMgr.cpp:638
uint32 GetMaxSlotInLootFor(Player *player) const
Definition LootMgr.cpp:868
QuestItemList * FillFFALoot(Player *player)
Definition LootMgr.cpp:615
QuestItemList * FillNonQuestNonFFAConditionalLoot(Player *player)
Definition LootMgr.cpp:690

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
639{
640 if (items.size() == MAX_NR_LOOT_ITEMS)
641 return nullptr;
642
643 QuestItemList* ql = new QuestItemList();
644
645 bool isMasterLooter = player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID();
646
647 for (uint8 i = 0; i < quest_items.size(); ++i)
648 {
649 LootItem& item = quest_items[i];
650
651 sScriptMgr->OnPlayerBeforeFillQuestLootItem(player, item);
652
653 bool allowed = item.AllowedForPlayer(player, sourceWorldObjectGUID);
654
655 if (!allowed && !isMasterLooter)
656 continue;
657
658 ql->push_back(QuestItem(i));
659
660 // Only add "allowed looter" if you are actually allowed to loot.
661 if (allowed)
662 {
663 item.AddAllowedLooter(player);
664
665 if (item.freeforall)
666 {
668 }
669 else if (!item.is_counted)
670 {
672 item.is_counted = true;
673 }
674 }
675
676 if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
677 break;
678 }
679
680 if (ql->empty())
681 {
682 delete ql;
683 return nullptr;
684 }
685
686 PlayerQuestItems[player->GetGUID()] = ql;
687 return ql;
688}
@ MASTER_LOOT
Definition LootMgr.h:60
ObjectGuid GetMasterLooterGuid() const
Definition Group.cpp:2336
LootMethod GetLootMethod() const
Definition Group.cpp:2326

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 
)
791{
792 if (maxAmount > 0)
793 {
794 if (maxAmount <= minAmount)
795 gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY));
796 else if ((maxAmount - minAmount) < 32700)
797 gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY));
798 else
799 gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8;
800 }
801}
@ RATE_DROP_MONEY
Definition WorldConfig.h:428
#define sWorld
Definition World.h:316

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
869{
870 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
871 return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0);
872}

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
890{
891 QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems();
892 QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID());
893 if (q_itr != lootPlayerQuestItems.end())
894 {
895 QuestItemList* q_list = q_itr->second;
896 for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi)
897 {
898 const LootItem& item = quest_items[qi->index];
899 if (!qi->is_looted && !item.is_looted)
900 return true;
901 }
902 }
903
904 QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems();
905 QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID());
906 if (ffa_itr != lootPlayerFFAItems.end())
907 {
908 QuestItemList* ffa_list = ffa_itr->second;
909 for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi)
910 {
911 const LootItem& item = items[fi->index];
912 if (!fi->is_looted && !item.is_looted)
913 return true;
914 }
915 }
916
917 QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
918 QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
919 if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end())
920 {
921 QuestItemList* conditional_list = nn_itr->second;
922 for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci)
923 {
924 const LootItem& item = items[ci->index];
925 if (!ci->is_looted && !item.is_looted)
926 return true;
927 }
928 }
929
930 return false;
931}
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
875{
876 // Gold is always lootable
877 if (gold)
878 {
879 return true;
880 }
881
882 for (LootItem const& item : items)
883 if (!item.is_looted && !item.freeforall && item.conditions.empty())
884 return true;
885 return false;
886}
bool empty() const
Definition LootMgr.h:367

References gold, and items.

Referenced by Player::isAllowedToLoot().

◆ hasOverThresholdItem()

bool Loot::hasOverThresholdItem ( ) const
935{
936 for (uint8 i = 0; i < items.size(); ++i)
937 {
938 if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall)
939 return true;
940 }
941
942 return false;
943}

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 
)
804{
805 LootItem* item = nullptr;
806 bool is_looted = true;
807 if (lootSlot >= items.size())
808 {
809 uint32 questSlot = lootSlot - items.size();
810 QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID());
811 if (itr != PlayerQuestItems.end() && questSlot < itr->second->size())
812 {
813 QuestItem* qitem2 = &itr->second->at(questSlot);
814 if (qitem)
815 *qitem = qitem2;
816 item = &quest_items[qitem2->index];
817 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
818 return nullptr;
819 is_looted = qitem2->is_looted;
820 }
821 }
822 else
823 {
824 item = &items[lootSlot];
825 is_looted = item->is_looted;
826 if (item->freeforall)
827 {
828 QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID());
829 if (itr != PlayerFFAItems.end())
830 {
831 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
832 if (iter->index == lootSlot)
833 {
834 QuestItem* ffaitem2 = (QuestItem*) & (*iter);
835 if (ffaitem)
836 *ffaitem = ffaitem2;
837 is_looted = ffaitem2->is_looted;
838 break;
839 }
840 }
841 }
842 else if (!item->conditions.empty())
843 {
844 QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID());
846 {
847 for (QuestItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter)
848 {
849 if (iter->index == lootSlot)
850 {
851 QuestItem* conditem2 = (QuestItem*) & (*iter);
852 if (conditem)
853 *conditem = conditem2;
854 is_looted = conditem2->is_looted;
855 break;
856 }
857 }
858 }
859 }
860 }
861
862 if (is_looted)
863 return nullptr;
864
865 return item;
866}
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)
726{
727 // notify all players that are looting this that the item was removed
728 // convert the index to the slot the player sees
729 PlayersLootingSet::iterator i_next;
730 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
731 {
732 i_next = i;
733 ++i_next;
734 if (Player* player = ObjectAccessor::FindPlayer(*i))
735 player->SendNotifyLootItemRemoved(lootIndex);
736 else
737 PlayersLooting.erase(i);
738 }
739}

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

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

◆ NotifyMoneyRemoved()

void Loot::NotifyMoneyRemoved ( )
742{
743 // notify all players that are looting this that the money was removed
744 PlayersLootingSet::iterator i_next;
745 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
746 {
747 i_next = i;
748 ++i_next;
749 if (Player* player = ObjectAccessor::FindPlayer(*i))
750 player->SendNotifyLootMoneyRemoved();
751 else
752 PlayersLooting.erase(i);
753 }
754}

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

Referenced by WorldSession::HandleLootMoneyOpcode().

◆ NotifyQuestItemRemoved()

void Loot::NotifyQuestItemRemoved ( uint8  questIndex)
757{
758 // when a free for all questitem is looted
759 // all players will get notified of it being removed
760 // (other questitems can be looted by each group member)
761 // bit inefficient but isn't called often
762
763 PlayersLootingSet::iterator i_next;
764 for (PlayersLootingSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next)
765 {
766 i_next = i;
767 ++i_next;
768 if (Player* player = ObjectAccessor::FindPlayer(*i))
769 {
770 QuestItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID());
771 if (pq != PlayerQuestItems.end() && pq->second)
772 {
773 // find where/if the player has the given item in it's vector
774 QuestItemList& pql = *pq->second;
775
776 uint8 j;
777 for (j = 0; j < pql.size(); ++j)
778 if (pql[j].index == questIndex)
779 break;
780
781 if (j < pql.size())
782 player->SendNotifyLootItemRemoved(items.size() + j);
783 }
784 }
785 else
786 PlayersLooting.erase(i);
787 }
788}

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