Char selector after restart (#403)

* Char selector after restart

* at least make it work...

* Scroll the characters if the template was not found.

TODO: Ideally we would like to understand which character is currently selected rather than assuming we'll always be using the top one.

* make it fancy

Co-authored-by: Francesco <[email protected]>
This commit is contained in:
aeon0
2022-01-07 19:38:21 +01:00
committed by GitHub
co-authored by Francesco
parent f695954cbb
commit faed0154aa
5 changed files with 85 additions and 11 deletions
+4
View File
@@ -24,6 +24,8 @@ center_y=360
ingame_ref_x=625
ingame_ref_y=669
offline_width=105
char_selection_center_x=1050
char_selection_center_y=270
; some distance
skill_bar_height=67
save_and_exit_x=633
@@ -120,6 +122,8 @@ repair_needed=1000,0,280,280
wp_act_roi=42,66,365,53
stash_btn_roi=20,52,412,53
offline_tab= 1100,10,150,40
char_selection_top=1047,50,160,37
char_selection_all=1042,45,170,550
[path]
; static pathes in format: x0,y0, x1,y1, x2,y2, ...
+15 -5
View File
@@ -14,6 +14,7 @@ from health_manager import HealthManager
from logger import Logger
from messenger import Messenger
from screen import Screen
from ui.char_selector import CharSelector
from utils.misc import kill_thread
from utils.restart import restart_game
from utils.misc import kill_thread, set_d2r_always_on_top, restore_d2r_window_visibility
@@ -33,8 +34,16 @@ class GameController:
self.game_controller_thread = None
self.bot_thread = None
self.bot = None
self.char_selector = None
def run_bot(self, pick_corpse: bool = False):
# Make sure the correct char is selected
if self.char_selector.has_char_template_saved():
Logger.info("Selecting original char")
self.char_selector.select_char()
else:
Logger.info("Saving top-most char as template")
self.char_selector.save_char_template()
# Start bot thread
self.bot = Bot(self.screen, self.game_stats, pick_corpse)
self.bot_thread = threading.Thread(target=self.bot.start)
@@ -92,6 +101,11 @@ class GameController:
os._exit(1)
def start(self):
# Check if we user should update the d2r settings
diff = check_settings(self._config)
if len(diff) > 0:
Logger.warning("Your D2R settings differ from the requiered ones. Please use Auto Settings to adjust them. The differences are:")
Logger.warning(f"{diff}")
if self._config.advanced_options['d2r_windows_always_on_top']:
set_d2r_always_on_top()
self.setup_screen()
@@ -99,6 +113,7 @@ class GameController:
self.start_death_manager_thread()
self.game_recovery = GameRecovery(self.screen, self.death_manager)
self.game_stats = GameStats()
self.char_selector = CharSelector(self.screen, self._config)
self.start_game_controller_thread()
GameController.is_running = True
@@ -112,11 +127,6 @@ class GameController:
GameController.is_running = False
def setup_screen(self):
# Check if we user should update the d2r settings
diff = check_settings(self._config)
if len(diff) > 0:
Logger.warning("Your D2R settings differ from the requiered ones. Please use Auto Settings to adjust them. The differences are:")
Logger.warning(f"{diff}")
self.screen = Screen(self._config.general["monitor"])
if self.screen.found_offsets:
return True
+61
View File
@@ -0,0 +1,61 @@
from config import Config
from utils.custom_mouse import mouse
from utils.misc import cut_roi, wait
from screen import Screen
from template_finder import TemplateFinder
class CharSelector:
def __init__(self, screen: Screen, config: Config):
self._config = config
self._char_template = None
self._screen = screen
self._template_finder = TemplateFinder(screen)
def has_char_template_saved(self):
return self._char_template is not None
def save_char_template(self):
img = self._screen.grab()
# TODO: check which character is currently selected rather than assuming the top one is the correct one
self._char_template = cut_roi(img, self._config.ui_roi["char_selection_top"])
def select_char(self):
if self._char_template is not None:
scrolls_attempts = 0
while scrolls_attempts < 2: # 2 scrolls should suffice to see all possible characters
template_result = self._template_finder.search(
self._char_template,
self._screen.grab(),
threshold=0.8,
roi=self._config.ui_roi["char_selection_all"],
normalize_monitor=True
)
if template_result.valid:
# move cursor to result and select
mouse.move(*template_result.position)
wait(0.5)
mouse.click(button="left")
break
else:
# We can scroll the characters only if we have the mouse in the char names selection so move the mouse there
pos = (self._config.ui_pos["char_selection_center_x"], self._config.ui_pos["char_selection_center_y"])
pos = self._screen.convert_screen_to_monitor(pos)
mouse.move(*pos)
wait(0.5)
mouse.wheel(-14)
scrolls_attempts += 1
wait(0.5)
return False
if __name__ == "__main__":
import keyboard
keyboard.wait("f11")
from config import Config
config = Config()
screen = Screen(config.general["monitor"])
selector = CharSelector(screen, config)
if not selector.has_char_template_saved():
selector.save_char_template()
selector.select_char()
+3 -4
View File
@@ -275,6 +275,9 @@ class mouse:
def get_position():
return _mouse.get_position()
@staticmethod
def wheel(delta):
_mouse.wheel(delta)
if __name__ == "__main__":
mouse.move(100, 100)
@@ -282,7 +285,3 @@ if __name__ == "__main__":
mouse.move(200, 200)
time.sleep(2)
mouse.move(1800, 800)
# time.sleep(2)
# mousey.move((700, 900))
# time.sleep(2)
# mousey.move((750, 850))
+2 -2
View File
@@ -29,11 +29,11 @@ def restart_game(d2_path = None):
wait(4.4, 5.5)
for i in range(20):
keyboard.send("space")
wait(0.5, 1.0)
wait(0.5, 1.0)
success = False
attempts = 0
while not success:
screen = Screen(config.general["monitor"],wait = 5)
screen = Screen(config.general["monitor"], wait=5)
success = screen.found_offsets
if not success:
keyboard.send("space")