fix(Core/Loot): Quest items should not be lootable/visible if quest objective already fulfilled (#7700)

- Closes #6442
This commit is contained in:
UltraNix
2021-09-06 15:33:13 +02:00
committed by GitHub
parent 56ddb6711a
commit 02b0b29ffa
3 changed files with 68 additions and 26 deletions

View File

@@ -1398,7 +1398,7 @@ public:
void MoneyChanged(uint32 value);
void ReputationChanged(FactionEntry const* factionEntry);
void ReputationChanged2(FactionEntry const* factionEntry);
[[nodiscard]] bool HasQuestForItem(uint32 itemId, uint32 excludeQuestId = 0, bool turnIn = false) const;
[[nodiscard]] bool HasQuestForItem(uint32 itemId, uint32 excludeQuestId = 0, bool turnIn = false, bool* showInLoot = nullptr) const;
[[nodiscard]] bool HasQuestForGO(int32 GOId) const;
void UpdateForQuestWorldObjects();
[[nodiscard]] bool CanShareQuest(uint32 quest_id) const;

View File

@@ -2151,7 +2151,7 @@ void Player::ReputationChanged2(FactionEntry const* factionEntry)
}
}
bool Player::HasQuestForItem(uint32 itemid, uint32 excludeQuestId /* 0 */, bool turnIn /* false */) const
bool Player::HasQuestForItem(uint32 itemid, uint32 excludeQuestId /* 0 */, bool turnIn /* false */, bool* showInLoot /*= nullptr*/) const
{
for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
{
@@ -2180,8 +2180,27 @@ bool Player::HasQuestForItem(uint32 itemid, uint32 excludeQuestId /* 0 */, bool
// This part for ReqItem drop
for (uint8 j = 0; j < QUEST_ITEM_OBJECTIVES_COUNT; ++j)
{
if ((itemid == qinfo->RequiredItemId[j] && q_status.ItemCount[j] < qinfo->RequiredItemCount[j]) || (turnIn && q_status.ItemCount[j] >= qinfo->RequiredItemCount[j]))
if (itemid == qinfo->RequiredItemId[j] && q_status.ItemCount[j] < qinfo->RequiredItemCount[j])
{
if (showInLoot)
{
if (GetItemCount(itemid, true) < qinfo->RequiredItemCount[j])
{
return true;
}
*showInLoot = false;
}
else
{
return true;
}
}
if (turnIn && q_status.ItemCount[j] >= qinfo->RequiredItemCount[j])
{
return true;
}
}
// This part - for ReqSource
for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)

View File

@@ -1072,34 +1072,57 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
LootItem& item = l.quest_items[qi->index];
if (!qi->is_looted && !item.is_looted)
{
b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
if (item.follow_loot_rules)
bool showInLoot = true;
bool hasQuestForItem = lv.viewer->HasQuestForItem(item.itemid, 0, false, &showInLoot);
if (!hasQuestForItem)
{
switch (lv.permission)
if (!showInLoot)
{
case MASTER_PERMISSION:
b << uint8(LOOT_SLOT_TYPE_MASTER);
break;
case RESTRICTED_PERMISSION:
b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
break;
case GROUP_PERMISSION:
case ROUND_ROBIN_PERMISSION:
if (!item.is_blocked)
b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT);
else
b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING);
break;
default:
b << uint8(slotType);
break;
const_cast<QuestItem*>(&(*qi))->is_looted = true;
if (!item.freeforall)
{
item.is_looted = true;
}
continue;
}
b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
b << uint8(lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : LOOT_SLOT_TYPE_LOCKED);
}
else if (!item.freeforall)
b << uint8(partySlotType);
else
b << uint8(slotType);
{
b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
if (item.follow_loot_rules)
{
switch (lv.permission)
{
case MASTER_PERMISSION:
b << uint8(LOOT_SLOT_TYPE_MASTER);
break;
case RESTRICTED_PERMISSION:
b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType));
break;
case GROUP_PERMISSION:
case ROUND_ROBIN_PERMISSION:
if (!item.is_blocked)
b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT);
else
b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING);
break;
default:
b << uint8(slotType);
break;
}
}
else if (!item.freeforall)
b << uint8(partySlotType);
else
b << uint8(slotType);
}
++itemsShown;
}
}