protected GW_ItemSlotBase(int nItemID) { this.nItemID = nItemID; InvType = ItemConstants.GetInventoryType(nItemID); IsRechargeable = ItemConstants.IsRechargeableItem(nItemID); IsArrow = ItemConstants.IsArrow(nItemID); }
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); }
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); } }
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); } }
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); }
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; } }
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); } }