defmodule Odinsea.Game.ShopItem do @moduledoc """ Represents an item listed in a player shop or hired merchant. Ported from src/server/shops/MaplePlayerShopItem.java Each shop item contains: - The actual item data - Number of bundles (how many stacks) - Price per bundle """ alias Odinsea.Game.{Item, Equip} @type t :: %__MODULE__{ item: Item.t() | Equip.t(), bundles: integer(), price: integer() } defstruct [ :item, :bundles, :price ] @doc """ Creates a new shop item. """ def new(item, bundles, price) do %__MODULE__{ item: item, bundles: bundles, price: price } end @doc """ Calculates the total quantity available (bundles * quantity per bundle). """ def total_quantity(%__MODULE__{} = shop_item) do per_bundle = shop_item.item.quantity shop_item.bundles * per_bundle end @doc """ Calculates the total price for a given quantity. """ def calculate_price(%__MODULE__{} = shop_item, quantity) do shop_item.price * quantity end @doc """ Reduces the number of bundles by the given quantity. Returns the updated shop item. """ def reduce_bundles(%__MODULE__{} = shop_item, quantity) do %{shop_item | bundles: shop_item.bundles - quantity} end @doc """ Checks if the item is sold out (no bundles remaining). """ def sold_out?(%__MODULE__{} = shop_item) do shop_item.bundles <= 0 end @doc """ Creates a copy of the item for the buyer. The copy has the quantity adjusted based on bundles purchased. """ def create_buyer_item(%__MODULE__{} = shop_item, quantity) do item_copy = copy_item(shop_item.item) per_bundle = shop_item.item.quantity total_qty = quantity * per_bundle case item_copy do %{quantity: _} = item -> %{item | quantity: total_qty} equip -> # Equipment doesn't have quantity field equip end end defp copy_item(%Item{} = item), do: Item.copy(item) defp copy_item(%Equip{} = equip), do: Equip.copy(equip) defp copy_item(item), do: item @doc """ Removes karma flags from an item (for trade). """ def remove_karma(%__MODULE__{} = shop_item) do item = shop_item.item updated_item = cond do # KARMA_EQ flag = 0x02 Bitwise.band(item.flag, 0x02) != 0 -> %{item | flag: item.flag - 0x02} # KARMA_USE flag = 0x04 Bitwise.band(item.flag, 0x04) != 0 -> %{item | flag: item.flag - 0x04} true -> item end %{shop_item | item: updated_item} end end