Beispiel #1
0
 protected GW_ItemSlotBase(int nItemID)
 {
     this.nItemID   = nItemID;
     InvType        = ItemConstants.GetInventoryType(nItemID);
     IsRechargeable = ItemConstants.IsRechargeableItem(nItemID);
     IsArrow        = ItemConstants.IsArrow(nItemID);
 }
Beispiel #2
0
        public async Task <ShopResult> Sell(short position, int templateID, short count)
        {
            var inventory = User.Character.Inventories[(ItemInventoryType)(templateID / 1000000)];

            if (!inventory.Items.ContainsKey(position))
            {
                return(ShopResult.SellUnknown);
            }

            var itemSlot = inventory.Items[position];
            var item     = User.Service.TemplateManager.Get <ItemTemplate>(itemSlot.TemplateID);
            var price    = item.SellPrice;

            if (ItemConstants.IsRechargeableItem(item.ID))
            {
                price += (int)((itemSlot as ItemSlotBundle)?.Number *
                               (item as ItemBundleTemplate)?.UnitPrice ?? 0);
            }
            else
            {
                price *= count;
            }

            if (int.MaxValue - User.Character.Money < price)
            {
                return(ShopResult.SellUnknown);
            }

            await User.ModifyInventory(i => i.Remove(itemSlot, count));

            await User.ModifyStats(s => s.Money += price);

            return(ShopResult.SellSuccess);
        }
