322 lines
6.7 KiB
Elixir
322 lines
6.7 KiB
Elixir
defmodule Odinsea.Game.Item do
|
|
@moduledoc """
|
|
Represents an item in the game.
|
|
Items can be regular stackable items or equipment with stats.
|
|
"""
|
|
|
|
@type t :: %__MODULE__{
|
|
id: integer(),
|
|
item_id: integer(),
|
|
position: integer(),
|
|
quantity: integer(),
|
|
flag: integer(),
|
|
unique_id: integer(),
|
|
expiration: integer(),
|
|
owner: String.t(),
|
|
gift_from: String.t(),
|
|
gm_log: String.t(),
|
|
inventory_id: integer(),
|
|
pet: map() | nil
|
|
}
|
|
|
|
defstruct [
|
|
:id,
|
|
:item_id,
|
|
:position,
|
|
:quantity,
|
|
:flag,
|
|
:unique_id,
|
|
:expiration,
|
|
:owner,
|
|
:gift_from,
|
|
:gm_log,
|
|
:inventory_id,
|
|
:pet
|
|
]
|
|
|
|
@doc """
|
|
Creates a new item.
|
|
"""
|
|
def new(item_id, position, quantity, flag \\ 0, unique_id \\ -1) do
|
|
%__MODULE__{
|
|
id: nil,
|
|
item_id: item_id,
|
|
position: position,
|
|
quantity: quantity,
|
|
flag: flag,
|
|
unique_id: unique_id,
|
|
expiration: -1,
|
|
owner: "",
|
|
gift_from: "",
|
|
gm_log: "",
|
|
inventory_id: 0,
|
|
pet: nil
|
|
}
|
|
end
|
|
|
|
@doc """
|
|
Creates a copy of an item.
|
|
"""
|
|
def copy(%__MODULE__{} = item) do
|
|
%{item | id: nil}
|
|
end
|
|
|
|
@doc """
|
|
Returns the type of item (2 = regular item).
|
|
"""
|
|
def type(%__MODULE__{}), do: 2
|
|
|
|
@doc """
|
|
Checks if two items can be stacked (same item_id, owner, expiration).
|
|
"""
|
|
def stackable?(%__MODULE__{} = item1, %__MODULE__{} = item2) do
|
|
item1.item_id == item2.item_id &&
|
|
item1.owner == item2.owner &&
|
|
item1.expiration == item2.expiration &&
|
|
item1.flag == item2.flag
|
|
end
|
|
|
|
@doc """
|
|
Compares items by position for sorting.
|
|
"""
|
|
def compare(%__MODULE__{} = item1, %__MODULE__{} = item2) do
|
|
pos1 = abs(item1.position)
|
|
pos2 = abs(item2.position)
|
|
|
|
cond do
|
|
pos1 < pos2 -> :lt
|
|
pos1 == pos2 -> :eq
|
|
true -> :gt
|
|
end
|
|
end
|
|
end
|
|
|
|
defmodule Odinsea.Game.Equip do
|
|
@moduledoc """
|
|
Represents an equipment item with stats.
|
|
Extends the base Item with equipment-specific fields.
|
|
"""
|
|
|
|
@type t :: %__MODULE__{
|
|
# Base item fields
|
|
id: integer(),
|
|
item_id: integer(),
|
|
position: integer(),
|
|
quantity: integer(),
|
|
flag: integer(),
|
|
unique_id: integer(),
|
|
expiration: integer(),
|
|
owner: String.t(),
|
|
gift_from: String.t(),
|
|
gm_log: String.t(),
|
|
inventory_id: integer(),
|
|
pet: map() | nil,
|
|
# Equipment-specific fields
|
|
upgrade_slots: integer(),
|
|
level: integer(),
|
|
vicious_hammer: integer(),
|
|
enhance: integer(),
|
|
str: integer(),
|
|
dex: integer(),
|
|
int: integer(),
|
|
luk: integer(),
|
|
hp: integer(),
|
|
mp: integer(),
|
|
watk: integer(),
|
|
matk: integer(),
|
|
wdef: integer(),
|
|
mdef: integer(),
|
|
acc: integer(),
|
|
avoid: integer(),
|
|
hands: integer(),
|
|
speed: integer(),
|
|
jump: integer(),
|
|
hp_r: integer(),
|
|
mp_r: integer(),
|
|
charm_exp: integer(),
|
|
pvp_damage: integer(),
|
|
item_exp: integer(),
|
|
durability: integer(),
|
|
inc_skill: integer(),
|
|
potential1: integer(),
|
|
potential2: integer(),
|
|
potential3: integer(),
|
|
ring: map() | nil,
|
|
android: map() | nil
|
|
}
|
|
|
|
defstruct [
|
|
# Base item fields
|
|
:id,
|
|
:item_id,
|
|
:position,
|
|
:quantity,
|
|
:flag,
|
|
:unique_id,
|
|
:expiration,
|
|
:owner,
|
|
:gift_from,
|
|
:gm_log,
|
|
:inventory_id,
|
|
:pet,
|
|
# Equipment-specific fields
|
|
:upgrade_slots,
|
|
:level,
|
|
:vicious_hammer,
|
|
:enhance,
|
|
:str,
|
|
:dex,
|
|
:int,
|
|
:luk,
|
|
:hp,
|
|
:mp,
|
|
:watk,
|
|
:matk,
|
|
:wdef,
|
|
:mdef,
|
|
:acc,
|
|
:avoid,
|
|
:hands,
|
|
:speed,
|
|
:jump,
|
|
:hp_r,
|
|
:mp_r,
|
|
:charm_exp,
|
|
:pvp_damage,
|
|
:item_exp,
|
|
:durability,
|
|
:inc_skill,
|
|
:potential1,
|
|
:potential2,
|
|
:potential3,
|
|
:ring,
|
|
:android
|
|
]
|
|
|
|
@armor_ratio 350_000
|
|
@weapon_ratio 700_000
|
|
|
|
@doc """
|
|
Creates a new equipment item.
|
|
"""
|
|
def new(item_id, position, flag \\ 0, unique_id \\ -1) do
|
|
%__MODULE__{
|
|
id: nil,
|
|
item_id: item_id,
|
|
position: position,
|
|
quantity: 1,
|
|
flag: flag,
|
|
unique_id: unique_id,
|
|
expiration: -1,
|
|
owner: "",
|
|
gift_from: "",
|
|
gm_log: "",
|
|
inventory_id: 0,
|
|
pet: nil,
|
|
upgrade_slots: 0,
|
|
level: 0,
|
|
vicious_hammer: 0,
|
|
enhance: 0,
|
|
str: 0,
|
|
dex: 0,
|
|
int: 0,
|
|
luk: 0,
|
|
hp: 0,
|
|
mp: 0,
|
|
watk: 0,
|
|
matk: 0,
|
|
wdef: 0,
|
|
mdef: 0,
|
|
acc: 0,
|
|
avoid: 0,
|
|
hands: 0,
|
|
speed: 0,
|
|
jump: 0,
|
|
hp_r: 0,
|
|
mp_r: 0,
|
|
charm_exp: -1,
|
|
pvp_damage: 0,
|
|
item_exp: 0,
|
|
durability: -1,
|
|
inc_skill: -1,
|
|
potential1: 0,
|
|
potential2: 0,
|
|
potential3: 0,
|
|
ring: nil,
|
|
android: nil
|
|
}
|
|
end
|
|
|
|
@doc """
|
|
Returns the type of item (1 = equipment).
|
|
"""
|
|
def type(%__MODULE__{}), do: 1
|
|
|
|
@doc """
|
|
Gets the potential state of the equipment.
|
|
Returns: 0=none, 5=rare, 6=epic, 7=unique, 8=legendary
|
|
"""
|
|
def potential_state(%__MODULE__{} = equip) do
|
|
pots = equip.potential1 + equip.potential2 + equip.potential3
|
|
|
|
cond do
|
|
equip.potential1 >= 40_000 or equip.potential2 >= 40_000 or equip.potential3 >= 40_000 -> 8
|
|
equip.potential1 >= 30_000 or equip.potential2 >= 30_000 or equip.potential3 >= 30_000 -> 7
|
|
equip.potential1 >= 20_000 or equip.potential2 >= 20_000 or equip.potential3 >= 20_000 -> 6
|
|
pots >= 1 -> 5
|
|
pots < 0 -> 1
|
|
true -> 0
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Gets the equipment level based on item EXP.
|
|
"""
|
|
def equip_level(%__MODULE__{} = equip) do
|
|
if equip.item_exp <= 0 do
|
|
base_level(equip)
|
|
else
|
|
calculate_equip_level(equip, base_level(equip), equip_exp(equip))
|
|
end
|
|
end
|
|
|
|
defp calculate_equip_level(equip, level, exp) do
|
|
# Simplified - would need item data to check max level
|
|
max_level = 10
|
|
|
|
if level >= max_level or exp <= 0 do
|
|
level
|
|
else
|
|
# Simplified exp calculation
|
|
needed_exp = level * 100
|
|
|
|
if exp >= needed_exp do
|
|
calculate_equip_level(equip, level + 1, exp - needed_exp)
|
|
else
|
|
level
|
|
end
|
|
end
|
|
end
|
|
|
|
defp base_level(_equip), do: 1
|
|
|
|
@doc """
|
|
Gets the equipment EXP value.
|
|
"""
|
|
def equip_exp(%__MODULE__{} = equip) do
|
|
if equip.item_exp <= 0 do
|
|
0
|
|
else
|
|
# Simplified ratio
|
|
div(equip.item_exp, @armor_ratio)
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Creates a copy of an equipment.
|
|
"""
|
|
def copy(%__MODULE__{} = equip) do
|
|
%{equip | id: nil}
|
|
end
|
|
end
|