make it run a bit smoother (#50)
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
@@ -112,6 +112,7 @@ pindle_save_dist=1382,53, 1685,105, 1440,132
|
||||
eldritch_save_dist=978,95, 845,109
|
||||
pindle_end=1555,261
|
||||
eldritch_end=1012,42
|
||||
shenk_end=1600,816
|
||||
eldritch_save_tp=960,800
|
||||
pindle_save_tp=600,40
|
||||
shenk_save_tp=656,323
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
every screenshot made that handles getting stuck info / chicken info / timeout info / inventory info goes in here
|
||||
@@ -1 +0,0 @@
|
||||
If drop_screenshots is set to 1 in params.ini the saved screeenshots will be put into this folder
|
||||
@@ -40,7 +40,7 @@ show_items=alt
|
||||
inventory_screen=i
|
||||
;note: stand_still can not be the default "shift" as it would interfere with merc healing
|
||||
stand_still=capslock
|
||||
tp=9
|
||||
tp=f9
|
||||
show_belt=~
|
||||
potion1=q
|
||||
potion2=w
|
||||
@@ -50,23 +50,23 @@ es_available=0
|
||||
ts_available=0
|
||||
cta_available=0
|
||||
weapon_switch=x
|
||||
battle_orders=7
|
||||
battle_command=8
|
||||
battle_orders=f7
|
||||
battle_command=f8
|
||||
|
||||
[sorceress]
|
||||
teleport=1
|
||||
skill_left=2
|
||||
skill_right=3
|
||||
frozen_armor=4
|
||||
energy_shield=5
|
||||
thunder_storm=6
|
||||
teleport=f1
|
||||
skill_left=f2
|
||||
skill_right=f3
|
||||
frozen_armor=f4
|
||||
energy_shield=f5
|
||||
thunder_storm=f6
|
||||
|
||||
[hammerdin]
|
||||
teleport=1
|
||||
concentration=2
|
||||
redemption=3
|
||||
holy_shield=4
|
||||
blessed_hammer=5
|
||||
teleport=f1
|
||||
concentration=f2
|
||||
redemption=f3
|
||||
holy_shield=f4
|
||||
blessed_hammer=f5
|
||||
|
||||
[advanced_options]
|
||||
;===== don't touch unless you know what you're doing =====
|
||||
|
||||
@@ -139,9 +139,8 @@ class Bot:
|
||||
self.trigger_or_stop("maintenance")
|
||||
|
||||
def on_maintenance(self):
|
||||
time.sleep(0.6)
|
||||
|
||||
if self._death_manager.died() or self._health_manager.did_chicken():
|
||||
time.sleep(0.6)
|
||||
# Also do this for did_chicken because we can not be 100% sure that chicken did not press esc before
|
||||
# the death manager could determine if we were dead
|
||||
self._death_manager.pick_up_corpse()
|
||||
@@ -171,14 +170,14 @@ class Bot:
|
||||
self.trigger_or_stop("end_game")
|
||||
return
|
||||
self._curr_location = Location.A5_STASH
|
||||
time.sleep(1.5)
|
||||
time.sleep(0.3)
|
||||
# sometimes waypoint is opened and stash not found because of that, check for that
|
||||
if self._template_finder.search("WAYPOINT_MENU", self._screen.grab())[0]:
|
||||
keyboard.send("esc")
|
||||
if self._char.select_by_template("A5_STASH"):
|
||||
self._ui_manager.stash_all_items(self._config.char["num_loot_columns"])
|
||||
self._picked_up_items = False
|
||||
time.sleep(2) # otherwise next grab of screen will still have inventory
|
||||
time.sleep(1.2) # otherwise next grab of screen will still have inventory
|
||||
else:
|
||||
Logger.warning("Could not find stash, continue...")
|
||||
|
||||
@@ -194,7 +193,7 @@ class Bot:
|
||||
wait(0.1, 0.2)
|
||||
self._ui_manager.close_vendor_screen()
|
||||
self._tps_left = 20
|
||||
wait(0.8)
|
||||
wait(0.5)
|
||||
|
||||
# Check if merc needs to be revived
|
||||
merc_alive, _ = self._template_finder.search("MERC", self._screen.grab(), threshold=0.9, roi=[0, 0, 200, 200])
|
||||
@@ -206,7 +205,7 @@ class Bot:
|
||||
self._curr_location = Location.QUAL_KEHK
|
||||
if self._npc_manager.open_npc_menu(Npc.QUAL_KEHK):
|
||||
self._npc_manager.press_npc_btn(Npc.QUAL_KEHK, "resurrect")
|
||||
time.sleep(2)
|
||||
time.sleep(1.2)
|
||||
|
||||
# Start a new run
|
||||
started_run = False
|
||||
|
||||
@@ -18,12 +18,12 @@ class Hammerdin(IChar):
|
||||
self._pather = pather
|
||||
|
||||
def pre_buff(self):
|
||||
if self._char_config["cta_available"]:
|
||||
self._pre_buff_cta()
|
||||
keyboard.send(self._skill_hotkeys["holy_shield"])
|
||||
wait(0.04, 0.1)
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration, self._cast_duration + 0.06)
|
||||
if self._char_config["cta_available"]:
|
||||
self._pre_buff_cta()
|
||||
|
||||
def _cast_hammers(self, time_in_s: float):
|
||||
keyboard.send(self._skill_hotkeys["concentration"])
|
||||
@@ -47,8 +47,9 @@ class Hammerdin(IChar):
|
||||
keyboard.send(self._char_config["stand_still"], do_press=False)
|
||||
|
||||
def _do_redemption(self):
|
||||
keyboard.send(self._skill_hotkeys["redemption"])
|
||||
wait(1.5, 2.0)
|
||||
if "redemption" in self._skill_hotkeys:
|
||||
keyboard.send(self._skill_hotkeys["redemption"])
|
||||
wait(1.5, 2.0)
|
||||
|
||||
def kill_pindle(self) -> bool:
|
||||
wait(0.1, 0.15)
|
||||
|
||||
@@ -45,13 +45,13 @@ class IChar:
|
||||
if force_tp or not self._ui_manager.is_teleport_selected():
|
||||
keyboard.send(self._skill_hotkeys["teleport"])
|
||||
wait(0.15, 0.25)
|
||||
factor = self._config.advanced_options["pathing_delay_factor"]
|
||||
if force_tp or self._ui_manager.can_teleport():
|
||||
mouse.move(pos_monitor[0], pos_monitor[1], randomize=3, delay_factor=[0.6, 0.8])
|
||||
wait(0.03, 0.05)
|
||||
mouse.move(pos_monitor[0], pos_monitor[1], randomize=3, delay_factor=[factor*0.1, factor*0.14])
|
||||
wait(0.012, 0.02)
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration, self._cast_duration + 0.04)
|
||||
wait(self._cast_duration, self._cast_duration + 0.03)
|
||||
else:
|
||||
factor = self._config.advanced_options["pathing_delay_factor"]
|
||||
# in case we want to walk we actually want to move a bit before the point cause d2r will always "overwalk"
|
||||
pos_screen = self._screen.convert_monitor_to_screen(pos_monitor)
|
||||
pos_abs = self._screen.convert_screen_to_abs(pos_screen)
|
||||
@@ -59,12 +59,11 @@ class IChar:
|
||||
adjust_factor = (dist - 50) / dist
|
||||
pos_abs = [int(pos_abs[0] * adjust_factor), int(pos_abs[1] * adjust_factor)]
|
||||
x, y = self._screen.convert_abs_to_monitor(pos_abs)
|
||||
mouse.move(x, y, randomize=5, delay_factor=[factor*0.14, factor*0.2])
|
||||
wait(factor*0.006, factor*0.01)
|
||||
mouse.move(x, y, randomize=5, delay_factor=[factor*0.1, factor*0.14])
|
||||
wait(0.012, 0.02)
|
||||
mouse.click(button="left")
|
||||
wait(0.02, 0.03)
|
||||
if self._config.char["slow_walk"]:
|
||||
wait(0.6)
|
||||
wait(0.8)
|
||||
|
||||
def tp_town(self):
|
||||
keyboard.send(self._char_config["tp"])
|
||||
@@ -115,6 +114,7 @@ class IChar:
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration + 0.04, self._cast_duration + 0.07)
|
||||
keyboard.send(self._char_config["weapon_switch"])
|
||||
wait(0.28, 0.35)
|
||||
|
||||
@abstract
|
||||
def pre_buff(self):
|
||||
|
||||
@@ -20,6 +20,8 @@ class Sorceress(IChar):
|
||||
self._pather = pather
|
||||
|
||||
def pre_buff(self):
|
||||
if self._char_config["cta_available"]:
|
||||
self._pre_buff_cta()
|
||||
if self._char_config["es_available"]:
|
||||
keyboard.send(self._skill_hotkeys["energy_shield"])
|
||||
wait(0.1, 0.13)
|
||||
@@ -34,8 +36,6 @@ class Sorceress(IChar):
|
||||
wait(0.1, 0.13)
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration)
|
||||
if self._char_config["cta_available"]:
|
||||
self._pre_buff_cta()
|
||||
|
||||
def _left_attack(self, cast_pos_abs: Tuple[float, float], delay: float, spray: int = 10):
|
||||
keyboard.send(self._char_config["stand_still"], do_release=False)
|
||||
@@ -82,6 +82,11 @@ class Sorceress(IChar):
|
||||
def kill_eldritch(self) -> bool:
|
||||
delay = [0.2, 0.3]
|
||||
pos_abs = self._pather.find_abs_node_pos(123, self._screen.grab())
|
||||
if pos_abs is not None:
|
||||
eld_pos_abs = [pos_abs[0] * 0.9, pos_abs[1] * 0.9]
|
||||
else:
|
||||
eld_pos_abs = self._screen.convert_screen_to_abs(self._config.path["eldritch_end"][0])
|
||||
cast_pos_abs = [eld_pos_abs[0] * 0.9, eld_pos_abs[1] * 0.9]
|
||||
if pos_abs is not None:
|
||||
cast_pos_abs = [pos_abs[0] * 0.9, pos_abs[1] * 0.9]
|
||||
for _ in range(int(self._char_config["atk_len_eldritch"])):
|
||||
@@ -99,7 +104,11 @@ class Sorceress(IChar):
|
||||
def kill_shenk(self):
|
||||
delay = [0.2, 0.3]
|
||||
pos_abs = self._pather.find_abs_node_pos(149, self._screen.grab())
|
||||
cast_pos_abs = [pos_abs[0] * 0.9, pos_abs[1] * 0.9]
|
||||
if pos_abs is not None:
|
||||
shenk_pos_abs = [pos_abs[0] * 0.9, pos_abs[1] * 0.9]
|
||||
else:
|
||||
shenk_pos_abs = self._screen.convert_screen_to_abs(self._config.path["shenk_end"][0])
|
||||
cast_pos_abs = [shenk_pos_abs[0] * 0.9, shenk_pos_abs[1] * 0.9]
|
||||
for _ in range(int(self._char_config["atk_len_shenk"])):
|
||||
self._main_attack(cast_pos_abs, delay, 90)
|
||||
self._left_attack(cast_pos_abs, delay, 90)
|
||||
|
||||
@@ -52,7 +52,7 @@ class ItemFinder:
|
||||
else:
|
||||
self._gaus_filter = (15, 5)
|
||||
self._folder_name = "items_1280_720"
|
||||
self._min_score = 0.75
|
||||
self._min_score = 0.8
|
||||
# load all templates
|
||||
self._config = config
|
||||
self._templates = {}
|
||||
@@ -113,18 +113,18 @@ class ItemFinder:
|
||||
result = cv2.matchTemplate(cropped_input, template.data, cv2.TM_CCOEFF_NORMED)
|
||||
_, max_val, _, max_loc = cv2.minMaxLoc(result)
|
||||
if max_val > self._min_score:
|
||||
if template.blacklist:
|
||||
item = None
|
||||
break
|
||||
elif (best_score is None or max_val > best_score):
|
||||
if (best_score is None or max_val > best_score):
|
||||
best_score = max_val
|
||||
max_loc = [max_loc[0] + x, max_loc[1] + y]
|
||||
item = Item()
|
||||
item.center = (int(max_loc[0] + int(template.data.shape[1] * 0.5)), int(max_loc[1] + int(template.data.shape[0] * 0.5)))
|
||||
item.name = key
|
||||
item.score = max_val
|
||||
center_abs = (item.center[0] - (inp_img.shape[1] // 2), item.center[1] - (inp_img.shape[0] // 2))
|
||||
item.dist = math.dist(center_abs, (0, 0))
|
||||
if template.blacklist:
|
||||
item = None
|
||||
else:
|
||||
max_loc = [max_loc[0] + x, max_loc[1] + y]
|
||||
item = Item()
|
||||
item.center = (int(max_loc[0] + int(template.data.shape[1] * 0.5)), int(max_loc[1] + int(template.data.shape[0] * 0.5)))
|
||||
item.name = key
|
||||
item.score = max_val
|
||||
center_abs = (item.center[0] - (inp_img.shape[1] // 2), item.center[1] - (inp_img.shape[0] // 2))
|
||||
item.dist = math.dist(center_abs, (0, 0))
|
||||
if item is not None and self._config.items[item.name]:
|
||||
item_list.append(item)
|
||||
elapsed = time.time() - start
|
||||
@@ -144,7 +144,7 @@ if __name__ == "__main__":
|
||||
img = screen.grab().copy()
|
||||
item_list = item_finder.search(img)
|
||||
for item in item_list:
|
||||
# print(item.name + " " + str(item.score))
|
||||
print(item.name + " " + str(item.score))
|
||||
cv2.circle(img, item.center, 5, (255, 0, 255), thickness=3)
|
||||
img = cv2.resize(img, None, fx=0.5, fy=0.5)
|
||||
cv2.imshow('test', img)
|
||||
|
||||
@@ -50,6 +50,12 @@ if __name__ == "__main__":
|
||||
else:
|
||||
print(f"ERROR: Unkown logg_lvl {config.general['logg_lvl']}. Must be one of [info, debug]")
|
||||
|
||||
# create folder if they dont exist yet
|
||||
if not os.path.exists("info_screenshots"):
|
||||
os.system("mkdir info_screenshots")
|
||||
if not os.path.exists("loot_screenshots"):
|
||||
os.system("mkdir loot_screenshots")
|
||||
|
||||
# If anything seems to go wrong, press f12 and the bot will force exit
|
||||
keyboard.add_hotkey(config.general["exit_key"], lambda: Logger.info(f'Force Exit') or os._exit(1))
|
||||
|
||||
|
||||