from __future__ import annotations from engine.character import Character from engine.defs import DefRegistry from engine.world import World def try_pickup(character: Character, world: World, registry: DefRegistry) -> int: """Picks up every ground item at `character`'s current tile that fits somewhere in their inventory, leaving behind whatever doesn't (no free slot, or no inventory at all). Returns how many items were actually picked up. """ if character.position is None or character.inventory is None: return 0 pos = character.position picked = 0 for item in world.ground_items_at(pos.map_id, pos.x, pos.y, pos.z): item_def = registry.get_item_def(item.def_id) slot = character.inventory.find_first_fit(item_def) if slot is None: continue if character.inventory.place(item, item_def, *slot): world.remove_ground_item(pos.map_id, pos.x, pos.y, pos.z, item.item_id) picked += 1 return picked def drop_item( character: Character, world: World, item_id: str, def_id: str, inventory, registry: DefRegistry ) -> bool: """Removes `item_id` from `inventory` (the character's own base inventory, or a worn container's granted inventory - see CharacterMenu.resolve_open_inventory) and places it on the ground at `character`'s current position - the logic half of "drag it out of an open inventory card to drop" (see engine/render/menu_draw.py for the drag hit-testing, main.py for wiring the release event). Returns whether it actually happened (False if there's no such item in `inventory`, or no inventory/position to work with at all). """ if character.position is None or inventory is None: return False item_def = registry.get_item_def(def_id) removed = inventory.remove(item_id, item_def) if removed is None: return False pos = character.position world.drop_item_at(pos.map_id, pos.x, pos.y, pos.z, removed) return True