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)