from utils.misc import wait from screen import grab from config import Config from input_layer import mouse from input_layer import keyboard import cv2 from logger import Logger from utils.log_rotation import safe_imwrite import time from ui_manager import ScreenObjects, is_visible import threading class DeathManager: def __init__(self): self._died = False self._do_monitor = False self._loop_delay = 0.5 self._callback = None self._last_death_screenshot = None self._state_lock = threading.Lock() def get_loop_delay(self): return self._loop_delay def stop_monitor(self): with self._state_lock: self._do_monitor = False def set_callback(self, callback): self._callback = callback def reset_death_flag(self): with self._state_lock: self._died = False def died(self): with self._state_lock: return self._died def handle_death_screen(self): img = grab() if is_visible(ScreenObjects.YouHaveDied, img): Logger.warning("You have died!") if Config().general["info_screenshots"]: self._last_death_screenshot = "./log/screenshots/info/info_debug_death_" + time.strftime("%Y%m%d_%H%M%S") + ".png" safe_imwrite(self._last_death_screenshot, img) # first wait a bit to make sure health manager is done with its chicken stuff which obviously failed if self._callback is not None: self._callback() # clean up key presses that might be pressed keyboard.release(Config().char["stand_still"]) wait(0.1, 0.2) keyboard.release(Config().char["show_items"]) wait(0.1, 0.2) mouse.release(button="right") wait(0.1, 0.2) mouse.release(button="left") wait(1, 1.5) if is_visible(ScreenObjects.MainMenu): # in this case chicken executed and left the game, but we were still dead. return True keyboard.send("esc") with self._state_lock: self._died = True return True return False def start_monitor(self): from utils.misc import register_stop_condition, unregister_stop_condition register_stop_condition(threading.get_ident(), lambda: not self._do_monitor) try: with self._state_lock: self._do_monitor = True self._died = False Logger.info("Start Death monitoring") while True: with self._state_lock: if not self._do_monitor: break if self._died: monitor_active = True else: monitor_active = False if monitor_active: wait(0.5) continue wait(self._loop_delay, self._loop_delay * 1.5) # no need to do this too frequent, when we died we are not in a hurry... self.handle_death_screen() finally: unregister_stop_condition(threading.get_ident()) Logger.debug("Stop death monitoring") # Testing: if __name__ == "__main__": keyboard.wait("f11") manager = DeathManager() manager.pickup_corpse()