From 0facc8466118d09c18382e8a2c8cef736c11c0fb Mon Sep 17 00:00:00 2001 From: alexpolo1 Date: Fri, 19 Jun 2026 20:40:25 +0200 Subject: [PATCH] =?UTF-8?q?Add=20scripts/convert=5Fchipped.py=20=E2=80=94?= =?UTF-8?q?=20inventory=20chipped-gem=20right-click=20converter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- scripts/convert_chipped.py | 145 +++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 scripts/convert_chipped.py diff --git a/scripts/convert_chipped.py b/scripts/convert_chipped.py new file mode 100644 index 0000000..ddcf671 --- /dev/null +++ b/scripts/convert_chipped.py @@ -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() \ No newline at end of file