예제 #1
0
        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);
        }
예제 #2
0
        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);
        }