1. diff --git a/src/game/Player.cpp b/src/game/Player.cpp
  2. index a73de9b..dcc71a3 100644
  3. --- a/src/game/Player.cpp
  4. +++ b/src/game/Player.cpp
  5. @@ -11177,7 +11177,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
  6. else if (Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ))
  7. {
  8. pBag->StoreItem( slot, pItem, update );
  9. - if( IsInWorld() && update )
  10. + if (IsInWorld() && update)
  11. {
  12. pItem->AddToWorld();
  13. pItem->SendCreateUpdateToPlayer( this );
  14. @@ -11293,7 +11293,7 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
  15. }
  16. }
  17. - if( IsInWorld() && update )
  18. + if (IsInWorld() && update)
  19. {
  20. pItem->AddToWorld();
  21. pItem->SendCreateUpdateToPlayer( this );
  22. @@ -11315,12 +11315,12 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
  23. else
  24. {
  25. pItem2->SetCount( pItem2->GetCount() + pItem->GetCount() );
  26. - if( IsInWorld() && update )
  27. + if (IsInWorld() && update)
  28. pItem2->SendCreateUpdateToPlayer( this );
  29. // delete item (it not in any slot currently)
  30. //pItem->DeleteFromDB();
  31. - if( IsInWorld() && update )
  32. + if (IsInWorld() && update)
  33. {
  34. pItem->RemoveFromWorld();
  35. pItem->DestroyForPlayer( this );
  36. @@ -11618,7 +11618,7 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
  37. else if(Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ))
  38. pBag->RemoveItem(slot, update);
  39. - if( IsInWorld() && update )
  40. + if (IsInWorld() && update)
  41. {
  42. pItem->RemoveFromWorld();
  43. pItem->DestroyForPlayer(this);
  44. @@ -11631,15 +11631,15 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
  45. }
  46. }
  47. -void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool unequip_check)
  48. +void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check, bool inBankAlso)
  49. {
  50. - DEBUG_LOG( "STORAGE: DestroyItemCount item = %u, count = %u", item, count);
  51. + DEBUG_LOG("STORAGE: DestroyItemCount item = %u, count = %u", item, count);
  52. uint32 remcount = 0;
  53. // in inventory
  54. - for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
  55. + for (int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
  56. {
  57. - if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
  58. + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  59. {
  60. if (pItem->GetEntry() == item && !pItem->IsInTrade())
  61. {
  62. @@ -11647,17 +11647,17 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  63. {
  64. // all items in inventory can unequipped
  65. remcount += pItem->GetCount();
  66. - DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
  67. + DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
  68. if (remcount >= count)
  69. return;
  70. }
  71. else
  72. {
  73. - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
  74. - pItem->SetCount( pItem->GetCount() - count + remcount );
  75. - if (IsInWorld() & update)
  76. - pItem->SendCreateUpdateToPlayer( this );
  77. + ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
  78. + pItem->SetCount(pItem->GetCount() - count + remcount);
  79. + if (IsInWorld() && update)
  80. + pItem->SendCreateUpdateToPlayer(this);
  81. pItem->SetState(ITEM_CHANGED, this);
  82. return;
  83. }
  84. @@ -11665,9 +11665,9 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  85. }
  86. }
  87. - for(int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
  88. + for (int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
  89. {
  90. - if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
  91. + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  92. {
  93. if (pItem->GetEntry() == item && !pItem->IsInTrade())
  94. {
  95. @@ -11675,17 +11675,17 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  96. {
  97. // all keys can be unequipped
  98. remcount += pItem->GetCount();
  99. - DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
  100. + DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
  101. if (remcount >= count)
  102. return;
  103. }
  104. else
  105. {
  106. - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
  107. - pItem->SetCount( pItem->GetCount() - count + remcount );
  108. - if (IsInWorld() & update)
  109. - pItem->SendCreateUpdateToPlayer( this );
  110. + ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
  111. + pItem->SetCount(pItem->GetCount() - count + remcount);
  112. + if (IsInWorld() && update)
  113. + pItem->SendCreateUpdateToPlayer(this);
  114. pItem->SetState(ITEM_CHANGED, this);
  115. return;
  116. }
  117. @@ -11694,13 +11694,13 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  118. }
  119. // in inventory bags
  120. - for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
  121. + for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
  122. {
  123. - if(Bag *pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
  124. + if (Bag *pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  125. {
  126. - for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
  127. + for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
  128. {
  129. - if(Item* pItem = pBag->GetItemByPos(j))
  130. + if (Item* pItem = pBag->GetItemByPos(j))
  131. {
  132. if (pItem->GetEntry() == item && !pItem->IsInTrade())
  133. {
  134. @@ -11708,17 +11708,17 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  135. if (pItem->GetCount() + remcount <= count)
  136. {
  137. remcount += pItem->GetCount();
  138. - DestroyItem( i, j, update );
  139. + DestroyItem(i, j, update);
  140. if (remcount >= count)
  141. return;
  142. }
  143. else
  144. {
  145. - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
  146. - pItem->SetCount( pItem->GetCount() - count + remcount );
  147. + ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
  148. + pItem->SetCount(pItem->GetCount() - count + remcount);
  149. if (IsInWorld() && update)
  150. - pItem->SendCreateUpdateToPlayer( this );
  151. + pItem->SendCreateUpdateToPlayer(this);
  152. pItem->SetState(ITEM_CHANGED, this);
  153. return;
  154. }
  155. @@ -11729,18 +11729,18 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  156. }
  157. // in equipment and bag list
  158. - for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i)
  159. + for (int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_BAG_END; ++i)
  160. {
  161. - if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
  162. + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  163. {
  164. if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade())
  165. {
  166. if (pItem->GetCount() + remcount <= count)
  167. {
  168. - if (!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i, false) == EQUIP_ERR_OK )
  169. + if (!unequip_check || CanUnequipItem(INVENTORY_SLOT_BAG_0 << 8 | i, false) == EQUIP_ERR_OK)
  170. {
  171. remcount += pItem->GetCount();
  172. - DestroyItem( INVENTORY_SLOT_BAG_0, i, update);
  173. + DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
  174. if (remcount >= count)
  175. return;
  176. @@ -11748,16 +11748,80 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
  177. }
  178. else
  179. {
  180. - ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
  181. - pItem->SetCount( pItem->GetCount() - count + remcount );
  182. - if (IsInWorld() & update)
  183. - pItem->SendCreateUpdateToPlayer( this );
  184. + ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
  185. + pItem->SetCount(pItem->GetCount() - count + remcount);
  186. + if (IsInWorld() && update)
  187. + pItem->SendCreateUpdateToPlayer(this);
  188. pItem->SetState(ITEM_CHANGED, this);
  189. return;
  190. }
  191. }
  192. }
  193. }
  194. +
  195. + if (inBankAlso)
  196. + {
  197. + // in bank
  198. + for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
  199. + {
  200. + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  201. + {
  202. + if (pItem->GetEntry() == item && !pItem->IsInTrade())
  203. + {
  204. + if (pItem->GetCount() + remcount <= count)
  205. + {
  206. + remcount += pItem->GetCount();
  207. + DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
  208. +
  209. + if (remcount >= count)
  210. + return;
  211. + }
  212. + else
  213. + {
  214. + ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
  215. + pItem->SetCount(pItem->GetCount() - count + remcount);
  216. + if (IsInWorld() && update)
  217. + pItem->SendCreateUpdateToPlayer(this);
  218. + pItem->SetState(ITEM_CHANGED, this);
  219. + return;
  220. + }
  221. + }
  222. + }
  223. + }
  224. +
  225. + for (int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
  226. + {
  227. + if (Bag *pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
  228. + {
  229. + for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
  230. + {
  231. + if (Item* pItem = pBag->GetItemByPos(j))
  232. + {
  233. + if (pItem->GetEntry() == item && !pItem->IsInTrade())
  234. + {
  235. + if (pItem->GetCount() + remcount <= count)
  236. + {
  237. + remcount += pItem->GetCount();
  238. + DestroyItem(i, j, update);
  239. +
  240. + if (remcount >= count)
  241. + return;
  242. + }
  243. + else
  244. + {
  245. + ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
  246. + pItem->SetCount(pItem->GetCount() - count + remcount);
  247. + if (IsInWorld() && update)
  248. + pItem->SendCreateUpdateToPlayer(this);
  249. + pItem->SetState(ITEM_CHANGED, this);
  250. + return;
  251. + }
  252. + }
  253. + }
  254. + }
  255. + }
  256. + }
  257. + }
  258. }
  259. void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone )
  260. @@ -11835,7 +11899,7 @@ void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update )
  261. ItemRemovedQuestCheck( pItem->GetEntry(), count);
  262. pItem->SetCount( pItem->GetCount() - count );
  263. count = 0;
  264. - if( IsInWorld() & update )
  265. + if (IsInWorld() && update)
  266. pItem->SendCreateUpdateToPlayer( this );
  267. pItem->SetState(ITEM_CHANGED, this);
  268. }
  269. @@ -13958,12 +14022,22 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,
  270. {
  271. uint32 quest_id = pQuest->GetQuestId();
  272. - for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i )
  273. + for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
  274. {
  275. if (pQuest->ReqItemId[i])
  276. DestroyItemCount(pQuest->ReqItemId[i], pQuest->ReqItemCount[i], true);
  277. }
  278. + for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
  279. + {
  280. + if (pQuest->ReqSourceId[i])
  281. + {
  282. + ItemPrototype const* iProto = ObjectMgr::GetItemPrototype(pQuest->ReqSourceId[i]);
  283. + if (iProto && iProto->Bonding == BIND_QUEST_ITEM)
  284. + DestroyItemCount(pQuest->ReqSourceId[i], pQuest->ReqSourceCount[i], true, false, true);
  285. + }
  286. + }
  287. +
  288. RemoveTimedQuest(quest_id);
  289. if (BattleGround* bg = GetBattleGround())
  290. @@ -23200,4 +23274,4 @@ void Player::_fillGearScoreData(Item* item, GearScoreVec* gearScore, uint32& two
  291. default:
  292. break;
  293. }
  294. -}
  295. +}
  296. \ No newline at end of file
  297. diff --git a/src/game/Player.h b/src/game/Player.h
  298. index 5b2e8ec..8fa5fb4 100644
  299. --- a/src/game/Player.h
  300. +++ b/src/game/Player.h
  301. @@ -1240,7 +1240,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  302. // in trade, guild bank, mail....
  303. void RemoveItemDependentAurasAndCasts( Item * pItem );
  304. void DestroyItem( uint8 bag, uint8 slot, bool update );
  305. - void DestroyItemCount( uint32 item, uint32 count, bool update, bool unequip_check = false);
  306. + void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check = false, bool inBankAlso = false);
  307. void DestroyItemCount( Item* item, uint32& count, bool update );
  308. void DestroyConjuredItems( bool update );
  309. void DestroyZoneLimitedItem( bool update, uint32 new_zone );
  310. @@ -1342,7 +1342,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  311. void AddQuest( Quest const *pQuest, Object *questGiver );
  312. void CompleteQuest( uint32 quest_id );
  313. void IncompleteQuest( uint32 quest_id );
  314. - void RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce = true );
  315. + void RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver, bool announce = true);
  316. void FailQuest( uint32 quest_id );
  317. bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
  318. diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
  319. index 88536e1..df2fcfa 100644
  320. --- a/src/game/QuestHandler.cpp
  321. +++ b/src/game/QuestHandler.cpp
  322. @@ -320,22 +320,30 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data)
  323. uint8 slot;
  324. recv_data >> slot;
  325. - DEBUG_LOG( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u",slot );
  326. + DEBUG_LOG("WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u",slot);
  327. - if( slot < MAX_QUEST_LOG_SIZE )
  328. + if (slot < MAX_QUEST_LOG_SIZE)
  329. {
  330. - if(uint32 quest = _player->GetQuestSlotQuestId(slot))
  331. + if (uint32 quest = _player->GetQuestSlotQuestId(slot))
  332. {
  333. - if(!_player->TakeQuestSourceItem( quest, true ))
  334. + if (!_player->TakeQuestSourceItem(quest, true))
  335. return; // can't un-equip some items, reject quest cancel
  336. - if (const Quest *pQuest = sObjectMgr.GetQuestTemplate(quest))
  337. + const Quest *pQuest = sObjectMgr.GetQuestTemplate(quest);
  338. + if (pQuest->HasSpecialFlag(QUEST_SPECIAL_FLAG_TIMED))
  339. + _player->RemoveTimedQuest(quest);
  340. +
  341. + for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
  342. {
  343. - if (pQuest->HasSpecialFlag(QUEST_SPECIAL_FLAG_TIMED))
  344. - _player->RemoveTimedQuest(quest);
  345. + if (pQuest->ReqSourceId[i])
  346. + {
  347. + ItemPrototype const* iProto = ObjectMgr::GetItemPrototype(pQuest->ReqSourceId[i]);
  348. + if (iProto && iProto->Bonding == BIND_QUEST_ITEM)
  349. + _player->DestroyItemCount(pQuest->ReqSourceId[i], pQuest->ReqSourceCount[i], true, false, true);
  350. + }
  351. }
  352. - _player->SetQuestStatus( quest, QUEST_STATUS_NONE);
  353. + _player->SetQuestStatus(quest, QUEST_STATUS_NONE);
  354. }
  355. _player->SetQuestSlot(slot, 0);

REMOVE_REQ_SOURCE_ITEM