Add scripts/convert_chipped.py — inventory chipped-gem right-click converter

Standalone script: scans loot columns, tooltips every occupied slot to
identify chipped gems, then right-clicks each to convert in-place.
Uses the same screen/input_layer stack as the main bot (no D2R restart needed).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
alexpolo1
2026-06-19 20:40:25 +02:00
co-authored by Claude Sonnet 4.6
parent c3a2edb23c
commit 0facc84661
+145
View File
@@ -0,0 +1,145 @@
import sys
import os
import time
import itertools
import numpy as np
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
src = os.path.join(root, "src")
sys.path.insert(0, src)
sys.path.insert(0, root)
os.chdir(root)
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
import ssl
def _patch_ssl():
_orig = ssl.SSLContext.load_default_certs
def _safe(self, purpose=ssl.Purpose.CLIENT_AUTH):
try:
_orig(self, purpose)
except ssl.SSLError:
try:
import certifi
self.load_verify_locations(certifi.where())
except Exception:
pass
ssl.SSLContext.load_default_certs = _safe
_patch_ssl()
from logger import Logger
from config import Config
import screen
from screen import grab, convert_screen_to_monitor, set_window_position
from input_layer import mouse, keyboard
from inventory import common
from d2r_image import processing as d2r_image
from utils.misc import WindowSpec, find_d2r_window, wait
from ui_manager import is_visible, ScreenObjects
CHIPPED_GEMS = [
"Chipped Diamond", "Chipped Topaz", "Chipped Sapphire",
"Chipped Emerald", "Chipped Ruby", "Chipped Amethyst",
"Chipped Skull", "Chipped Star", "Chipped Flame",
"Chipped Sky", "Chipped Thunder", "Chipped Moon",
"Chipped Sun", "Chipped Shadow", "Chipped Death",
"Chipped Life", "Chipped Energy", "Chipped Mana"
]
def get_all_inventory_items(img):
cfg = Config()
items = []
for col, row in itertools.product(range(cfg.char["num_loot_columns"]), range(4)):
center_pos, slot_img = common.get_slot_pos_and_img(img, col, row)
if not common.slot_has_item(slot_img):
continue
x_m, y_m = convert_screen_to_monitor(center_pos)
mouse.move(x_m, y_m, randomize=3, delay_factor=[0.1, 0.15])
wait(0.2, 0.3)
hover_img = grab(True)
try:
item_props, item_box = d2r_image.get_hovered_item(hover_img)
if item_box and item_box.ocr_result:
name = item_box.ocr_result.text.strip().splitlines()[0]
items.append({"pos": center_pos, "col": col, "row": row, "name": name})
print(f" [{col},{row}] {name}")
else:
print(f" [{col},{row}] (has item, no tooltip)")
except Exception as e:
print(f" [{col},{row}] ERROR: {e}")
return items
def convert_chipped(item):
x_m, y_m = convert_screen_to_monitor(item["pos"])
mouse.move(x_m, y_m, randomize=3, delay_factor=[0.2, 0.3])
wait(0.2, 0.3)
mouse.click(button="right")
wait(0.5, 0.8)
print(f" Converted: {item['name']}")
def main():
Logger.info("=== Chipped Gem Converter ===")
# Find D2R window
print("Finding D2R window...")
spec = WindowSpec(title_regex=None, process_name_regex="D2R\\.exe")
pos = find_d2r_window(spec, offset=(0, 0))
if pos is None:
print("ERROR: Could not find D2R window")
return
set_window_position(*pos)
print(f"Client area at ({pos[0]},{pos[1]})")
# Close any open UI panels
print("Closing open UI...")
for _ in range(5):
keyboard.send("esc")
wait(0.3)
wait(0.5)
# Open inventory
print("Opening inventory...")
cfg = Config()
keyboard.send(cfg.char["inventory_screen"])
wait(1.0)
# Verify inventory is open by checking slot brightness
img = grab(True)
# Check if any slot has content (brightness > 16)
has_content = False
for col in range(cfg.char["num_loot_columns"]):
for row in range(4):
_, slot_img = common.get_slot_pos_and_img(img, col, row)
if common.slot_has_item(slot_img):
has_content = True
break
if has_content:
break
if not has_content:
print("ERROR: Inventory appears empty or not open")
keyboard.send("esc")
return
print("Inventory open, scanning...")
all_items = get_all_inventory_items(img)
# Filter for chipped gems
chipped = [i for i in all_items if any(c in i["name"] for c in CHIPPED_GEMS)]
if not chipped:
print("\nNo chipped gems found in inventory.")
else:
print(f"\nFound {len(chipped)} chipped gem(s). Converting...")
for item in chipped:
convert_chipped(item)
# Close inventory
print("\nClosing inventory...")
keyboard.send("esc")
wait(0.3, 0.5)
print("Done.")
if __name__ == "__main__":
main()