mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
Merge pull request #1241 from poszer/QuestAbandonFinishFix
Core/Quests: Abandon&Finish quest items
This commit is contained in:
@@ -15747,15 +15747,23 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
uint32 quest_id = quest->GetQuestId();
|
||||
|
||||
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
|
||||
if (quest->RequiredItemId[i])
|
||||
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true);
|
||||
|
||||
{
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i]))
|
||||
{
|
||||
if (quest->RequiredItemCount[i] > 0 && itemTemplate->Bonding == BIND_QUEST_ITEM && !quest->IsRepeatable() && !HasQuestForItem(quest->RequiredItemId[i], quest_id, true))
|
||||
DestroyItemCount(quest->RequiredItemId[i], 9999, true);
|
||||
else
|
||||
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true);
|
||||
}
|
||||
}
|
||||
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
{
|
||||
if (quest->ItemDrop[i])
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->ItemDrop[i]))
|
||||
{
|
||||
uint32 count = quest->ItemDropQuantity[i];
|
||||
DestroyItemCount(quest->ItemDrop[i], count ? count : 9999, true);
|
||||
if (quest->ItemDropQuantity[i] > 0 && itemTemplate->Bonding == BIND_QUEST_ITEM && !quest->IsRepeatable() && !HasQuestForItem(quest->ItemDrop[i], quest_id))
|
||||
DestroyItemCount(quest->ItemDrop[i], 9999, true);
|
||||
else
|
||||
DestroyItemCount(quest->ItemDrop[i], quest->ItemDropQuantity[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15986,14 +15994,32 @@ void Player::FailQuest(uint32 questId)
|
||||
SendQuestFailed(questId);
|
||||
|
||||
// Destroy quest items on quest failure.
|
||||
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
if (quest->RequiredItemId[i] > 0 && quest->RequiredItemCount[i] > 0)
|
||||
// Destroy items received on starting the quest.
|
||||
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true, true);
|
||||
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i]))
|
||||
if (quest->RequiredItemCount[i] > 0 && itemTemplate->Bonding == BIND_QUEST_ITEM)
|
||||
DestroyItemCount(quest->RequiredItemId[i], 9999, true);
|
||||
|
||||
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
if (quest->ItemDrop[i] > 0 && quest->ItemDropQuantity[i] > 0)
|
||||
// Destroy items received during the quest.
|
||||
DestroyItemCount(quest->ItemDrop[i], quest->ItemDropQuantity[i], true, true);
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->ItemDrop[i]))
|
||||
if (quest->ItemDropQuantity[i] > 0 && itemTemplate->Bonding == BIND_QUEST_ITEM)
|
||||
DestroyItemCount(quest->ItemDrop[i], 9999, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::AbandonQuest(uint32 questId)
|
||||
{
|
||||
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
|
||||
{
|
||||
// It will Destroy quest items on quests abandons.
|
||||
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i]))
|
||||
if (quest->RequiredItemCount[i] > 0 && itemTemplate->Bonding == BIND_QUEST_ITEM)
|
||||
DestroyItemCount(quest->RequiredItemId[i], 9999, true);
|
||||
|
||||
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->ItemDrop[i]))
|
||||
if (quest->ItemDropQuantity[i] > 0 && itemTemplate->Bonding == BIND_QUEST_ITEM)
|
||||
DestroyItemCount(quest->ItemDrop[i], 9999, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17221,12 +17247,12 @@ void Player::ReputationChanged2(FactionEntry const* factionEntry)
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::HasQuestForItem(uint32 itemid) const
|
||||
bool Player::HasQuestForItem(uint32 itemid, uint32 excludeQuestId /* 0 */, bool turnIn /* false */) const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
|
||||
{
|
||||
uint32 questid = GetQuestSlotQuestId(i);
|
||||
if (questid == 0)
|
||||
if (questid == 0 || questid == excludeQuestId)
|
||||
continue;
|
||||
|
||||
QuestStatusMap::const_iterator qs_itr = m_QuestStatus.find(questid);
|
||||
@@ -17235,7 +17261,7 @@ bool Player::HasQuestForItem(uint32 itemid) const
|
||||
|
||||
QuestStatusData const& q_status = qs_itr->second;
|
||||
|
||||
if (q_status.Status == QUEST_STATUS_INCOMPLETE)
|
||||
if ((q_status.Status == QUEST_STATUS_INCOMPLETE) || (turnIn && q_status.Status == QUEST_STATUS_COMPLETE))
|
||||
{
|
||||
Quest const* qinfo = sObjectMgr->GetQuestTemplate(questid);
|
||||
if (!qinfo)
|
||||
@@ -17250,7 +17276,7 @@ bool Player::HasQuestForItem(uint32 itemid) const
|
||||
// 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])
|
||||
if ((itemid == qinfo->RequiredItemId[j] && q_status.ItemCount[j] < qinfo->RequiredItemCount[j]) || (turnIn && q_status.ItemCount[j] >= qinfo->RequiredItemCount[j]))
|
||||
return true;
|
||||
}
|
||||
// This part - for ReqSource
|
||||
@@ -17260,17 +17286,18 @@ bool Player::HasQuestForItem(uint32 itemid) const
|
||||
if (qinfo->ItemDrop[j] == itemid)
|
||||
{
|
||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
||||
|
||||
uint32 ownedCount = GetItemCount(itemid, true);
|
||||
// 'unique' item
|
||||
if (pProto->MaxCount && int32(GetItemCount(itemid, true)) < pProto->MaxCount)
|
||||
if ((pProto->MaxCount && int32(ownedCount) < pProto->MaxCount) || (turnIn && int32(ownedCount) >= pProto->MaxCount))
|
||||
return true;
|
||||
|
||||
// allows custom amount drop when not 0
|
||||
if (qinfo->ItemDropQuantity[j])
|
||||
{
|
||||
if (GetItemCount(itemid, true) < qinfo->ItemDropQuantity[j])
|
||||
if ((ownedCount < qinfo->ItemDropQuantity[j]) || (turnIn && ownedCount >= qinfo->ItemDropQuantity[j]))
|
||||
return true;
|
||||
} else if (GetItemCount(itemid, true) < pProto->GetMaxStackSize())
|
||||
}
|
||||
else if (ownedCount < pProto->GetMaxStackSize())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1399,6 +1399,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
bool CanRewardQuest(Quest const* quest, uint32 reward, bool msg);
|
||||
void AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver);
|
||||
void AddQuest(Quest const* quest, Object* questGiver);
|
||||
void AbandonQuest(uint32 quest_id);
|
||||
void CompleteQuest(uint32 quest_id);
|
||||
void IncompleteQuest(uint32 quest_id);
|
||||
void RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, bool announce = true);
|
||||
@@ -1486,7 +1487,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void MoneyChanged(uint32 value);
|
||||
void ReputationChanged(FactionEntry const* factionEntry);
|
||||
void ReputationChanged2(FactionEntry const* factionEntry);
|
||||
bool HasQuestForItem(uint32 itemid) const;
|
||||
bool HasQuestForItem(uint32 itemId, uint32 excludeQuestId = 0, bool turnIn = false) const;
|
||||
bool HasQuestForGO(int32 GOId) const;
|
||||
void UpdateForQuestWorldObjects();
|
||||
bool CanShareQuest(uint32 quest_id) const;
|
||||
|
||||
@@ -418,6 +418,7 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
_player->TakeQuestSourceItem(questId, true); // remove quest src item from player
|
||||
_player->AbandonQuest(questId); // remove all quest items player received before abandoning quest.
|
||||
_player->RemoveActiveQuest(questId);
|
||||
_player->RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId);
|
||||
#ifdef ELUNA
|
||||
|
||||
Reference in New Issue
Block a user