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:
co-authored by
Claude Sonnet 4.6
parent
c3a2edb23c
commit
0facc84661
@@ -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()
|
||||
Reference in New Issue
Block a user