public void SendListInventory(ObjectGuid vendorGuid) { Creature vendor = GetPlayer().GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor); if (vendor == null) { Log.outDebug(LogFilter.Network, "WORLD: SendListInventory - {0} not found or you can not interact with him.", vendorGuid.ToString()); GetPlayer().SendSellError(SellResult.CantFindVendor, null, ObjectGuid.Empty); return; } // remove fake death if (GetPlayer().HasUnitState(UnitState.Died)) { GetPlayer().RemoveAurasByType(AuraType.FeignDeath); } // Stop the npc if moving if (vendor.HasUnitState(UnitState.Moving)) { vendor.StopMoving(); } VendorItemData vendorItems = vendor.GetVendorItems(); int rawItemCount = vendorItems != null?vendorItems.GetItemCount() : 0; VendorInventory packet = new VendorInventory(); packet.Vendor = vendor.GetGUID(); float discountMod = GetPlayer().GetReputationPriceDiscount(vendor); byte count = 0; for (uint slot = 0; slot < rawItemCount; ++slot) { VendorItem vendorItem = vendorItems.GetItem(slot); if (vendorItem == null) { continue; } VendorItemPkt item = new VendorItemPkt(); PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(vendorItem.PlayerConditionId); if (playerCondition != null) { if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition)) { item.PlayerConditionFailed = (int)playerCondition.Id; } } if (vendorItem.Type == ItemVendorType.Item) { ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(vendorItem.item); if (itemTemplate == null) { continue; } int leftInStock = vendorItem.maxcount == 0 ? -1 : (int)vendor.GetVendorItemCurrentCount(vendorItem); if (!GetPlayer().IsGameMaster()) { if (!Convert.ToBoolean(itemTemplate.GetAllowableClass() & GetPlayer().getClassMask()) && itemTemplate.GetBonding() == ItemBondingType.OnAcquire) { continue; } if ((itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionHorde) && GetPlayer().GetTeam() == Team.Alliance) || (itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionAlliance) && GetPlayer().GetTeam() == Team.Horde)) { continue; } if (leftInStock == 0) { continue; } } if (!Global.ConditionMgr.IsObjectMeetingVendorItemConditions(vendor.GetEntry(), vendorItem.item, _player, vendor)) { Log.outDebug(LogFilter.Condition, "SendListInventory: conditions not met for creature entry {0} item {1}", vendor.GetEntry(), vendorItem.item); continue; } int price = (int)(vendorItem.IsGoldRequired(itemTemplate) ? Math.Floor(itemTemplate.GetBuyPrice() * discountMod) : 0); int priceMod = GetPlayer().GetTotalAuraModifier(AuraType.ModVendorItemsPrices); if (priceMod != 0) { price -= MathFunctions.CalculatePct(price, priceMod); } item.MuID = (int)slot + 1; item.Durability = (int)itemTemplate.MaxDurability; item.ExtendedCostID = (int)vendorItem.ExtendedCost; item.Type = (int)vendorItem.Type; item.Quantity = leftInStock; item.StackCount = (int)itemTemplate.GetBuyCount(); item.Price = (ulong)price; item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering; item.Item.ItemID = vendorItem.item; if (!vendorItem.BonusListIDs.Empty()) { item.Item.ItemBonus.HasValue = true; item.Item.ItemBonus.Value.BonusListIDs = vendorItem.BonusListIDs; } packet.Items.Add(item); } else if (vendorItem.Type == ItemVendorType.Currency) { CurrencyTypesRecord currencyTemplate = CliDB.CurrencyTypesStorage.LookupByKey(vendorItem.item); if (currencyTemplate == null) { continue; } if (vendorItem.ExtendedCost == 0) { continue; // there's no price defined for currencies, only extendedcost is used } item.MuID = (int)slot + 1; // client expects counting to start at 1 item.ExtendedCostID = (int)vendorItem.ExtendedCost; item.Item.ItemID = vendorItem.item; item.Type = (int)vendorItem.Type; item.StackCount = (int)vendorItem.maxcount; item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering; packet.Items.Add(item); } else { continue; } if (++count >= SharedConst.MaxVendorItems) { break; } } SendPacket(packet); }
static void SendListInventory(ulong vendorGuid, ref WorldSession session) { Log.outDebug("WORLD: Sent SMSG_LIST_INVENTORY"); Player pl = session.GetPlayer(); Creature vendor = pl.GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor); if (vendor == null) { Log.outDebug("WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", ObjectGuid.GuidLowPart(vendorGuid)); session.GetPlayer().SendSellError(SellResult.CantFindVendor, null, 0); return; } // remove fake death //if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) //GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving //if (vendor.HasUnitState(UNIT_STATE_MOVING)) //vendor->StopMoving(); VendorItemData vendorItems = vendor.GetVendorItems(); int rawItemCount = vendorItems != null?vendorItems.GetItemCount() : 0; List <bool> enablers = new List <bool>(); PacketWriter itemsData = new PacketWriter(); float discountMod = session.GetPlayer().GetReputationPriceDiscount(vendor); ushort count = 0; for (ushort slot = 0; slot < rawItemCount; ++slot) { VendorItem vendorItem = vendorItems.GetItem(slot); if (vendorItem == null) { continue; } if (vendorItem.Type == (byte)ItemVendorType.Item) { ItemTemplate itemTemplate = ObjMgr.GetItemTemplate(vendorItem.item); if (itemTemplate == null) { continue; } uint leftInStock = vendorItem.maxcount == 0 ? 0xFFFFFFFF : vendor.GetVendorItemCurrentCount(vendorItem); if (!pl.isGameMaster()) // ignore conditions if GM on { // Respect allowed class if (!Convert.ToBoolean(itemTemplate.AllowableClass & pl.getClassMask()) && itemTemplate.Bonding == ItemBondingType.PickedUp) { continue; } // Only display items in vendor lists for the team the player is on if ((Convert.ToBoolean(itemTemplate.Flags2 & ItemFlags2.HordeOnly) && pl.GetTeam() == Team.Alliance) || (Convert.ToBoolean(itemTemplate.Flags2 & ItemFlags2.AllianceOnly) && pl.GetTeam() == Team.Horde)) { continue; } // Items sold out are not displayed in list if (leftInStock == 0) { continue; } } int price = vendorItem.IsGoldRequired(itemTemplate) ? (int)(Math.Floor(itemTemplate.BuyPrice * discountMod)) : 0; //int priceMod = pl.GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES) //if (priceMod != 0) //price -= CalculatePctN(price, priceMod); itemsData.WriteUInt32(count++ + 1); // client expects counting to start at 1 itemsData.WriteUInt32(itemTemplate.MaxDurability); if (vendorItem.ExtendedCost != 0) { enablers.Add(false); itemsData.WriteUInt32(vendorItem.ExtendedCost); } else { enablers.Add(true); } enablers.Add(true); // unk bit itemsData.WriteUInt32(vendorItem.item); itemsData.WriteUInt32(vendorItem.Type); // 1 is items, 2 is currency itemsData.WriteUInt32(price); itemsData.WriteUInt32(itemTemplate.DisplayInfoID); // if (!unk "enabler") data << uint32(something); itemsData.WriteUInt32(leftInStock); itemsData.WriteUInt32(itemTemplate.BuyCount); } else if (vendorItem.Type == (byte)ItemVendorType.Currency) { CurrencyTypesEntry currencyTemplate = DBCStorage.CurrencyTypesStorage.LookupByKey(vendorItem.item); if (currencyTemplate == null) { continue; } if (vendorItem.ExtendedCost == 0) { continue; // there's no price defined for currencies, only extendedcost is used } uint precision = (uint)(Convert.ToBoolean(currencyTemplate.Flags & (uint)CurrencyFlags.HighPrecision) ? 100 : 1); itemsData.WriteUInt32(count++ + 1); // client expects counting to start at 1 itemsData.WriteUInt32(0); // max durability if (vendorItem.ExtendedCost != 0) { enablers.Add(false); itemsData.WriteUInt32(vendorItem.ExtendedCost); } else { enablers.Add(true); } enablers.Add(true); // unk bit itemsData.WriteUInt32(vendorItem.item); itemsData.WriteUInt32(vendorItem.Type); // 1 is items, 2 is currency itemsData.WriteUInt32(0); // price, only seen currency types that have Extended cost itemsData.WriteUInt32(0); // displayId // if (!unk "enabler") data << uint32(something); itemsData.WriteInt32(-1); itemsData.WriteUInt32(vendorItem.maxcount * precision); } // else error } ObjectGuid guid = new ObjectGuid(vendorGuid); PacketWriter data = new PacketWriter(Opcodes.SMSG_ListInventory); data.WriteBit(guid[1]); data.WriteBit(guid[0]); data.WriteBits(count, 21); // item count data.WriteBit(guid[3]); data.WriteBit(guid[6]); data.WriteBit(guid[5]); data.WriteBit(guid[2]); data.WriteBit(guid[7]); foreach (var itr in enablers) { data.WriteBit(itr); } data.WriteBit(guid[4]); data.BitFlush(); data.WriteBytes(itemsData); data.WriteByteSeq(guid[5]); data.WriteByteSeq(guid[4]); data.WriteByteSeq(guid[1]); data.WriteByteSeq(guid[0]); data.WriteByteSeq(guid[6]); data.WriteUInt8(count == 0); // unk byte, item count 0: 1, item count != 0: 0 or some "random" value below 300 data.WriteByteSeq(guid[2]); data.WriteByteSeq(guid[3]); data.WriteByteSeq(guid[7]); session.Send(data); }