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); }
public static bool BuildEnumData(SQLResult result, ref PacketWriter data) { for (int c = 0; c < result.Count; c++) { ObjectGuid guid = new ObjectGuid(result.Read <ulong>(c, 0)); ObjectGuid guildGuid = new ObjectGuid();//result.Read<uint>(c, 13)); string name = result.Read <string>(c, 1); data.WriteBit(guid[7]); data.WriteBit(guid[0]); data.WriteBit(guid[4]); data.WriteBit(guildGuid[2]); data.WriteBit(guid[5]); data.WriteBit(guid[3]); data.WriteBits(name.Length, 7); data.WriteBit(guildGuid[0]); data.WriteBit(guildGuid[5]); data.WriteBit(guildGuid[3]); data.WriteBit(0); data.WriteBit(guildGuid[6]); data.WriteBit(guildGuid[7]); data.WriteBit(guid[1]); data.WriteBit(guildGuid[4]); data.WriteBit(guildGuid[1]); data.WriteBit(guid[2]); data.WriteBit(guid[6]); } data.WriteBit(1); data.BitFlush(); for (int c = 0; c < result.Count; c++) { ObjectGuid guid = new ObjectGuid(result.Read <ulong>(c, 0)); string name = result.Read <string>(c, 1); byte plrRace = result.Read <byte>(c, 2); Class plrClass = (Class)result.Read <byte>(c, 3); byte gender = result.Read <byte>(c, 4); byte skin = (byte)(result.Read <uint>(c, 5) & 0xFF); byte face = (byte)((result.Read <uint>(c, 5) >> 8) & 0xFF); byte hairStyle = (byte)((result.Read <uint>(c, 5) >> 16) & 0xFF); byte hairColor = (byte)((result.Read <uint>(c, 5) >> 24) & 0xFF); byte facialHair = (byte)(result.Read <uint>(c, 6) & 0xFF); byte level = result.Read <byte>(c, 7); uint zone = result.Read <uint>(c, 8); uint mapId = result.Read <uint>(c, 9); float x = result.Read <float>(c, 10); float y = result.Read <float>(c, 11); float z = result.Read <float>(c, 12); ObjectGuid guildGuid = new ObjectGuid();//result.Read<ulong>(c, 13)); PlayerFlags playerFlags = (PlayerFlags)result.Read <uint>(c, 14); AtLoginFlags atLoginFlags = (AtLoginFlags)result.Read <uint>(c, 15); string[] equipment = result.Read <string>(c, 19).Split(' '); byte slot = result.Read <byte>(c, 21); CharacterFlags charFlags = 0; if (Convert.ToBoolean(playerFlags & PlayerFlags.HideHelm)) { charFlags |= CharacterFlags.HideHelm; } if (Convert.ToBoolean(playerFlags & PlayerFlags.HideCloak)) { charFlags |= CharacterFlags.HideCloak; } if (Convert.ToBoolean(playerFlags & PlayerFlags.Ghost)) { charFlags |= CharacterFlags.Ghost; } if (Convert.ToBoolean(atLoginFlags & AtLoginFlags.Rename)) { charFlags |= CharacterFlags.Rename; } //if (result.Read<uint>(c, 20) != 0) //charFlags |= CharacterFlags.LockedByBilling; //if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) && !fields[22].GetString().empty()) //charFlags |= CHARACTER_FLAG_DECLINED; CharacterCustomizeFlags customizationFlag = 0; if (Convert.ToBoolean(atLoginFlags & AtLoginFlags.Customize)) { customizationFlag = CharacterCustomizeFlags.Customize; } else if (Convert.ToBoolean(atLoginFlags & AtLoginFlags.ChangeFaction)) { customizationFlag = CharacterCustomizeFlags.Faction; } else if (Convert.ToBoolean(atLoginFlags & AtLoginFlags.ChangeRace)) { customizationFlag = CharacterCustomizeFlags.Race; } uint petDisplayId = 0; uint petLevel = 0; uint petFamily = 0; // show pet at selection character in character list only for non-ghost character if (!Convert.ToBoolean(playerFlags & PlayerFlags.Ghost) && (plrClass == Class.Warlock || plrClass == Class.Hunter || plrClass == Class.Deathknight)) { //uint entry = result.Read<uint>(c, 16); //var creatureInfo = ObjMgr.GetCreatureTemplate(entry); //if (creatureInfo != null) { //petDisplayId = result.Read<uint>(c, 17); //petLevel = result.Read<uint>(c, 18); //petFamily = creatureInfo.Family; } } data.WriteUInt32(charFlags); data.WriteUInt32(petFamily); data.WriteFloat(z); data.WriteByteSeq(guid[7]); data.WriteByteSeq(guildGuid[6]); for (uint i = 0; i < InventorySlots.BagEnd; ++i) { uint index = i * 2; uint itemId; uint.TryParse(equipment[index], out itemId); var entry = ObjMgr.GetItemTemplate(itemId); if (entry == null) { data.WriteInt32(0); data.WriteInt8(0); data.WriteInt32(0); continue; } uint enchants; SpellItemEnchantmentEntry enchant = null; uint.TryParse(equipment[index + 1], out enchants); for (int enchantSlot = (int)EnchantmentSlot.PERM_ENCHANTMENT_SLOT; enchantSlot <= (int)EnchantmentSlot.TEMP_ENCHANTMENT_SLOT; enchantSlot++) { // values stored in 2 uint16 uint enchantId = 0x0000FFFF & (enchants >> enchantSlot * 16); if (enchantId == 0) { continue; } enchant = DBCStorage.SpellItemEnchantmentStorage.LookupByKey(enchantId); if (enchant != null) { break; } } data.WriteInt32(0);//enchant != null ? enchant.aura_id : 0); data.WriteInt8(entry.inventoryType); data.WriteInt32(entry.DisplayInfoID); } data.WriteFloat(x); data.WriteUInt8(plrClass); data.WriteByteSeq(guid[5]); data.WriteFloat(y); data.WriteByteSeq(guildGuid[3]); data.WriteByteSeq(guid[6]); data.WriteUInt32(petLevel); data.WriteUInt32(petDisplayId); data.WriteByteSeq(guid[2]); data.WriteByteSeq(guid[1]); data.WriteUInt8(hairColor); data.WriteUInt8(facialHair); data.WriteByteSeq(guildGuid[2]); data.WriteUInt32(zone); data.WriteUInt8(slot); // List order data.WriteByteSeq(guid[0]); data.WriteByteSeq(guildGuid[1]); data.WriteUInt8(skin); data.WriteByteSeq(guid[4]); data.WriteByteSeq(guildGuid[5]); data.WriteString(name); data.WriteByteSeq(guildGuid[0]); data.WriteUInt8(level); data.WriteByteSeq(guid[3]); data.WriteByteSeq(guildGuid[7]); data.WriteUInt8(hairStyle); data.WriteByteSeq(guildGuid[4]); data.WriteUInt8(gender); data.WriteUInt32(mapId); data.WriteUInt32((uint)customizationFlag); data.WriteUInt8(plrRace); data.WriteUInt8(face); } return(true); }