defmodule Odinsea.Game.InventoryManipulator do @moduledoc """ High-level inventory operations for adding/removing items. Ported from Java server.MapleInventoryManipulator This module provides convenient functions for: - Adding items from drops - Adding items by ID - Removing items - Checking inventory space """ require Logger alias Odinsea.Game.Character @doc """ Adds an item to the character's inventory from a drop. Returns {:ok, item} on success, {:error, reason} on failure. Ported from MapleInventoryManipulator.addFromDrop() """ def add_from_drop(character_pid, item) when is_pid(character_pid) do Character.add_item_from_drop(character_pid, item) end def add_from_drop(character_id, item) when is_integer(character_id) do case Registry.lookup(Odinsea.CharacterRegistry, character_id) do [{pid, _}] -> add_from_drop(pid, item) [] -> {:error, :character_not_found} end end @doc """ Adds an item to the character's inventory by item ID and quantity. Creates a new item instance with default properties. Ported from MapleInventoryManipulator.addById() """ def add_by_id(character_pid, item_id, quantity \\ 1, gm_log \\ "") do # Create a basic item item = %{ item_id: item_id, quantity: quantity, owner: "", flag: 0, gm_log: gm_log } add_from_drop(character_pid, item) end @doc """ Adds an item to the character's inventory with full item details. Ported from MapleInventoryManipulator.addbyItem() """ def add_by_item(character_pid, item) do add_from_drop(character_pid, item) end @doc """ Removes an item from a specific inventory slot. Ported from MapleInventoryManipulator.removeFromSlot() """ def remove_from_slot(character_pid, inv_type, slot, quantity \\ 1, _from_drop \\ false, _wedding \\ false) do Character.drop_item(character_pid, inv_type, slot, quantity) end @doc """ Removes items by item ID from the inventory. Ported from MapleInventoryManipulator.removeById() """ def remove_by_id(_character_pid, _inv_type, _item_id, _quantity, _delete \\ false, _wedding \\ false) do # TODO: Implement remove by ID (search for item, then remove) {:ok, 0} end @doc """ Checks if the character has space for an item. Ported from MapleInventoryManipulator.checkSpace() """ def check_space(character_pid, item_id, quantity \\ 1, _owner \\ "") do inv_type = get_inventory_type(item_id) case Character.check_inventory_space(character_pid, inv_type, quantity) do {:ok, _slot} -> true {:error, _} -> false end end @doc """ Checks if the character's inventory is full. """ def inventory_full?(character_pid, inv_type) do case Character.check_inventory_space(character_pid, inv_type, 1) do {:ok, _} -> false {:error, :inventory_full} -> true end end @doc """ Gets the inventory type from an item ID. """ def get_inventory_type(item_id) do type_prefix = div(item_id, 1_000_000) case type_prefix do 1 -> :equip 2 -> :use 3 -> :setup 4 -> :etc 5 -> :cash _ -> :etc end end end