Files
odinsea-elixir/lib/odinsea/database/schema/inventory_item.ex
2026-02-14 19:36:59 -07:00

239 lines
6.4 KiB
Elixir

defmodule Odinsea.Database.Schema.InventoryItem do
@moduledoc """
Ecto schema for the inventoryitems table.
Stores all items for all characters.
"""
use Ecto.Schema
import Ecto.Changeset
@primary_key {:inventoryitemid, :integer, autogenerate: false}
schema "inventoryitems" do
field :characterid, :integer
field :itemid, :integer
field :inventorytype, :integer
field :position, :integer
field :quantity, :integer
field :owner, :string, default: ""
field :petid, :integer, default: -1
field :flag, :integer, default: 0
field :expiration, :integer, default: -1
field :gift_from, :string, source: :giftFrom, default: ""
field :uniqueid, :integer, default: -1
# Equipment-specific fields (stored in the same table)
field :upgradeslots, :integer, default: 0
field :level, :integer, default: 0
field :str, :integer, default: 0
field :dex, :integer, default: 0
field :int, :integer, default: 0
field :luk, :integer, default: 0
field :hp, :integer, default: 0
field :mp, :integer, default: 0
field :watk, :integer, default: 0
field :matk, :integer, default: 0
field :wdef, :integer, default: 0
field :mdef, :integer, default: 0
field :acc, :integer, default: 0
field :avoid, :integer, default: 0
field :hands, :integer, default: 0
field :speed, :integer, default: 0
field :jump, :integer, default: 0
field :locked, :integer, default: 0
field :vicioushammer, :integer, default: 0
field :itemexp, :integer, default: 0
field :durability, :integer, default: -1
field :enhance, :integer, default: 0
field :potential1, :integer, default: 0
field :potential2, :integer, default: 0
field :potential3, :integer, default: 0
field :hp_r, :integer, source: :hpR, default: 0
field :mp_r, :integer, source: :mpR, default: 0
field :incskill, :integer, default: -1
field :charmexp, :integer, default: -1
field :pvpdamage, :integer, default: 0
end
@doc """
Changeset for creating a new inventory item.
"""
def changeset(item, attrs) do
item
|> cast(attrs, [
:inventoryitemid,
:characterid,
:itemid,
:inventorytype,
:position,
:quantity,
:owner,
:petid,
:flag,
:expiration,
:gift_from,
:uniqueid,
:upgradeslots,
:level,
:str,
:dex,
:int,
:luk,
:hp,
:mp,
:watk,
:matk,
:wdef,
:mdef,
:acc,
:avoid,
:hands,
:speed,
:jump,
:vicioushammer,
:itemexp,
:durability,
:enhance,
:potential1,
:potential2,
:potential3,
:hp_r,
:mp_r,
:incskill,
:charmexp,
:pvpdamage
])
|> validate_required([:characterid, :itemid, :inventorytype, :position, :quantity])
end
@doc """
Converts a database item to a game Item or Equip struct.
"""
def to_game_item(%__MODULE__{} = db_item) do
base_fields = %{
id: db_item.inventoryitemid,
item_id: db_item.itemid,
position: db_item.position,
quantity: db_item.quantity,
flag: db_item.flag,
unique_id: db_item.uniqueid,
expiration: db_item.expiration,
owner: db_item.owner || "",
gift_from: db_item.gift_from || "",
gm_log: "",
inventory_id: db_item.inventoryitemid,
pet: nil
}
if is_equip?(db_item) do
struct(Odinsea.Game.Equip, Map.merge(base_fields, equip_fields(db_item)))
else
struct(Odinsea.Game.Item, base_fields)
end
end
defp is_equip?(db_item) do
# Equipment items have inventory type 1 (EQUIP) or -1 (EQUIPPED)
# or have non-zero equip stats
db_item.inventorytype in [1, -1] or
db_item.upgradeslots > 0 or
db_item.str > 0 or
db_item.dex > 0 or
db_item.int > 0 or
db_item.luk > 0 or
db_item.watk > 0 or
db_item.wdef > 0
end
defp equip_fields(db_item) do
%{
upgrade_slots: db_item.upgradeslots,
level: db_item.level,
vicious_hammer: db_item.vicioushammer,
enhance: db_item.enhance,
str: db_item.str,
dex: db_item.dex,
int: db_item.int,
luk: db_item.luk,
hp: db_item.hp,
mp: db_item.mp,
watk: db_item.watk,
matk: db_item.matk,
wdef: db_item.wdef,
mdef: db_item.mdef,
acc: db_item.acc,
avoid: db_item.avoid,
hands: db_item.hands,
speed: db_item.speed,
jump: db_item.jump,
hp_r: db_item.hp_r,
mp_r: db_item.mp_r,
charm_exp: db_item.charmexp,
pvp_damage: db_item.pvpdamage,
item_exp: db_item.itemexp,
durability: db_item.durability,
inc_skill: db_item.incskill,
potential1: db_item.potential1,
potential2: db_item.potential2,
potential3: db_item.potential3,
ring: nil,
android: nil
}
end
@doc """
Converts a game Item or Equip to database attributes.
"""
def from_game_item(%Odinsea.Game.Item{} = item, character_id, inv_type) do
%{
inventoryitemid: item.id,
characterid: character_id,
itemid: item.item_id,
inventorytype: Odinsea.Game.InventoryType.type_value(inv_type),
position: item.position,
quantity: item.quantity,
owner: item.owner,
petid: if(item.pet, do: item.pet.unique_id, else: -1),
flag: item.flag,
expiration: item.expiration,
gift_from: item.gift_from,
uniqueid: item.unique_id
}
end
def from_game_item(%Odinsea.Game.Equip{} = equip, character_id, inv_type) do
base = from_game_item(%Odinsea.Game.Item{} = equip, character_id, inv_type)
Map.merge(base, %{
upgradeslots: equip.upgrade_slots,
level: equip.level,
str: equip.str,
dex: equip.dex,
int: equip.int,
luk: equip.luk,
hp: equip.hp,
mp: equip.mp,
watk: equip.watk,
matk: equip.matk,
wdef: equip.wdef,
mdef: equip.mdef,
acc: equip.acc,
avoid: equip.avoid,
hands: equip.hands,
speed: equip.speed,
jump: equip.jump,
vicioushammer: equip.vicious_hammer,
itemexp: equip.item_exp,
durability: equip.durability,
enhance: equip.enhance,
potential1: equip.potential1,
potential2: equip.potential2,
potential3: equip.potential3,
hp_r: equip.hp_r,
mp_r: equip.mp_r,
incskill: equip.inc_skill,
charmexp: equip.charm_exp,
pvpdamage: equip.pvp_damage
})
end
end