Skip to content

Commit

Permalink
helper rogue script (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeon0 authored Nov 2, 2023
1 parent 482482e commit 16772b1
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 9 deletions.
15 changes: 13 additions & 2 deletions config/game_1920x1080.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
; min and max hsv range (opencv format: h: [0-180], s: [0-255], v: [0, 255])
; h_min, s_min, v_min, h_max, s_max, v_max
gray_seperator=14,10,62,40,42,100
; for scripts
skill_cd=5,61,38,16,191,90
cold_imbued=88,0,0,112,255,255
posion_imbued=55,0,0,65,255,255
shadow_imbued=120,0,0,140,255,255

[ui_pos]
; all positions in [x, y]
Expand All @@ -20,7 +25,13 @@ item_descr_line_height=25
character_active=1306,13,154,30
rel_descr_search_left=-516,0,160,880
rel_descr_search_right=-40,0,160,880
3x11_slots=1268,722,607,243
5x10_slots=46,269,612,486
slots_3x11=1268,722,607,243
slots_5x10=46,269,612,486
stash_menu_icon=296,72,109,48
tab_slots_5=183,142,336,51
; for scripts
core_skill=1094,981,47,47
skill4=967,981,47,47
rel_skill_cd=6,4,22,12
mini_map_visible=1719,123,60,60
hud_detection=702,978,59,53
15 changes: 13 additions & 2 deletions config/game_2560x1440.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
; min and max hsv range (opencv format: h: [0-180], s: [0-255], v: [0, 255])
; h_min, s_min, v_min, h_max, s_max, v_max
gray_seperator=14,10,62,40,42,100
; for scripts
skill_cd=5,61,38,16,191,90
cold_imbued=88,0,0,112,255,255
posion_imbued=55,0,0,65,255,255
shadow_imbued=120,0,0,140,255,255

[ui_pos]
; all positions in [x, y]
Expand All @@ -20,7 +25,13 @@ item_descr_line_height=33
character_active=1741,17,205,40
rel_descr_search_left=-688,0,213,1173
rel_descr_search_right=-53,0,213,1173
3x11_slots=1691,963,809,324
5x10_slots=61,359,816,648
slots_3x11=1691,963,809,324
slots_5x10=61,359,816,648
stash_menu_icon=395,96,145,64
tab_slots_5=244,189,448,68
; for scripts
core_skill=1459,1308,63,63
skill4=1289,1308,63,63
rel_skill_cd=8,5,29,16
mini_map_visible=2292,164,80,80
hud_detection=936,1304,79,71
7 changes: 7 additions & 0 deletions config/params.ini
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
[general]
; How many tabs should be checked for items in chest. Note: All 5 Tabs must be unlocked!
check_chest_tabs=2
; Which additional scripts should be run. Seperated by comma
; Currently available:
; 1920x1080: rogue_tb
; 2560x1440: rogue_tb
run_scripts=

[char]
; Hotkey to open inventory
inventory=i
skill4=4

[advanced_options]
run_scripts=f9
run_key=f11
exit_key=f12
log_lvl=info
2 changes: 2 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ def load_data(self):
except configparser.MissingSectionHeaderError:
Logger.error("custom.ini missing section header, defaulting to params.ini")

run_scripts_str = str(self._select_val("general", "run_scripts"))
self.general = {
"check_chest_tabs": int(self._select_val("general", "check_chest_tabs")),
"run_scripts": run_scripts_str.split(",") if run_scripts_str else [],
}

for key in self.configs["params"]["parser"]["char"]:
Expand Down
2 changes: 2 additions & 0 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ def main():
print(f"============ D4 Loot Filter {__version__} ============")
table = BeautifulTable()
table.set_style(BeautifulTable.STYLE_BOX_ROUNDED)
table.rows.append([Config().advanced_options["run_scripts"], "Run/Stop Scripts"])
table.rows.append([Config().advanced_options["run_key"], "Run/Stop Loot Filter"])
table.rows.append([Config().advanced_options["exit_key"], "Stop"])
table.columns.header = ["hotkey", "action"]
print(table)
print("\n")

keyboard.add_hotkey(Config().advanced_options["run_scripts"], lambda: overlay.run_scripts())
keyboard.add_hotkey(Config().advanced_options["run_key"], lambda: overlay.filter_items())
keyboard.add_hotkey(Config().advanced_options["exit_key"], lambda: safe_exit())

Expand Down
39 changes: 35 additions & 4 deletions src/overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from utils.process_handler import kill_thread
from logger import Logger
import logging
from scripts.rogue_tb import run_rogue_tb
from config import Config


class ListboxHandler(logging.Handler):
Expand All @@ -23,6 +25,7 @@ def emit(self, record):
class Overlay:
def __init__(self):
self.loot_filter_thread = None
self.script_threads = []
self.is_minimized = True
self.root = tk.Tk()
self.root.title("LootFilter Overlay")
Expand All @@ -33,8 +36,8 @@ def __init__(self):

self.screen_width = self.root.winfo_screenwidth()
self.screen_height = self.root.winfo_screenheight()
self.initial_height = int(self.root.winfo_screenheight() * 0.027)
self.initial_width = int(self.screen_width * 0.05)
self.initial_height = int(self.root.winfo_screenheight() * 0.03)
self.initial_width = int(self.screen_width * 0.072)
self.maximized_height = int(self.initial_height * 3.85)
self.maximized_width = int(self.initial_width * 6)

Expand All @@ -52,7 +55,7 @@ def __init__(self):
borderwidth=0,
command=self.toggle_size,
)
self.canvas.create_window(int(self.initial_width * 0.3), self.initial_height // 2, window=self.toggle_button)
self.canvas.create_window(int(self.initial_width * 0.19), self.initial_height // 2, window=self.toggle_button)

self.filter_button = tk.Button(
self.root,
Expand All @@ -62,7 +65,17 @@ def __init__(self):
borderwidth=0,
command=self.filter_items,
)
self.canvas.create_window(int(self.initial_width * 0.73), self.initial_height // 2, window=self.filter_button)
self.canvas.create_window(int(self.initial_width * 0.5), self.initial_height // 2, window=self.filter_button)

self.start_scripts_button = tk.Button(
self.root,
text="scripts",
bg="#222222",
fg="#555555",
borderwidth=0,
command=self.run_scripts,
)
self.canvas.create_window(int(self.initial_width * 0.8), self.initial_height // 2, window=self.start_scripts_button)

self.terminal_listbox = tk.Listbox(
self.canvas,
Expand Down Expand Up @@ -119,5 +132,23 @@ def _wrapper_run_loot_filter(self):
finally:
self.loot_filter_thread = None

def run_scripts(self):
if len(self.script_threads) > 0:
Logger.info("Stoping Scripts")
for script_thread in self.script_threads:
kill_thread(script_thread)
self.script_threads = []
return
if self.is_minimized:
self.toggle_size()
if len(Config().general["run_scripts"]) == 0:
Logger.info("No scripts configured")
return
for name in Config().general["run_scripts"]:
if name == "rogue_tb":
rogue_tb_thread = threading.Thread(target=run_rogue_tb, daemon=True)
rogue_tb_thread.start()
self.script_threads.append(rogue_tb_thread)

def run(self):
self.root.mainloop()
39 changes: 39 additions & 0 deletions src/scripts/rogue_tb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import keyboard
import traceback
from cam import Cam
from config import Config
from ui.hud import Hud
from utils.misc import wait
from logger import Logger


def run_rogue_tb():
hud = Hud()

Logger.info("Starting Rogue Script")
while True:
img = Cam().grab()
# find the skill at position 3a
if hud.is_ingame(img):
# skills
ready = hud.is_skill_ready(img)
imbued = hud.is_imbued(img)
# print(ready, poison, shadow)
if ready and not imbued:
keyboard.send(Config().char["skill4"])
Logger.debug("Casting imbuement")
wait(0.4, 0.6)


if __name__ == "__main__":
try:
from utils.window import start_detecting_window

start_detecting_window()
while not Cam().is_offset_set():
wait(0.2)
run_rogue_tb()
except:
traceback.print_exc()
print("Press Enter to exit ...")
input()
57 changes: 57 additions & 0 deletions src/ui/hud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import cv2
import numpy as np

from cam import Cam
from config import Config
from utils.image_operations import color_filter, crop
from template_finder import SearchArgs


class Hud(SearchArgs):
def __init__(self):
self.ref = ["HUD_DETECTION_LEFT"]
self.threshold = 0.94
self.roi = "hud_detection"
self.use_grayscale = True
self.do_multi_process = False

def is_ingame(self, img: np.ndarray = None) -> bool:
img = img if img is not None else Cam().grab()
cropped_img = cv2.cvtColor(crop(img, Config().ui_roi["mini_map_visible"]), cv2.COLOR_BGR2GRAY)
_, binary_mask = cv2.threshold(cropped_img, 155, 255, cv2.THRESH_BINARY)
mini_map_visible = cv2.countNonZero(binary_mask) > 40
return self.is_visible(img=img) and mini_map_visible

@staticmethod
def is_skill_ready(img: np.ndarray = None, roi_name: str = "skill4") -> bool:
img = Cam().grab() if img is None else img
# Check avg saturation
roi = Config().ui_roi[roi_name]
cropped = crop(img, roi)
hsv_image = cv2.cvtColor(cropped, cv2.COLOR_BGR2HSV)
_, saturation, _ = cv2.split(hsv_image)
avg_saturation = np.mean(saturation)
# Check if on cd
cropped = crop(cropped, Config().ui_roi["rel_skill_cd"])
mask, _ = color_filter(cropped, Config().colors[f"skill_cd"], False)
# at least half of the row must be filled
target_sum = (mask.shape[0] * mask.shape[1] * 255) * 0.8
cd_sum = np.sum(mask)
ready = avg_saturation > 100 and cd_sum < target_sum
return ready

@staticmethod
def is_imbued(img: np.ndarray = None, roi_name: str = "core_skill") -> bool:
colors = ["shadow_imbued", "posion_imbued", "cold_imbued"]
for color in colors:
img = Cam().grab() if img is None else img
# Check avg saturation
roi = Config().ui_roi[roi_name]
cropped = crop(img, roi)
mask, _ = color_filter(cropped, Config().colors[color], False)
# at least half of the row must be filled
target_sum = (mask.shape[0] * mask.shape[1] * 255) * 0.3
cd_sum = np.sum(mask)
if cd_sum > target_sum:
return True
return False
2 changes: 1 addition & 1 deletion src/ui/inventory_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, rows: int = 3, columns: int = 11):
super().__init__()
self.rows = rows
self.columns = columns
self.slots_roi = Config().ui_roi[f"{self.rows}x{self.columns}_slots"]
self.slots_roi = Config().ui_roi[f"slots_{self.rows}x{self.columns}"]

def get_item_slots(self, img: Optional[np.ndarray] = None) -> tuple[list[ItemSlot], list[ItemSlot]]:
"""
Expand Down

0 comments on commit 16772b1

Please sign in to comment.