Guest User

Untitled

a guest
Apr 16th, 2017
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.95 KB | None | 0 0
  1. void WorldSession::SendListInventory(uint64 vendorGuid, uint32 vendorEntry)
  2. {
  3. TC_LOG_DEBUG("network.opcode", "WORLD: Sent SMSG_LIST_INVENTORY");
  4.  
  5. Creature* vendor = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
  6. if (!vendor)
  7. {
  8. TC_LOG_DEBUG("network.opcode", "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorGuid)));
  9. _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0);
  10. return;
  11. }
  12.  
  13. // remove fake death
  14. if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
  15. GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
  16.  
  17. // Stop the npc if moving
  18. if (vendor->HasUnitState(UNIT_STATE_MOVING))
  19. vendor->StopMoving();
  20.  
  21. //VendorItemData const* vendorItems = vendor->GetVendorItems();
  22. //VendorItemData const* items = vendorEntry ? sObjectMgr->GetNpcVendorItemList(vendorEntry) : vendor->GetVendorItems();
  23. VendorItemData const* vendorItems = vendorEntry ? sObjectMgr->GetNpcVendorItemList(vendorEntry) : vendor->GetVendorItems();
  24. /*if (!vendorItems)
  25. {
  26. WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);*/
  27. uint16 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
  28.  
  29. ByteBuffer itemsData(32 * rawItemCount);
  30. std::vector<bool> enablers;
  31. enablers.reserve(2 * rawItemCount);
  32.  
  33. SetCurrentVendor(vendorEntry, GUID_LOPART(vendorGuid), GUID_HIPART(vendorGuid));
  34.  
  35. const float discountMod = _player->GetReputationPriceDiscount(vendor);
  36. uint16 count = 0;
  37. for (uint16 slot = 0; slot < rawItemCount; ++slot)
  38. {
  39. if (count == 300)
  40. {
  41. TC_LOG_ERROR("sql.sql", "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", count, MAX_VENDOR_ITEMS, vendor->GetEntry());
  42. break;
  43. }
  44. VendorItem const* vendorItem = vendorItems->GetItem(slot);
  45. if (!vendorItem) continue;
  46.  
  47. if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM)
  48. {
  49. ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item);
  50. if (!itemTemplate)
  51. continue;
  52.  
  53. uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
  54. if (!_player->isGameMaster()) // ignore conditions if GM on
  55. {
  56. // Respect allowed class
  57. if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP)
  58. continue;
  59.  
  60. // Only display items in vendor lists for the team the player is on
  61. if ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) ||
  62. (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))
  63. continue;
  64.  
  65. // Items sold out are not displayed in list
  66. if (leftInStock == 0)
  67. continue;
  68. }
  69.  
  70. ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), vendorItem->item);
  71. if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
  72. {
  73. TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), vendorItem->item);
  74. continue;
  75. }
  76.  
  77. int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
  78.  
  79. if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES))
  80. price -= CalculatePct(price, priceMod);
  81.  
  82. ++count;
  83. itemsData << uint32(slot + 1); // client expects counting to start at 1
  84. itemsData << uint32(itemTemplate->MaxDurability);
  85.  
  86. if (vendorItem->ExtendedCost != 0)
  87. {
  88. enablers.push_back(0);
  89. itemsData << uint32(vendorItem->ExtendedCost);
  90. }
  91. else
  92. enablers.push_back(1);
  93. enablers.push_back(1); // unk bit
  94.  
  95. itemsData << uint32(vendorItem->item);
  96. itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
  97. itemsData << uint32(price);
  98. itemsData << uint32(itemTemplate->DisplayInfoID);
  99. // if (!unk "enabler") data << uint32(something);
  100. itemsData << int32(leftInStock);
  101. itemsData << uint32(itemTemplate->BuyCount);
  102. }
  103. else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY)
  104. {
  105. CurrencyTypesEntry const* currencyTemplate = sCurrencyTypesStore.LookupEntry(vendorItem->item);
  106. if (!currencyTemplate)
  107. continue;
  108.  
  109. if (vendorItem->ExtendedCost == 0)
  110. continue; // there's no price defined for currencies, only extendedcost is used
  111.  
  112. ++count;
  113. itemsData << uint32(slot + 1); // client expects counting to start at 1
  114. itemsData << uint32(0); // max durability
  115.  
  116. if (vendorItem->ExtendedCost != 0)
  117. {
  118. enablers.push_back(0);
  119. itemsData << uint32(vendorItem->ExtendedCost);
  120. }
  121. else
  122. enablers.push_back(1);
  123.  
  124. enablers.push_back(1); // unk bit
  125.  
  126. itemsData << uint32(vendorItem->item);
  127. itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
  128. itemsData << uint32(0); // price, only seen currency types that have Extended cost
  129. itemsData << uint32(0); // displayId
  130. // if (!unk "enabler") data << uint32(something);
  131. itemsData << int32(-1);
  132. itemsData << uint32(vendorItem->maxcount);
  133. }
  134. // else error
  135. }
  136.  
  137. ObjectGuid guid = vendorGuid;
  138.  
  139. WorldPacket data(SMSG_LIST_INVENTORY, 12 + itemsData.size());
  140.  
  141. data.WriteBit(guid[1]);
  142. data.WriteBit(guid[0]);
  143.  
  144. data.WriteBits(count, 21); // item count
  145.  
  146. data.WriteBit(guid[3]);
  147. data.WriteBit(guid[6]);
  148. data.WriteBit(guid[5]);
  149. data.WriteBit(guid[2]);
  150. data.WriteBit(guid[7]);
  151.  
  152. for (std::vector<bool>::const_iterator itr = enablers.begin(); itr != enablers.end(); ++itr)
  153. data.WriteBit(*itr);
  154.  
  155. data.WriteBit(guid[4]);
  156.  
  157. data.FlushBits();
  158. data.append(itemsData);
  159.  
  160. data.WriteByteSeq(guid[5]);
  161. data.WriteByteSeq(guid[4]);
  162. data.WriteByteSeq(guid[1]);
  163. data.WriteByteSeq(guid[0]);
  164. data.WriteByteSeq(guid[6]);
  165.  
  166. data << uint8(count == 0); // unk byte, item count 0: 1, item count != 0: 0 or some "random" value below 300
  167.  
  168. data.WriteByteSeq(guid[2]);
  169. data.WriteByteSeq(guid[3]);
  170. data.WriteByteSeq(guid[7]);
  171.  
  172. SendPacket(&data);
  173. }
Add Comment
Please, Sign In to add comment