Beispiel #3
0
        public override async Task Enter()
        {
            using var p = new Packet(SendPacketOperations.OpenShopDlg);
            p.Encode <int>(_template.ID);

            var items = _template.Items.Values
                        .OrderBy(i => i.ID)
                        .ToList();

            p.Encode <short>((short)items.Count);
            items.ForEach(i =>
            {
                p.Encode <int>(i.TemplateID);
                p.Encode <int>(i.Price);
                p.Encode <byte>(i.DiscountRate);
                p.Encode <int>(i.TokenTemplateID);
                p.Encode <int>(i.TokenPrice);
                p.Encode <int>(i.ItemPeriod);
                p.Encode <int>(i.LevelLimited);

                if (!ItemConstants.IsRechargeableItem(i.TemplateID))
                {
                    p.Encode <short>(i.Quantity);
                }
                else
                {
                    p.Encode <double>(i.UnitPrice);
                }

                p.Encode <short>(i.MaxPerSlot);
            });

            await User.SendPacket(p);
        }
        public void Remove(int template, short count)
        {
            var removed = 0;

            _inventory.Items.Values
            .Where(i => i.TemplateID == template)
            .ForEach(i =>
            {
                if (removed >= count)
                {
                    return;
                }
                if (i is ItemSlotBundle bundle &&
                    !ItemConstants.IsRechargeableItem(bundle.TemplateID))
                {
                    var diff = count - removed;

                    if (bundle.Number > diff)
                    {
                        removed      += diff;
                        bundle.Number = (short)(bundle.Number - diff);
                        UpdateQuantity(bundle);
                    }
                    else
                    {
                        removed += bundle.Number;
                        Remove(bundle);
                    }
                }
Beispiel #5
0
        private static void RechargeItem(Character pChar, short nSlot)
        {
            var pItem = InventoryManipulator.GetItem(pChar, InventoryType.Consume, nSlot);

            if (pItem is null)
            {
                pChar.SendMessage("Trying to recharge null item.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeIncorrectRequest));
                return;
            }

            if (!ItemConstants.IsRechargeableItem(pItem.nItemID))
            {
                pChar.SendMessage("Trying to recharge item that isn't rechargeable.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeIncorrectRequest));
                return;
            }

            var slotmax = pItem.SlotMax;

            if (pChar.Skills.Get(false,
                                 (int)Skills.NIGHTWALKER_JAVELIN_MASTERY,
                                 (int)Skills.ASSASSIN_JAVELIN_MASTERY) is SkillEntry se)
            {
                slotmax += (short)se.Y_Effect;
            }

            if (pItem.nNumber >= slotmax)
            {
                pChar.SendMessage("Trying to recharge item that is fully charged.");
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeIncorrectRequest));
                return;
            }

            var dUnitPrice = (pItem.Template as ConsumeItemTemplate).UnitPrice;

            var nRechargeNeeded     = slotmax - pItem.nNumber;
            var nTotalRechargePrice = (int)Math.Floor(nRechargeNeeded * dUnitPrice);

            if (pChar.Stats.nMoney < nTotalRechargePrice)
            {
                pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeNoMoney));
                return;
            }

            pChar.Modify.GainMeso(-nTotalRechargePrice);

            pItem.nNumber = slotmax;

            pChar.Modify.Inventory(ctx =>
            {
                ctx.UpdateQuantity(InventoryType.Consume, nSlot, pItem.nNumber);
            });

            pChar.SendPacket(CPacket.CShopDlg.ShopResult(ShopRes.RechargeSuccess));
        }
        public void Add(ItemSlot item)
        {
            switch (item)
            {
            case ItemSlotBundle bundle:
                if (ItemConstants.IsRechargeableItem(bundle.TemplateID))
                {
                    goto default;
                }
                if (bundle.Number < 1)
                {
                    bundle.Number = 1;
                }
                if (bundle.MaxNumber < 1)
                {
                    bundle.MaxNumber = 1;
                }

                var mergeable = _inventory.Items.Values
                                .OfType <ItemSlotBundle>()
                                .Where(b => bundle.Number + b.Number <= b.MaxNumber)
                                .FirstOrDefault(b => b.Equals(bundle));

                if (mergeable != null)
                {
                    var count     = bundle.Number + mergeable.Number;
                    var maxNumber = mergeable.MaxNumber;

                    if (count > maxNumber)
                    {
                        var leftover = count - maxNumber;

                        bundle.Number    = (short)leftover;
                        mergeable.Number = maxNumber;
                        UpdateQuantity(mergeable);
                        Add(bundle);
                        return;
                    }

                    mergeable.Number += bundle.Number;
                    UpdateQuantity(mergeable);
                    return;
                }

                goto default;

            default:
                var slot = Enumerable.Range(1, _inventory.SlotMax)
                           .Select(i => (short)i)
                           .Except(_inventory.Items.Keys)
                           .First(i => i > 0);

                Set(slot, item);
                break;
            }
        }
        public void Add(ItemTemplate template, short quantity = 1, ItemVariationType type = ItemVariationType.None)
        {
            var item = template.ToItemSlot();

            if (item is ItemSlotBundle bundle &&
                !ItemConstants.IsRechargeableItem(bundle.TemplateID))
            {
                bundle.Number = quantity;
                Add(bundle);
            }
        public override void RawEncode(COutPacket p, bool bFromCS = false)
        {
            p.Encode1(2);

            base.RawEncode(p, bFromCS);

            p.Encode2(nNumber);
            p.EncodeString(sTitle);
            p.Encode2(nAttribute);

            if (ItemConstants.IsRechargeableItem(nItemID))
            {
                p.Encode8(liSN);
            }
        }
        public static void Encode(this ItemSlotBundle i, IPacket p)
        {
            p.Encode <byte>(2);

            i.EncodeBase(p);

            p.Encode <short>(i.Number);
            p.Encode <string>(i.Title);
            p.Encode <short>(i.Attribute);

            if (ItemConstants.IsRechargeableItem(i.TemplateID))
            {
                p.Encode <long>(0);
            }
        }
Beispiel #10
0
        public static GW_ItemSlotBase CreateItem(int nItemID, bool bRandStats = true)
        {
            if (nItemID <= 0)
            {
                return(null);
            }

            // TODO test the below
            if (ItemConstants.GetInventoryType(nItemID) != InventoryType.Equip)
            {
                GW_ItemSlotBase item;
                if (ItemConstants.IsPet(nItemID))
                {
                    item = new GW_ItemSlotPet(nItemID);
                    ((GW_ItemSlotPet)item).nRemainLife = 7776000;
                }
                else
                {
                    item = new GW_ItemSlotBundle(nItemID);
                }

                if (item.Template is null)
                {
                    throw new ArgumentOutOfRangeException(nameof(nItemID), "Doesn't exist in data files.");
                }

                if (ItemConstants.IsRechargeableItem(item.nItemID))
                {
                    item.nNumber = (short)item.Template.SlotMax;
                }
                else
                {
                    item.nNumber = 1;
                }

                item.tDateExpire = DateTime.MaxValue;

                return(item);
            }

            if (bRandStats)
            {
                return(CreateVariableStatEquip(nItemID));
            }

            return(CreateNormalStatEquip(nItemID));
        }
        public void Remove(ItemSlot item, short count)
        {
            if (item is ItemSlotBundle bundle &&
                !ItemConstants.IsRechargeableItem(bundle.TemplateID))
            {
                if (count > 0)
                {
                    bundle.Number -= count;
                    bundle.Number  = Math.Max((short)0, bundle.Number);

                    if (bundle.Number > 0)
                    {
                        UpdateQuantity(bundle);
                        return;
                    }
                }
            }

            Remove(item);
        }
Beispiel #12
0
        public void Encode(COutPacket p)
        {
            p.Encode4(nItemID);
            p.Encode4(nPrice);
            p.Encode1(nDiscountRate);
            p.Encode4(nTokenItemID);
            p.Encode4(nTokenPrice);
            p.Encode4(nItemPeriod);
            p.Encode4(nLevelLimited);

            if (ItemConstants.IsRechargeableItem(nItemID))
            {
                p.Encode8(dUnitPrice);
            }
            else
            {
                p.Encode2(nQuantity);
            }
            p.Encode2(nMaxPerSlot);
        }
        public void Add(ItemInventoryType type, ItemSlot item)
        {
            var inventory = _character.GetInventory(type);

            switch (item)
            {
            case ItemSlotBundle bundle:
                if (ItemConstants.IsRechargeableItem(bundle.TemplateID))
                {
                    goto default;
                }
                if (bundle.Number < 1)
                {
                    bundle.Number = 1;
                }
                if (bundle.MaxNumber < 1)
                {
                    bundle.MaxNumber = 1;
                }

                var mergeableSlots = inventory.Items
                                     .OfType <ItemSlotBundle>()
                                     .Where(b => b.TemplateID == bundle.TemplateID)
                                     .Where(b => b.DateExpire == bundle.DateExpire)
                                     .Where(b => b.Attribute == bundle.Attribute)
                                     .Where(b => b.Title == bundle.Title)
                                     .Where(b => b.Number != b.MaxNumber)
                                     .Where(b => b.Position > 0)
                                     .Where(b => b.Position <= inventory.SlotMax)
                                     .ToList();

                if (mergeableSlots.Count > 0)
                {
                    var existingBundle = mergeableSlots.First();

                    var count     = bundle.Number + existingBundle.Number;
                    var maxNumber = existingBundle.MaxNumber;

                    if (count > maxNumber)
                    {
                        var leftover = count - maxNumber;

                        bundle.Number         = (short)leftover;
                        existingBundle.Number = maxNumber;
                        UpdateQuantity(existingBundle);
                        Add(bundle);
                        return;
                    }

                    existingBundle.Number += bundle.Number;
                    UpdateQuantity(existingBundle);
                    return;
                }

                goto default;

            default:
                var usedSlots = inventory.Items
                                .Select <ItemSlot, int>(i => i.Position)
                                .Where(s => s > 0)
                                .Where(s => s <= inventory.SlotMax)
                                .ToList();
                var unusedSlots = Enumerable.Range(1, inventory.SlotMax)
                                  .Except(usedSlots)
                                  .ToList();

                if (unusedSlots.Count == 0)
                {
                    throw new InventoryFullException();
                }

                Set(type, item, (short)unusedSlots.First());
                break;
            }
        }
Beispiel #14
0
        public async Task <ShopResult> Buy(short position, short count)
        {
            try
            {
                var shopItems = _template.Items
                                .OrderBy(kv => kv.Key)
                                .Select(kv => kv.Value)
                                .Where(i => i.Price > 0 ||
                                       i.TokenPrice > 0)
                                .ToList();

                if (position > shopItems.Count)
                {
                    return(ShopResult.CantBuyAnymore);
                }

                var shopItem = shopItems[position];
                var item     = User.Service.TemplateManager.Get <ItemTemplate>(shopItem.TemplateID);

                if (shopItem.Quantity > 1)
                {
                    count = 1;
                }

                count = Math.Max(count, shopItem.MaxPerSlot);
                count = Math.Min(count, (short)1);

                if (item == null)
                {
                    return(ShopResult.BuyUnknown);
                }
                if (shopItem.Price > 0 &&
                    User.Character.Money < shopItem.Price * count)
                {
                    return(ShopResult.BuyNoMoney);
                }
                if (shopItem.TokenTemplateID > 0 &&
                    User.Character.GetItemCount(shopItem.TokenTemplateID) > shopItem.TokenPrice * count)
                {
                    return(ShopResult.BuyNoToken);
                }
                if (User.Character.Level < shopItem.LevelLimited)
                {
                    return(ShopResult.LimitLevel_Less);
                }

                var itemSlot = item.ToItemSlot();

                if (itemSlot is ItemSlotBundle bundle)
                {
                    if (ItemConstants.IsRechargeableItem(bundle.TemplateID))
                    {
                        bundle.Number = bundle.MaxNumber;
                    }
                    else
                    {
                        bundle.Number = (short)(count * shopItem.Quantity);
                    }
                }
                if (!User.Character.HasSlotFor(itemSlot))
                {
                    return(ShopResult.BuyUnknown);
                }

                if (shopItem.ItemPeriod > 0)
                {
                    itemSlot.DateExpire = DateTime.Now.AddMinutes(shopItem.ItemPeriod);
                }

                if (shopItem.Price > 0)
                {
                    await User.ModifyStats(s => s.Money -= shopItem.Price *count);
                }
                if (shopItem.TokenTemplateID > 0)
                {
                    await User.ModifyInventory(i => i.Remove(
                                                   shopItem.TokenTemplateID,
                                                   (short)(shopItem.TokenPrice *count)
                                                   ));
                }
                await User.ModifyInventory(i => i.Add(itemSlot));

                return(ShopResult.BuySuccess);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return(ShopResult.BuySuccess);
            }
        }