diff options
Diffstat (limited to 'src/server/game/Loot/Loot.cpp')
-rw-r--r-- | src/server/game/Loot/Loot.cpp | 79 |
1 files changed, 67 insertions, 12 deletions
diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp index a59f228d001..1629f2230d2 100644 --- a/src/server/game/Loot/Loot.cpp +++ b/src/server/game/Loot/Loot.cpp @@ -57,6 +57,10 @@ LootItem::LootItem(LootStoreItem const& li) : itemid(li.itemid), conditions(li.c type = LootItemType::Currency; freeforall = true; break; + case LootStoreItem::Type::TrackingQuest: + type = LootItemType::TrackingQuest; + freeforall = true; + break; default: break; } @@ -77,6 +81,8 @@ bool LootItem::AllowedForPlayer(Player const* player, Loot const* loot) const return ItemAllowedForPlayer(player, loot, itemid, needs_quest, follow_loot_rules, false, conditions); case LootItemType::Currency: return CurrencyAllowedForPlayer(player, itemid, needs_quest, conditions); + case LootItemType::TrackingQuest: + return TrackingQuestAllowedForPlayer(player, itemid, conditions); default: break; } @@ -93,6 +99,8 @@ bool LootItem::AllowedForPlayer(Player const* player, LootStoreItem const& lootS strictUsabilityCheck, lootStoreItem.conditions); case LootStoreItem::Type::Currency: return CurrencyAllowedForPlayer(player, lootStoreItem.itemid, lootStoreItem.needs_quest, lootStoreItem.conditions); + case LootStoreItem::Type::TrackingQuest: + return TrackingQuestAllowedForPlayer(player, lootStoreItem.itemid, lootStoreItem.conditions); default: break; } @@ -174,6 +182,18 @@ bool LootItem::CurrencyAllowedForPlayer(Player const* player, uint32 currencyId, return true; } +bool LootItem::TrackingQuestAllowedForPlayer(Player const* player, uint32 questId, ConditionsReference const& conditions) +{ + // DB conditions check + if (!conditions.Meets(player)) + return false; + + if (player->IsQuestCompletedBitSet(questId)) + return false; + + return true; +} + void LootItem::AddAllowedLooter(Player const* player) { allowedGUIDs.insert(player->GetGUID()); @@ -740,9 +760,9 @@ void Loot::NotifyMoneyRemoved(Map const* map) } } -void Loot::OnLootOpened(Map* map, ObjectGuid looter) +void Loot::OnLootOpened(Map* map, Player* looter) { - AddLooter(looter); + AddLooter(looter->GetGUID()); if (!_wasOpened) { _wasOpened = true; @@ -770,18 +790,20 @@ void Loot::OnLootOpened(Map* map, ObjectGuid looter) } else if (_lootMethod == MASTER_LOOT) { - if (looter == _lootMaster) + if (looter->GetGUID() == _lootMaster) { - if (Player* lootMaster = ObjectAccessor::GetPlayer(map, looter)) - { - WorldPackets::Loot::MasterLootCandidateList masterLootCandidateList; - masterLootCandidateList.LootObj = GetGUID(); - masterLootCandidateList.Players = _allowedLooters; - lootMaster->SendDirectMessage(masterLootCandidateList.Write()); - } + WorldPackets::Loot::MasterLootCandidateList masterLootCandidateList; + masterLootCandidateList.LootObj = GetGUID(); + masterLootCandidateList.Players = _allowedLooters; + looter->SendDirectMessage(masterLootCandidateList.Write()); } } } + + // Flag tracking quests as completed after all items were scanned for this player (some might depend on this quest not being completed) + //if (!_mailUnlootedItems) + if (std::vector<NotNormalLootItem>* ffaItems = Trinity::Containers::MapGetValuePtr(PlayerFFAItems, looter->GetGUID())) + AutoStoreTrackingQuests(looter, *ffaItems); } bool Loot::HasAllowedLooter(ObjectGuid const& looter) const @@ -832,7 +854,7 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo roundRobinPlayer = lootOwner->GetGUID(); for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) - if (Player const* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter + if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter if (player->IsAtGroupRewardDistance(lootOwner)) FillNotNormalLootFor(player); @@ -905,6 +927,14 @@ void Loot::AddItem(LootStoreItem const& item) items.push_back(generatedLoot); break; } + case LootStoreItem::Type::TrackingQuest: + { + LootItem generatedLoot(item); + generatedLoot.count = 1; + generatedLoot.LootListId = items.size(); + items.push_back(generatedLoot); + break; + } default: break; } @@ -959,6 +989,11 @@ bool Loot::AutoStore(Player* player, uint8 bag, uint8 slot, bool broadcast, bool case LootItemType::Currency: player->ModifyCurrency(lootItem->itemid, lootItem->count, CurrencyGainSource::Loot); break; + case LootItemType::TrackingQuest: + + if (Quest const* quest = sObjectMgr->GetQuestTemplate(lootItem->itemid)) + player->RewardQuest(quest, LootItemType::Item, 0, player, false); + break; } if (ffaitem) @@ -973,6 +1008,20 @@ bool Loot::AutoStore(Player* player, uint8 bag, uint8 slot, bool broadcast, bool return allLooted; } +void Loot::AutoStoreTrackingQuests(Player* player, NotNormalLootItemList& ffaItems) +{ + for (NotNormalLootItem& ffaItem : ffaItems) + { + if (items[ffaItem.LootListId].type != LootItemType::TrackingQuest) + continue; + + --unlootedCount; + ffaItem.is_looted = true; + if (Quest const* quest = sObjectMgr->GetQuestTemplate(items[ffaItem.LootListId].itemid)) + player->RewardQuest(quest, LootItemType::Item, 0, player, false); + } +} + void Loot::LootMoney() { gold = 0; @@ -1113,7 +1162,7 @@ void Loot::Update() } } -void Loot::FillNotNormalLootFor(Player const* player) +void Loot::FillNotNormalLootFor(Player* player) { ObjectGuid plguid = player->GetGUID(); _allowedLooters.insert(plguid); @@ -1140,7 +1189,13 @@ void Loot::FillNotNormalLootFor(Player const* player) } if (!ffaItems->empty()) + { + // TODO: flag immediately for loot that is supposed to be mailed if unlooted, otherwise flag when sending SMSG_LOOT_RESPONSE + //if (_mailUnlootedItems) + // AutoStoreTrackingQuests(player, *ffaItems); + PlayerFFAItems[player->GetGUID()] = std::move(ffaItems); + } } // |