diff --git a/src/bot.py b/src/bot.py index 2a6d72b..a1e4c43 100644 --- a/src/bot.py +++ b/src/bot.py @@ -930,6 +930,10 @@ class Bot: if self._curr_loc: items = result_items sell_items = any([item.sell for item in items]) if items else None + # Recompute: a protected item (e.g. a charm) blocked at the vendor is + # flipped to keep=True so the stash step below picks it up. keep_items + # was computed before this call and would otherwise still be stale. + keep_items = any([item.keep for item in items]) if items else keep_items Logger.debug(f"Needs: {consumables.get_needs()}") _step("buy_consumables", "ok", f"at {self._curr_loc} | after: {consumables.get_needs()}") else: diff --git a/src/inventory/personal.py b/src/inventory/personal.py index 900cd88..b21e7c5 100644 --- a/src/inventory/personal.py +++ b/src/inventory/personal.py @@ -462,8 +462,14 @@ def transfer_items(items: list, action: str = "drop", img: np.ndarray = None) -> safe = [] for item in candidates: if _is_protected(item): - Logger.warning(f"Blocked {action_name} for protected item: {item.name} at {item.pos}") + Logger.warning(f"Blocked {action_name} for protected item: {item.name} at {item.pos} — marking for stash") item.sell = False + # Send it to the stash instead of leaving it in limbo. Without this a + # protected item pickit rejected (keep=False) can be neither sold, nor + # dropped, nor stashed (the stash branch only takes keep==True), so it + # sits in the inventory forever and is re-hovered every single game. + # This mirrors the per-item recovery already done by inspect_inventory. + item.keep = True continue safe.append(item) return safe