public static void OnBuyItem(WorldClient client, INetPacketStream packet) { var buyItemPacket = new BuyItemPacket(packet); var npcShopEvent = new NpcShopBuyEventArgs(buyItemPacket.ItemId, buyItemPacket.Quantity, buyItemPacket.Tab, buyItemPacket.Slot); client.Player.NotifySystem <NpcShopSystem>(npcShopEvent); }
/// <summary> /// Buys an item from the current shop. /// </summary> /// <param name="player">Player entity</param> /// <param name="e"></param> private void BuyItem(IPlayerEntity player, NpcShopBuyEventArgs e) { var npcLoader = DependencyContainer.Instance.Resolve <NpcLoader>(); var npcData = npcLoader.GetNpcData(player.PlayerData.CurrentShopName); if (npcData == null) { Logger.Error($"ShopSystem: Cannot find NPC: {player.PlayerData.CurrentShopName}"); return; } if (!npcData.HasShop) { Logger.Error($"ShopSystem: NPC {npcData.Name} doesn't have a shop."); return; } var currentTab = npcData.Shop.Items[e.Tab]; if (e.Slot < 0 || e.Slot > currentTab.Count - 1) { Logger.Error($"ShopSystem: Item slot index was out of tab bounds. Slot: {e.Slot}"); return; } var shopItem = currentTab[e.Slot]; if (shopItem.Id != e.ItemId) { Logger.Error($"ShopSystem: Shop item id doens't match the item id that {player.Object.Name} is trying to buy."); return; } if (player.PlayerData.Gold < e.ItemData.Cost) { Logger.Info($"ShopSystem: {player.Object.Name} doens't have enough gold to buy item {e.ItemData.Name} at {e.ItemData.Cost}."); WorldPacketFactory.SendDefinedText(player, DefineText.TID_GAME_LACKMONEY); return; } int quantity = e.Quantity; int cost = e.ItemData.Cost; if (e.ItemData.IsStackable) { for (var i = 0; i < InventorySystem.EquipOffset; i++) { Item inventoryItem = player.Inventory.Items[i]; if (inventoryItem.Id == e.ItemId) { if (inventoryItem.Quantity + quantity > e.ItemData.PackMax) { int boughtQuantity = inventoryItem.Data.PackMax - inventoryItem.Quantity; quantity -= boughtQuantity; inventoryItem.Quantity = inventoryItem.Data.PackMax; player.PlayerData.Gold -= cost * boughtQuantity; } else { inventoryItem.Quantity += quantity; player.PlayerData.Gold -= cost * quantity; quantity = 0; } WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.GOLD, player.PlayerData.Gold); WorldPacketFactory.SendItemUpdate(player, UpdateItemType.UI_NUM, inventoryItem.UniqueId, inventoryItem.Quantity); } } if (quantity > 0) { if (!player.Inventory.HasAvailableSlots()) { WorldPacketFactory.SendDefinedText(player, DefineText.TID_GAME_LACKSPACE); } else { var item = new Item(e.ItemId, quantity, -1); if (player.Inventory.CreateItem(item)) { player.PlayerData.Gold -= cost; WorldPacketFactory.SendItemCreation(player, item); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.GOLD, player.PlayerData.Gold); } else { Logger.Error("ShopSystem: Failed to create item."); } } } } else { while (quantity > 0) { if (!player.Inventory.HasAvailableSlots()) { WorldPacketFactory.SendDefinedText(player, DefineText.TID_GAME_LACKSPACE); break; } var item = new Item(e.ItemId, 1, -1); if (player.Inventory.CreateItem(item)) { player.PlayerData.Gold -= cost; WorldPacketFactory.SendItemCreation(player, item); WorldPacketFactory.SendUpdateAttributes(player, DefineAttributes.GOLD, player.PlayerData.Gold); } else { Logger.Error("ShopSystem: Failed to create item."); } quantity--; } } }