This commit is contained in:
ra
2026-02-14 19:36:59 -07:00
parent f5b8aeb39d
commit bbd205ecbe
19 changed files with 5191 additions and 554 deletions

321
lib/odinsea/game/item.ex Normal file
View File

@@ -0,0 +1,321 @@
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