120 lines
5.8 KiB
Python
120 lines
5.8 KiB
Python
import time
|
|
import os
|
|
from template_finder import TemplateFinder
|
|
from config import Config
|
|
from screen import Screen
|
|
from utils.misc import color_filter, wait
|
|
from logger import Logger
|
|
import keyboard
|
|
from utils.custom_mouse import mouse
|
|
|
|
|
|
class Npc:
|
|
QUAL_KEHK = "qual_kehk"
|
|
MALAH = "malah"
|
|
LARZUK = "larzuk"
|
|
ANYA = "anya"
|
|
|
|
class NpcManager:
|
|
def __init__(self, screen: Screen, template_finder: TemplateFinder):
|
|
self._config = Config()
|
|
self._screen = screen
|
|
self._template_finder = template_finder
|
|
self._npcs = {
|
|
Npc.QUAL_KEHK: {
|
|
"name_tag_white": color_filter(self._template_finder.get_template("QUAL_NAME_TAG_WHITE"), self._config.colors["white"])[1],
|
|
"name_tag_gold": color_filter(self._template_finder.get_template("QUAL_NAME_TAG_GOLD"), self._config.colors["gold"])[1],
|
|
"action_btns": {
|
|
"resurrect": color_filter(self._template_finder.get_template("QUAL_RESURRECT_BTN"), self._config.colors["white"])[1]
|
|
},
|
|
"template_group": ["QUAL_FRONT", "QUAL_SIDE", "QUAL_BACK", "QUAL_45", "QUAL_45_2", "QUAL_45_3"]
|
|
},
|
|
Npc.MALAH: {
|
|
"name_tag_white": color_filter(self._template_finder.get_template("MALAH_NAME_TAG_WHITE"), self._config.colors["white"])[1],
|
|
"name_tag_gold": color_filter(self._template_finder.get_template("MALAH_NAME_TAG_GOLD"), self._config.colors["gold"])[1],
|
|
"action_btns": {
|
|
"trade": color_filter(self._template_finder.get_template("MALAH_TRADE_BTN"), self._config.colors["white"])[1]
|
|
},
|
|
"template_group": ["MALAH_FRONT", "MALAH_BACK", "MALAH_45", "MALAH_SIDE", "MALAH_SIDE_2"]
|
|
},
|
|
Npc.LARZUK: {
|
|
"name_tag_white": color_filter(self._template_finder.get_template("LARZUK_NAME_TAG_WHITE"), self._config.colors["white"])[1],
|
|
"name_tag_gold": color_filter(self._template_finder.get_template("LARZUK_NAME_TAG_GOLD"), self._config.colors["gold"])[1],
|
|
"action_btns": {
|
|
"trade_repair": color_filter(self._template_finder.get_template("LARZUK_TRADE_REPAIR_BTN"), self._config.colors["white"])[1]
|
|
},
|
|
"template_group": ["LARZUK_FRONT", "LARZUK_BACK", "LARZUK_SIDE", "LARZUK_SIDE_2", "LARZUK_SIDE_3"]
|
|
},
|
|
Npc.ANYA: {
|
|
"name_tag_white": color_filter(self._template_finder.get_template("ANYA_NAME_TAG_WHITE"), self._config.colors["white"])[1],
|
|
"name_tag_gold": color_filter(self._template_finder.get_template("ANYA_NAME_TAG_GOLD"), self._config.colors["gold"])[1],
|
|
"action_btns": {
|
|
"trade": color_filter(self._template_finder.get_template("ANYA_TRADE_BTN"), self._config.colors["white"])[1]
|
|
},
|
|
"template_group": ["ANYA_FRONT", "ANYA_BACK", "ANYA_SIDE"]
|
|
}
|
|
}
|
|
|
|
def open_npc_menu(self, npc_key: Npc) -> bool:
|
|
roi = self._config.ui_roi["cut_skill_bar"]
|
|
start = time.time()
|
|
while (time.time() - start) < 35:
|
|
img = self._screen.grab()
|
|
results = []
|
|
for key in self._npcs[npc_key]["template_group"]:
|
|
res = self._template_finder.search(key, img, threshold=0.35, roi=roi, normalize_monitor=True)
|
|
if res.valid:
|
|
results.append({"pos": res.position, "score": res.score})
|
|
results = sorted(results, key=lambda r: r["score"], reverse=True)
|
|
|
|
for result in results:
|
|
pos = result["pos"]
|
|
mouse.move(*pos, randomize=3, delay_factor=[0.9, 1.5])
|
|
wait(0.2, 0.3)
|
|
_, filtered_inp_w = color_filter(self._screen.grab(), self._config.colors["white"])
|
|
_, filtered_inp_g = color_filter(self._screen.grab(), self._config.colors["gold"])
|
|
res_w = self._template_finder.search(self._npcs[npc_key]["name_tag_white"], filtered_inp_w, 0.9, roi=roi).valid
|
|
res_g = self._template_finder.search(self._npcs[npc_key]["name_tag_gold"], filtered_inp_g, 0.9, roi=roi).valid
|
|
if res_w:
|
|
mouse.click(button="left")
|
|
wait(1.4, 1.7)
|
|
_, filtered_inp = color_filter(self._screen.grab(), self._config.colors["gold"])
|
|
res = self._template_finder.search(self._npcs[npc_key]["name_tag_gold"], filtered_inp, 0.9, roi=roi).valid
|
|
if res:
|
|
return True
|
|
elif res_g:
|
|
return True
|
|
return False
|
|
|
|
def press_npc_btn(self, npc_key: Npc, action_btn_key: str):
|
|
_, filtered_inp = color_filter(self._screen.grab(), self._config.colors["white"])
|
|
res = self._template_finder.search(
|
|
self._npcs[npc_key]["action_btns"][action_btn_key],
|
|
filtered_inp, 0.85, roi=self._config.ui_roi["cut_skill_bar"],
|
|
normalize_monitor=True
|
|
)
|
|
if res.valid:
|
|
mouse.move(*res.position, randomize=3, delay_factor=[1.0, 1.5])
|
|
wait(0.2, 0.4)
|
|
mouse.click(button="left")
|
|
wait(0.3, 0.4)
|
|
else:
|
|
Logger.error(f"Could not find {action_btn_key} btn. Should not happen! Continue...")
|
|
keyboard.send("esc")
|
|
|
|
|
|
# Testing: Stand close to Qual-Kehk or Malah and run
|
|
if __name__ == "__main__":
|
|
from screen import Screen
|
|
from config import Config
|
|
import os
|
|
import keyboard
|
|
keyboard.add_hotkey('f12', lambda: os._exit(1))
|
|
keyboard.wait("f11")
|
|
config = Config()
|
|
screen = Screen(config.general["monitor"])
|
|
template_finder = TemplateFinder(screen)
|
|
npc_manager = NpcManager(screen, template_finder)
|
|
npc_manager.open_npc_menu(Npc.ANYA)
|
|
npc_manager.press_npc_btn(Npc.ANYA, "trade")
|