[11438] Clarify code for quest start/source/req items adding/remove at quest start.

* Fix problem with complete quest when quest start item == quest source item.
  And source item not have max items amount setting.
* Avoid remove start item for case when it will re-added at next code line as source item
This commit is contained in:
VladimirMangos 2011-05-08 05:45:59 +04:00
parent 1cd48649c2
commit a5fe00d6f6
4 changed files with 37 additions and 33 deletions

View file

@ -13512,7 +13512,7 @@ bool Player::CanAddQuest(Quest const *pQuest, bool msg) const
if (!SatisfyQuestLog(msg)) if (!SatisfyQuestLog(msg))
return false; return false;
if (!CanGiveQuestSourceItem(pQuest)) if (!CanGiveQuestSourceItemIfNeed(pQuest))
return false; return false;
return true; return true;
@ -13726,7 +13726,28 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
questStatusData.m_creatureOrGOcount[i] = 0; questStatusData.m_creatureOrGOcount[i] = 0;
} }
GiveQuestSourceItem(pQuest); // remove start item if not need
if (questGiver && questGiver->isType(TYPEID_ITEM))
{
// destroy not required for quest finish quest starting item
bool notRequiredItem = true;
for(int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
if (pQuest->ReqItemId[i] == questGiver->GetEntry())
{
notRequiredItem = false;
break;
}
}
if (pQuest->GetSrcItemId() == questGiver->GetEntry())
notRequiredItem = false;
if (notRequiredItem)
DestroyItem(((Item*)questGiver)->GetBagSlot(), ((Item*)questGiver)->GetSlot(), true);
}
GiveQuestSourceItemIfNeed(pQuest);
AdjustQuestReqItemCount( pQuest, questStatusData ); AdjustQuestReqItemCount( pQuest, questStatusData );
@ -14374,14 +14395,18 @@ bool Player::SatisfyQuestMonth(Quest const* qInfo, bool msg) const
return m_monthlyquests.find(qInfo->GetQuestId()) == m_monthlyquests.end(); return m_monthlyquests.find(qInfo->GetQuestId()) == m_monthlyquests.end();
} }
bool Player::CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest ) const bool Player::CanGiveQuestSourceItemIfNeed( Quest const *pQuest, ItemPosCountVec* dest) const
{ {
uint32 srcitem = pQuest->GetSrcItemId(); if (uint32 srcitem = pQuest->GetSrcItemId())
if (srcitem > 0)
{ {
uint32 count = pQuest->GetSrcItemCount(); uint32 count = pQuest->GetSrcItemCount();
if( count <= 0 )
count = 1; // player already have max amount required item (including bank), just report success
uint32 has_count = GetItemCount(srcitem, true);
if (has_count >= count)
return true;
count -= has_count; // real need amount
InventoryResult msg; InventoryResult msg;
if (!dest) if (!dest)
@ -14394,9 +14419,6 @@ bool Player::CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest
if (msg == EQUIP_ERR_OK) if (msg == EQUIP_ERR_OK)
return true; return true;
// player already have max amount required item, just report success
else if (msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS)
return true;
else else
SendEquipError( msg, NULL, NULL, srcitem ); SendEquipError( msg, NULL, NULL, srcitem );
return false; return false;
@ -14405,11 +14427,10 @@ bool Player::CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest
return true; return true;
} }
void Player::GiveQuestSourceItem( Quest const *pQuest ) void Player::GiveQuestSourceItemIfNeed(Quest const *pQuest)
{ {
ItemPosCountVec dest; ItemPosCountVec dest;
if (CanGiveQuestSourceItemIfNeed(pQuest, &dest) && !dest.empty())
if (CanGiveQuestSourceItem(pQuest, &dest) && !dest.empty())
{ {
uint32 count = 0; uint32 count = 0;
for(ItemPosCountVec::const_iterator c_itr = dest.begin(); c_itr != dest.end(); ++c_itr) for(ItemPosCountVec::const_iterator c_itr = dest.begin(); c_itr != dest.end(); ++c_itr)

View file

@ -1370,8 +1370,8 @@ class MANGOS_DLL_SPEC Player : public Unit
bool SatisfyQuestDay( Quest const* qInfo, bool msg ) const; bool SatisfyQuestDay( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestWeek( Quest const* qInfo, bool msg ) const; bool SatisfyQuestWeek( Quest const* qInfo, bool msg ) const;
bool SatisfyQuestMonth(Quest const* qInfo, bool msg) const; bool SatisfyQuestMonth(Quest const* qInfo, bool msg) const;
bool CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest = NULL) const; bool CanGiveQuestSourceItemIfNeed( Quest const *pQuest, ItemPosCountVec* dest = NULL) const;
void GiveQuestSourceItem( Quest const *pQuest ); void GiveQuestSourceItemIfNeed(Quest const *pQuest);
bool TakeQuestSourceItem( uint32 quest_id, bool msg ); bool TakeQuestSourceItem( uint32 quest_id, bool msg );
bool GetQuestRewardStatus( uint32 quest_id ) const; bool GetQuestRewardStatus( uint32 quest_id ) const;
QuestStatus GetQuestStatus( uint32 quest_id ) const; QuestStatus GetQuestStatus( uint32 quest_id ) const;

View file

@ -196,25 +196,8 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
break; break;
case TYPEID_ITEM: case TYPEID_ITEM:
case TYPEID_CONTAINER: case TYPEID_CONTAINER:
{
sScriptMgr.OnQuestAccept(_player, (Item*)pObject, qInfo); sScriptMgr.OnQuestAccept(_player, (Item*)pObject, qInfo);
// destroy not required for quest finish quest starting item
bool destroyItem = true;
for(int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
{
destroyItem = false;
break;
}
}
if(destroyItem)
_player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true);
break; break;
}
case TYPEID_GAMEOBJECT: case TYPEID_GAMEOBJECT:
sScriptMgr.OnQuestAccept(_player, (GameObject*)pObject, qInfo); sScriptMgr.OnQuestAccept(_player, (GameObject*)pObject, qInfo);
break; break;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11437" #define REVISION_NR "11438"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__