113 lines
2.6 KiB
Elixir
113 lines
2.6 KiB
Elixir
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
|