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
+1 -1
View File
@@ -1398,7 +1398,7 @@ public:
void MoneyChanged(uint32 value); void MoneyChanged(uint32 value);
void ReputationChanged(FactionEntry const* factionEntry); void ReputationChanged(FactionEntry const* factionEntry);
void ReputationChanged2(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; [[nodiscard]] bool HasQuestForGO(int32 GOId) const;
void UpdateForQuestWorldObjects(); void UpdateForQuestWorldObjects();
[[nodiscard]] bool CanShareQuest(uint32 quest_id) const; [[nodiscard]] bool CanShareQuest(uint32 quest_id) const;
@@ -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) 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 // This part for ReqItem drop
for (uint8 j = 0; j < QUEST_ITEM_OBJECTIVES_COUNT; ++j) 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; return true;
}
} }
// This part - for ReqSource // This part - for ReqSource
for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j) for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
+46 -23
View File
@@ -1072,34 +1072,57 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
LootItem& item = l.quest_items[qi->index]; LootItem& item = l.quest_items[qi->index];
if (!qi->is_looted && !item.is_looted) if (!qi->is_looted && !item.is_looted)
{ {
b << uint8(l.items.size() + (qi - q_list->begin())); bool showInLoot = true;
b << item; bool hasQuestForItem = lv.viewer->HasQuestForItem(item.itemid, 0, false, &showInLoot);
if (item.follow_loot_rules) if (!hasQuestForItem)
{ {
switch (lv.permission) if (!showInLoot)
{ {
case MASTER_PERMISSION: const_cast<QuestItem*>(&(*qi))->is_looted = true;
b << uint8(LOOT_SLOT_TYPE_MASTER); if (!item.freeforall)
break; {
case RESTRICTED_PERMISSION: item.is_looted = true;
b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); }
break; continue;
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;
} }
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 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; ++itemsShown;
} }
} }