diff --git a/assets/images/1433eace-21_13_50_556378_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_z8GnYut.png b/assets/images/1433eace-21_13_50_556378_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_z8GnYut.png index 523ed102..eaf0d7e4 100644 Binary files a/assets/images/1433eace-21_13_50_556378_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_z8GnYut.png and b/assets/images/1433eace-21_13_50_556378_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_z8GnYut.png differ diff --git a/assets/images/154eb284-17_01_16_406889_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_6yGu616.png b/assets/images/154eb284-17_01_16_406889_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_6yGu616.png index 69f328ee..0aca6c6c 100644 Binary files a/assets/images/154eb284-17_01_16_406889_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_6yGu616.png and b/assets/images/154eb284-17_01_16_406889_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_6yGu616.png differ diff --git a/assets/images/221458a6-13_25_04_962031_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_XYXLS23.png b/assets/images/221458a6-13_25_04_962031_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_XYXLS23.png index dfc39a80..b27ce7ca 100644 Binary files a/assets/images/221458a6-13_25_04_962031_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_XYXLS23.png and b/assets/images/221458a6-13_25_04_962031_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_XYXLS23.png differ diff --git a/assets/images/3b991d47-10_18_37_465122_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3Hw8AdB.png b/assets/images/3b991d47-10_18_37_465122_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3Hw8AdB.png index ceb6a33f..323af29e 100644 Binary files a/assets/images/3b991d47-10_18_37_465122_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3Hw8AdB.png and b/assets/images/3b991d47-10_18_37_465122_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3Hw8AdB.png differ diff --git a/assets/images/5841f84c-17_04_26_738022_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_TIDxIl1.png b/assets/images/5841f84c-17_04_26_738022_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_TIDxIl1.png index 17d55c4c..66cbd20a 100644 Binary files a/assets/images/5841f84c-17_04_26_738022_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_TIDxIl1.png and b/assets/images/5841f84c-17_04_26_738022_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_TIDxIl1.png differ diff --git a/assets/images/934f0ca6-17_53_47_840123_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_aJQVINN.png b/assets/images/934f0ca6-17_53_47_840123_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_aJQVINN.png index b745c29c..0903d5e3 100644 Binary files a/assets/images/934f0ca6-17_53_47_840123_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_aJQVINN.png and b/assets/images/934f0ca6-17_53_47_840123_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_aJQVINN.png differ diff --git a/assets/images/9beed513-16_15_23_246388_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_a4tQhDg.png b/assets/images/9beed513-16_15_23_246388_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_a4tQhDg.png index b927ed22..0e84ab45 100644 Binary files a/assets/images/9beed513-16_15_23_246388_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_a4tQhDg.png and b/assets/images/9beed513-16_15_23_246388_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_a4tQhDg.png differ diff --git a/assets/images/9ed8b373-00_57_50_813872_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3jLoRJh.png b/assets/images/9ed8b373-00_57_50_813872_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3jLoRJh.png new file mode 100644 index 00000000..d9af7201 Binary files /dev/null and b/assets/images/9ed8b373-00_57_50_813872_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3jLoRJh.png differ diff --git a/assets/images/9f04db98-16_20_58_825243_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_VuLpBVc.png b/assets/images/9f04db98-16_20_58_825243_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_VuLpBVc.png index eb7a1ad1..ca144e9c 100644 Binary files a/assets/images/9f04db98-16_20_58_825243_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_VuLpBVc.png and b/assets/images/9f04db98-16_20_58_825243_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_VuLpBVc.png differ diff --git a/assets/images/e521850f-00_37_38_458841_Encore_liberation_0.274_original.png b/assets/images/e521850f-00_37_38_458841_Encore_liberation_0.274_original.png new file mode 100644 index 00000000..1f1f430c Binary files /dev/null and b/assets/images/e521850f-00_37_38_458841_Encore_liberation_0.274_original.png differ diff --git a/assets/result.json b/assets/result.json index a1c7b6ef..8025910d 100644 --- a/assets/result.json +++ b/assets/result.json @@ -47,6 +47,18 @@ "height": 2160, "id": 7, "file_name": "images\\1433eace-21_13_50_556378_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_z8GnYut.png" + }, + { + "width": 3840, + "height": 2160, + "id": 8, + "file_name": "images\\9ed8b373-00_57_50_813872_WindowsGraphicsCaptureMethod_3840x2160_title_None_Clie_3jLoRJh.png" + }, + { + "width": 3840, + "height": 2160, + "id": 9, + "file_name": "images\\e521850f-00_37_38_458841_Encore_liberation_0.274_original.png" } ], "categories": [ @@ -160,6 +172,14 @@ }, { "id": 27, + "name": "edge_levitator" + }, + { + "id": 28, + "name": "gray_combat_count_down" + }, + { + "id": 29, "name": "pick_up_f" } ], @@ -542,7 +562,7 @@ { "id": 25, "image_id": 7, - "category_id": 27, + "category_id": 29, "segmentation": [], "bbox": [ 2503.364084708245, @@ -553,6 +573,36 @@ "ignore": 0, "iscrowd": 0, "area": 749.9059299877902 + }, + { + "id": 26, + "image_id": 8, + "category_id": 27, + "segmentation": [], + "bbox": [ + 2938.5892304377853, + 1889.8640796534446, + 86.40993725371172, + 84.73207439441629 + ], + "ignore": 0, + "iscrowd": 0, + "area": 7321.693231798345 + }, + { + "id": 27, + "image_id": 9, + "category_id": 28, + "segmentation": [], + "bbox": [ + 1748.3257980253275, + 275.04182659424396, + 58.93319960335, + 54.079877283073856 + ], + "ignore": 0, + "iscrowd": 0, + "area": 3187.100202448065 } ], "info": { @@ -561,6 +611,6 @@ "description": "", "contributor": "Label Studio", "url": "", - "date_created": "2024-06-15 21:20:52.772035" + "date_created": "2024-06-19 01:31:47.083274" } } \ No newline at end of file diff --git a/config.py b/config.py index bf6afdff..3ede35d5 100644 --- a/config.py +++ b/config.py @@ -8,7 +8,7 @@ def calculate_pc_exe_path(running_path): - return None + return running_path config = { @@ -29,17 +29,18 @@ def calculate_pc_exe_path(running_path): }, 'windows': { # required when supporting windows game 'exe': 'Client-Win64-Shipping.exe', + 'calculate_pc_exe_path': calculate_pc_exe_path, 'can_bit_blt': False # default false, opengl games does not support bit_blt }, 'analytics': { 'report_url': 'https://okreport.ok-script.com/report' }, - # 'update': { - # 'releases_url': 'https://api.github.com/repos/ok-oldking/ok-baijing/releases?per_page=15', - # 'proxy_url': 'https://gh.ok-script.com/', - # 'exe_name': 'ok-baijing.exe', - # 'use_proxy': True - # }, + 'update': { + 'releases_url': 'https://api.github.com/repos/ok-oldking/ok-wuthering-waves/releases?per_page=15', + 'proxy_url': 'https://gh.ok-script.com/', + 'exe_name': 'ok-baijing.exe', + 'use_proxy': True + }, 'about': """

OK-WW

免费开源软件 https://github.com/ok-oldking/ok-baijing

diff --git a/main_debug.py b/main_debug.py index 7fc45e3a..4b593119 100644 --- a/main_debug.py +++ b/main_debug.py @@ -3,6 +3,6 @@ config = config config['debug'] = True -config['click_screenshots_folder'] = "click_screenshots" # debug用 点击后截图文件夹] +# config['click_screenshots_folder'] = "click_screenshots" # debug用 点击后截图文件夹] ok = OK(config) ok.start() diff --git a/src/char/BaseChar.py b/src/char/BaseChar.py index e10b9373..3f579c08 100644 --- a/src/char/BaseChar.py +++ b/src/char/BaseChar.py @@ -1,5 +1,5 @@ import time -from enum import IntEnum +from enum import IntEnum, StrEnum from ok.color.Color import white_color, calculate_colorfulness from ok.logging.Logger import get_logger @@ -14,6 +14,15 @@ class Priority(IntEnum): NORMAL = 10 +class Role(StrEnum): + DEFAULT = 'Default' + SUB_DPS = 'Sub DPS' + MAIN_DPS = 'Main DPS' + HEALER = 'Healer' + + +role_values = [role for role in Role] + char_lib_check_marks = ['char_1_lib_check_mark', 'char_2_lib_check_mark', 'char_3_lib_check_mark'] logger = get_logger(__name__) @@ -33,7 +42,6 @@ def __init__(self, task, index, res_cd=0): self.last_res = -1 self.has_intro = False self.res_cd = res_cd - self.con_ready = False self.is_current_char = False @property @@ -46,38 +54,42 @@ def __eq__(self, other): return False def perform(self): - self.is_current_char = True self.wait_down() self.do_perform() logger.debug(f'set current char false {self.index}') - self.is_current_char = False def wait_down(self): clicked = False + start = time.time() while self.flying(): if not clicked: self.task.click() clicked = True self.sleep(0.001) + if self.has_intro: + waited = time.time() - start + self.task.info[f'{self} intro time'] = f'{waited:.2f}' + if waited < 0.2: + self.sleep(0.8 - waited) + self.task.log_info(f'sleep extra for task') + + self.task.screenshot( + f'{self}_down_finish_{(time.time() - start):.2f}_f:{self.is_forte_full()}_e:{self.resonance_available()}_r:{self.echo_available()}_q:{self.liberation_available()}') def do_perform(self): - if self.liberation_available(): - self.click_liberation() - self.sleep(2) + self.click_liberation() if self.resonance_available(): self.click_resonance() - self.sleep(0.1) - elif self.echo_available(): + self.sleep(0.2) + if self.echo_available(): self.click_echo() self.sleep(0.2) self.switch_next_char() - self.con_ready = False def __repr__(self): - return self.__class__.__name__ + return self.__class__.__name__ + ('_T' if self.is_current_char else '_F') def switch_next_char(self, post_action=None): - self.normal_attack() self.last_switch_time = self.task.switch_next_char(self, post_action=post_action) def sleep(self, sec): @@ -85,6 +97,7 @@ def sleep(self, sec): def click_resonance(self): self.task.send_key('e') + logger.info(f'{self} click resonance') def update_res_cd(self): current = time.time() @@ -93,9 +106,17 @@ def update_res_cd(self): def click_echo(self): self.task.send_key(self.get_echo_key()) + logger.info(f'{self} click echo') - def click_liberation(self): + def click_liberation(self, wait_end=True): self.task.send_key(self.get_liberation_key()) + while self.liberation_available(): + self.sleep(0.02) + self.task.send_key(self.get_liberation_key()) + start = time.time() + while not self.task.in_team()[0]: + self.sleep(0.02) + self.task.info[f'{self} liberation time'] = f'{(time.time() - start):.2f}' def get_liberation_key(self): return self.task.config['Liberation Key'] @@ -128,11 +149,15 @@ def resonance_available(self): return False if self.base_resonance_white_percentage != 0: return abs(self.base_resonance_white_percentage - snap1) < self.white_off_threshold - cd_text = self.task.ocr(box=self.task.get_box_by_name('box_resonance'), target_height=540) - if len(cd_text) == 0 or not cd_text[0].name.isdigit(): + cd_text = self.task.ocr(box=self.task.get_box_by_name('box_resonance'), target_height=540, threshold=0.95) + if len(cd_text) == 0 or not is_float(cd_text[0].name): self.base_resonance_white_percentage = snap1 - logger.info(f'set base resonance to {self.base_resonance_white_percentage:.3f}') + if self.task.debug: + self.task.screenshot(f'{self}_resonance_{snap1:.3f}') + logger.info(f'{self} set base resonance to {self.base_resonance_white_percentage:.3f}') return True + if cd_text: + logger.info(f'{self} set base resonance to has text {cd_text}') else: if self.res_cd > 0: return time.time() - self.last_res > self.res_cd @@ -143,9 +168,11 @@ def echo_available(self): return False if self.base_echo_white_percentage != 0: return abs(self.base_echo_white_percentage - snap1) < self.white_off_threshold - cd_text = self.task.ocr(box=self.task.get_box_by_name('box_echo'), target_height=540) - if not cd_text: + cd_text = self.task.ocr(box=self.task.get_box_by_name('box_echo'), target_height=540, threshold=0.95) + if not cd_text or not cd_text[0].name.isdigit(): self.base_echo_white_percentage = snap1 + if self.task.debug: + self.task.screenshot(f'{self}_echo_{snap1:.3f}') logger.info(f'set base resonance to {self.base_echo_white_percentage:.3f}') return True @@ -172,10 +199,12 @@ def liberation_available(self): return False if self.base_liberation_white_percentage != 0: return abs(self.base_liberation_white_percentage - snap1_lib) < self.white_off_threshold - cd_text = self.task.ocr(box=self.task.get_box_by_name('box_liberation'), target_height=540) - if not cd_text: + cd_text = self.task.ocr(box=self.task.get_box_by_name('box_liberation'), target_height=540, threshold=0.95) + if not cd_text or not cd_text[0].name.isdigit(): self.base_liberation_white_percentage = snap1_lib logger.info(f'{self} set base liberation to {self.base_liberation_white_percentage:.3f}') + if self.task.debug: + self.task.screenshot(f'{self}_liberation_{self.base_liberation_white_percentage:.3f}') return True else: logger.debug( @@ -210,7 +239,11 @@ def current_liberation(self): return self.task.calculate_color_percentage(white_color, self.task.get_box_by_name('box_liberation')) def flying(self): - return self.current_resonance() == 0 + return self.get_current_levitator() == 0 + + def get_current_levitator(self): + return self.task.calculate_color_percentage(white_color, + self.task.get_box_by_name('edge_levitator')) forte_white_color = { @@ -218,3 +251,11 @@ def flying(self): 'g': (246, 255), # Green range 'b': (250, 255) # Blue range } + + +def is_float(s): + try: + float(s) + return True + except ValueError: + return False diff --git a/src/char/Encore.py b/src/char/Encore.py index ab0ec0e2..84cc764f 100644 --- a/src/char/Encore.py +++ b/src/char/Encore.py @@ -7,33 +7,43 @@ class Encore(BaseChar): def do_perform(self): - if self.has_intro: - logger.info('Encore has_intro sleep') - if self.has_intro and self.liberation_available(): + logger.debug( + f'Encore_perform_{self.has_intro}_{self.echo_available()}_{self.resonance_available()}_{self.liberation_available()}') + if self.liberation_available(): self.click_liberation() - self.sleep(2) self.n4() self.click_resonance() self.n4() - self.sleep(0.5) + self.task.right_click() + self.sleep(0.4) + self.n4() + self.click_resonance() + if self.is_forte_full(): + logger.info('Encore is_forte_full cast') + self.sleep(2) + self.heavy_attack() elif self.resonance_available(): self.click_resonance() self.sleep(0.2) elif self.echo_available(): self.click_echo() - self.sleep(0.2) + self.sleep(0.3) self.click_echo() - self.sleep(0.2) + self.sleep(0.3) self.click_echo() - self.sleep(0.2) + self.sleep(0.4) + elif self.is_forte_full(): + self.heavy_attack() + else: + logger.info('Encore nothing is available') self.switch_next_char() def n4(self): self.normal_attack() - self.sleep(.4) + self.sleep(.3) self.normal_attack() - self.sleep(.4) + self.sleep(.3) self.normal_attack() - self.sleep(.4) + self.sleep(.3) self.normal_attack() - self.sleep(.4) + self.sleep(.8) diff --git a/src/char/HavocRover.py b/src/char/HavocRover.py index 2c466978..34a7121f 100644 --- a/src/char/HavocRover.py +++ b/src/char/HavocRover.py @@ -14,13 +14,11 @@ def do_perform(self): if self.is_forte_full() and self.liberation_available(): logger.info(f'forte_full, and liberation_available, heavy attack') self.heavy_attack() - self.sleep(0.2) - if self.resonance_available(): + self.sleep(0.4) self.click_resonance() self.sleep(0.2) if self.liberation_available(): self.click_liberation() - self.sleep(2) if self.echo_available(): self.click_echo() self.sleep(0.1) diff --git a/src/char/Jianxin.py b/src/char/Jianxin.py index 63057ed0..cd4c2577 100644 --- a/src/char/Jianxin.py +++ b/src/char/Jianxin.py @@ -5,12 +5,12 @@ class Jianxin(BaseChar): def do_perform(self): if self.has_intro: self.sleep(0.8) - if self.liberation_available(): - self.click_liberation() - self.sleep(2) + # if self.liberation_available(): + # self.click_liberation() + # self.sleep(2) if self.is_forte_full(): self.task.mouse_down() - self.sleep(6) + self.sleep(5.6) self.task.mouse_up() if self.resonance_available(): self.click_resonance() diff --git a/src/char/Sanhua.py b/src/char/Sanhua.py index ebe000f5..04fc5b08 100644 --- a/src/char/Sanhua.py +++ b/src/char/Sanhua.py @@ -5,14 +5,17 @@ class Sanhua(BaseChar): def do_perform(self): if self.liberation_available(): self.click_liberation() - self.sleep(2) + need_switch = False if self.resonance_available(): self.click_resonance() + self.sleep(0.2) + need_switch = True + if self.echo_available(): + self.click_echo() self.sleep(0.3) - if self.echo_available(): - self.click_echo() - self.sleep(0.3) - else: + need_switch = True + + if not need_switch: self.task.mouse_down() self.sleep(.7) self.task.mouse_up() diff --git a/src/char/Taoqi.py b/src/char/Taoqi.py index c005a8d2..ea258fc8 100644 --- a/src/char/Taoqi.py +++ b/src/char/Taoqi.py @@ -12,7 +12,6 @@ def do_perform(self): self.normal_attack() if self.liberation_available(): self.click_liberation() - self.sleep(2) if self.resonance_available(): self.click_resonance() if self.echo_available(): diff --git a/src/char/Verina.py b/src/char/Verina.py index 19b49c1c..92dc9748 100644 --- a/src/char/Verina.py +++ b/src/char/Verina.py @@ -8,7 +8,6 @@ def do_perform(self): return self.switch_next_char() if self.liberation_available(): self.click_liberation() - self.sleep(1.5) if self.resonance_available(): self.click_resonance() if self.echo_available(): diff --git a/src/char/Yinlin.py b/src/char/Yinlin.py index 1cc4be9e..811b37a9 100644 --- a/src/char/Yinlin.py +++ b/src/char/Yinlin.py @@ -8,29 +8,19 @@ class Yinlin(BaseChar): def do_perform(self): if self.is_forte_full(): - if self.liberation_available(): - self.click_liberation() - self.sleep(3.1) + self.click_liberation() self.heavy_attack() self.sleep(0.4) elif self.resonance_available(): self.click_resonance() - self.sleep(0.2) - if self.liberation_available(): - self.click_liberation() - self.sleep(3.1) - else: - self.sleep(0.2) + self.sleep(0.5) self.click_resonance() - self.sleep(.6) + self.sleep(.5) elif self.echo_available(): echo_key = self.get_echo_key() self.task.send_key_down(echo_key) self.sleep(.8) self.switch_next_char(post_action=self.echo_post_action) - elif self.liberation_available(): - self.click_liberation() - self.sleep(3.1) self.switch_next_char() def echo_post_action(self): # hold down the echo for 1 seconds and switch and then release the echo key diff --git a/src/task/AutoCombatTask.py b/src/task/AutoCombatTask.py index f2601ca2..ee3f7330 100644 --- a/src/task/AutoCombatTask.py +++ b/src/task/AutoCombatTask.py @@ -7,12 +7,16 @@ from ok.task.TriggerTask import TriggerTask from ok.util.list import safe_get from src.char import BaseChar -from src.char.BaseChar import Priority +from src.char.BaseChar import Priority, role_values from src.char.CharFactory import get_char_by_pos logger = get_logger(__name__) +class NotInCombatException(Exception): + pass + + class AutoCombatTask(TriggerTask, FindFeature, OCR): def __init__(self): @@ -23,14 +27,24 @@ def __init__(self): 'Echo Key': 'q', 'Liberation Key': 'r', 'Resonance Key': 'e', + 'Character 1 Role': 'Default', + 'Character 2 Role': 'Default', + 'Character 3 Role': 'Default', }) + self.config_type["Character 1 Role"] = {'type': "drop_down", 'options': role_values} + self.config_type["Character 2 Role"] = {'type': "drop_down", 'options': role_values} + self.config_type["Character 3 Role"] = {'type': "drop_down", 'options': role_values} self.last_check_combat = time.time() self._in_combat = False self.char_texts = ['char_1_text', 'char_2_text', 'char_3_text'] def run(self): while self.in_combat(): - self.get_current_char().perform() + try: + logger.debug(f'autocombat loop {self.chars}') + self.get_current_char().perform() + except NotInCombatException: + logger.info('out of combat break') def trigger(self): if self.in_combat(): @@ -54,14 +68,17 @@ def switch_next_char(self, current_char, post_action=None): logger.warning(f"can't find next char to switch to, maybe switching too fast, sleep and wait") return switch_to.has_intro = has_intro + current_char.is_current_char = False self.send_key(switch_to.index + 1) while True: self.sleep(0.01) - if self.find_one(self.char_texts[switch_to.index]): + _, current_index = self.in_team() + if current_index != switch_to.index: self.send_key(switch_to.index + 1) - logger.info('switch not detected, try click again') + logger.info(f'switch not detected, try click again {current_index} {switch_to}') else: switch_time = time.time() + switch_to.is_current_char = True break if post_action: @@ -69,10 +86,9 @@ def switch_next_char(self, current_char, post_action=None): return switch_time def get_current_char(self): - for i, char in enumerate(self.char_texts): - feature = self.find_one(char) - if not feature: - return self.chars[i] + for char in self.chars: + if char.is_current_char: + return char self.log_error('can find current char!!') return None @@ -83,18 +99,23 @@ def in_combat(self): self.handler.post(self.check_in_combat, remove_existing=True, skip_if_running=True) else: if current_time - self.last_check_combat > 2: - self.handler.post(self.check_in_combat, remove_existing=True, skip_if_running=True) + return self.check_in_combat() return self._in_combat def check_in_combat(self): self.last_check_combat = time.time() if self._in_combat: - if not self.in_team() or not self.check_health_bar(): + if self.come_out_of_combat(): time.sleep(4) - if not self.in_team() or not self.check_health_bar(): + if self.come_out_of_combat(): self._in_combat = False else: - self._in_combat = self.in_team() and self.check_health_bar() + edge_levitator = self.find_one('edge_levitator', threshold=0.9) + self._in_combat = edge_levitator and self.in_team()[0] and self.check_health_bar() + + def come_out_of_combat(self): + return not self.find_one('gray_combat_count_down') and ( + not self.in_team()[0] or not self.check_health_bar()) def check_health_bar(self): if self._in_combat: @@ -118,15 +139,21 @@ def check_health_bar(self): self.draw_boxes('boss_health', boxes, color='blue') return True + def sleep(self, timeout): + if not self._in_combat: + raise NotInCombatException('not in combat') + super().sleep(timeout) + def load_chars(self): - if not self.in_team(): + in_team, current_index = self.in_team() + if not in_team: return self.log_info('load chars') char = get_char_by_pos(self, self.get_box_by_name('box_char_1'), 0) old_char = safe_get(self.chars, 0) if (type(char) is BaseChar and old_char is None) or type(char) is not BaseChar: self.chars[0] = char - logger.info(f'update char1 to {char.name}') + logger.info(f'update char1 to {char.name} {type(char)} {type(char) is not BaseChar}') char = get_char_by_pos(self, self.get_box_by_name('box_char_2'), 1) old_char = safe_get(self.chars, 1) @@ -140,6 +167,12 @@ def load_chars(self): self.chars[2] = char logger.info(f'update char3 to {char.name}') + for char in self.chars: + if char.index == current_index: + char.is_current_char = True + else: + char.is_current_char = False + self.log_info(f'load chars success {self.chars}') def box_resonance(self): @@ -155,7 +188,18 @@ def in_team(self): c1 = self.find_one('char_1_text') c2 = self.find_one('char_2_text') c3 = self.find_one('char_3_text') - return sum(x is not None for x in [c1, c2, c3]) == 2 + arr = [c1, c2, c3] + current = -1 + exist_count = 0 + for i in range(len(arr)): + if arr[i] is None: + current = i + else: + exist_count += 1 + if exist_count == 2: + return True, current + else: + return False, -1 enemy_health_color_red = { diff --git a/src/task/SkipDialogTask.py b/src/task/SkipDialogTask.py index b23c6e7f..ffed71f7 100644 --- a/src/task/SkipDialogTask.py +++ b/src/task/SkipDialogTask.py @@ -45,7 +45,7 @@ def trigger(self): if btn_dialog_close: self.click(btn_dialog_close, move_back=True) return - btn_dialog_eye = self.find_one('btn_dialog_eye', use_gray_scale=True) + btn_dialog_eye = self.find_one('btn_dialog_eye', use_gray_scale=True, threshold=0.8) if btn_dialog_eye: self.has_eye_time = time.time() btn_auto_play_dialog = self.find_one('btn_auto_play_dialog', use_gray_scale=True)