mirror of
https://github.com/ok-oldking/ok-wuthering-waves.git
synced 2025-06-03 09:25:19 +00:00
优化自动战斗, 修复今汐不切问题
This commit is contained in:
parent
3df738f691
commit
dcf4c20f16
@ -1,13 +1,7 @@
|
||||
from src.char.BaseChar import BaseChar
|
||||
from src.char.Healer import Healer
|
||||
|
||||
|
||||
class Baizhi(BaseChar):
|
||||
|
||||
def count_base_priority(self):
|
||||
return -1
|
||||
|
||||
def count_echo_priority(self):
|
||||
return 0
|
||||
class Baizhi(Healer):
|
||||
|
||||
def do_perform(self):
|
||||
if self.has_intro:
|
||||
@ -15,6 +9,5 @@ class Baizhi(BaseChar):
|
||||
self.continues_normal_attack(1.2, click_resonance_if_ready_and_return=True)
|
||||
self.click_liberation(con_less_than=1)
|
||||
self.click_resonance()
|
||||
if self.get_current_con() > 0.65:
|
||||
self.click_echo()
|
||||
self.click_echo()
|
||||
self.switch_next_char()
|
||||
|
@ -231,7 +231,7 @@ class BaseChar:
|
||||
self.logger.info('reset state')
|
||||
self.has_intro = False
|
||||
|
||||
def click_liberation(self, wait_end=True, con_less_than=-1, send_click=False):
|
||||
def click_liberation(self, con_less_than=-1, send_click=False, wait_if_cd_ready=0):
|
||||
if con_less_than > 0:
|
||||
if self.get_current_con() > con_less_than:
|
||||
return False
|
||||
@ -239,6 +239,11 @@ class BaseChar:
|
||||
start = time.time()
|
||||
last_click = 0
|
||||
clicked = False
|
||||
while time.time() - start < wait_if_cd_ready and not self.liberation_available() and not self.has_cd(
|
||||
'liberation'):
|
||||
self.logger.debug(f'click_liberation wait ready {wait_if_cd_ready}')
|
||||
self.click(interval=0.1)
|
||||
self.task.next_frame()
|
||||
while self.liberation_available(): # clicked and still in team wait for animation
|
||||
self.logger.debug(f'click_liberation liberation_available click')
|
||||
now = time.time()
|
||||
@ -299,14 +304,14 @@ class BaseChar:
|
||||
def get_resonance_key(self):
|
||||
return self.task.get_resonance_key()
|
||||
|
||||
def get_switch_priority(self, current_char, has_intro):
|
||||
priority = self.do_get_switch_priority(current_char, has_intro)
|
||||
def get_switch_priority(self, current_char, has_intro, target_low_con):
|
||||
priority = self.do_get_switch_priority(current_char, has_intro, target_low_con)
|
||||
if priority < Priority.MAX and time.time() - self.last_switch_time < 0.9:
|
||||
return Priority.SWITCH_CD # switch cd
|
||||
else:
|
||||
return priority
|
||||
|
||||
def do_get_switch_priority(self, current_char, has_intro=False):
|
||||
def do_get_switch_priority(self, current_char, has_intro=False, target_low_con=False):
|
||||
priority = 0
|
||||
if self.count_liberation_priority() and self.liberation_available():
|
||||
priority += self.count_liberation_priority()
|
||||
@ -353,10 +358,10 @@ class BaseChar:
|
||||
return time.time() - self.last_echo > self.echo_cd
|
||||
|
||||
def is_con_full(self):
|
||||
return self.task.is_con_full()
|
||||
return self.task.is_con_full(self.config)
|
||||
|
||||
def get_current_con(self):
|
||||
self.current_con = self.task.get_current_con()
|
||||
self.current_con = self.task.get_current_con(self.config)
|
||||
return self.current_con
|
||||
|
||||
def is_forte_full(self):
|
||||
|
@ -11,7 +11,7 @@ class Changli(BaseChar):
|
||||
def reset_state(self):
|
||||
self.enhanced_normal = False
|
||||
|
||||
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False):
|
||||
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False, target_low_con=False):
|
||||
if self.time_elapsed_accounting_for_freeze(self.last_e) < 4:
|
||||
self.logger.info(
|
||||
f'switch priority MIN because e not finished')
|
||||
|
@ -19,36 +19,28 @@ class Encore(BaseChar):
|
||||
self.last_resonance = 0
|
||||
|
||||
def do_perform(self):
|
||||
target_low_con = False
|
||||
if self.has_intro:
|
||||
self.logger.debug('encore wait intro')
|
||||
self.continues_normal_attack(1.5)
|
||||
self.continues_normal_attack(1.4)
|
||||
self.wait_down()
|
||||
else:
|
||||
while not self.still_in_liberation() and self.can_resonance_step2():
|
||||
if self.click_resonance()[0]:
|
||||
self.last_resonance = 0
|
||||
self.logger.info('try Encore resonance_step2 success')
|
||||
self.sleep(0.2)
|
||||
break
|
||||
else:
|
||||
self.task.next_frame()
|
||||
if self.still_in_liberation():
|
||||
target_low_con = True
|
||||
self.n4()
|
||||
elif self.click_resonance()[0]:
|
||||
self.logger.debug('click_resonance')
|
||||
self.last_resonance = time.time()
|
||||
elif self.click_liberation():
|
||||
return self.switch_next_char()
|
||||
if self.click_resonance()[0]:
|
||||
if not self.can_resonance_step2(delay=4):
|
||||
self.last_resonance = time.time()
|
||||
return self.switch_next_char()
|
||||
if self.click_liberation(wait_if_cd_ready=0.4):
|
||||
self.liberation_time = time.time()
|
||||
self.n4()
|
||||
target_low_con = True
|
||||
elif self.echo_available():
|
||||
self.logger.debug('click_echo')
|
||||
self.click_echo(duration=1.5)
|
||||
return self.switch_next_char()
|
||||
else:
|
||||
self.logger.info('Encore nothing is available')
|
||||
self.switch_next_char(target_low_con=target_low_con)
|
||||
if self.echo_available():
|
||||
self.logger.debug('click_echo')
|
||||
self.click_echo(duration=1.5)
|
||||
return self.switch_next_char()
|
||||
self.switch_next_char()
|
||||
|
||||
def count_liberation_priority(self):
|
||||
return 40
|
||||
@ -62,7 +54,7 @@ class Encore(BaseChar):
|
||||
def can_resonance_step2(self, delay=2):
|
||||
return self.time_elapsed_accounting_for_freeze(self.last_resonance) < delay
|
||||
|
||||
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False):
|
||||
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False, target_low_con=False):
|
||||
if self.time_elapsed_accounting_for_freeze(self.last_heavy) < 4:
|
||||
return Priority.MIN
|
||||
elif self.still_in_liberation() or self.can_resonance_step2():
|
||||
@ -73,7 +65,7 @@ class Encore(BaseChar):
|
||||
return super().do_get_switch_priority(current_char, has_intro)
|
||||
|
||||
def n4(self, duration=2.0):
|
||||
duration = 2.6 if self.click_resonance()[0] else 2.3
|
||||
duration = 2.7 if self.click_resonance()[0] else 2.4
|
||||
if self.time_elapsed_accounting_for_freeze(self.liberation_time) < 6:
|
||||
self.logger.debug('encore liberation n4')
|
||||
self.continues_normal_attack(duration=duration)
|
||||
|
@ -3,12 +3,15 @@ from src.char.BaseChar import BaseChar
|
||||
|
||||
class HavocRover(BaseChar):
|
||||
def do_perform(self):
|
||||
if self.is_forte_full() and self.liberation_available():
|
||||
self.click_liberation()
|
||||
if self.click_resonance()[0]:
|
||||
return self.switch_next_char()
|
||||
if self.is_forte_full():
|
||||
self.logger.info(f'forte_full, and liberation_available, heavy attack')
|
||||
self.wait_down()
|
||||
self.heavy_attack()
|
||||
self.sleep(0.4)
|
||||
self.click_liberation()
|
||||
if not self.click_resonance()[0]:
|
||||
self.click_echo()
|
||||
if self.click_resonance()[0]:
|
||||
return self.switch_next_char()
|
||||
self.click_echo()
|
||||
self.switch_next_char()
|
||||
|
16
src/char/Healer.py
Normal file
16
src/char/Healer.py
Normal file
@ -0,0 +1,16 @@
|
||||
from src.char.BaseChar import BaseChar, Priority
|
||||
|
||||
|
||||
class Healer(BaseChar):
|
||||
|
||||
def count_base_priority(self):
|
||||
return -1
|
||||
|
||||
def count_echo_priority(self):
|
||||
return 0
|
||||
|
||||
def do_get_switch_priority(self, current_char, has_intro=False, target_low_con=False):
|
||||
if has_intro and not target_low_con:
|
||||
return Priority.MIN
|
||||
else:
|
||||
return super().do_get_switch_priority(current_char, has_intro, target_low_con)
|
@ -33,7 +33,7 @@ class Jinhsi(BaseChar):
|
||||
super().switch_next_char(free_intro=self.has_free_intro, target_low_con=True)
|
||||
self.has_free_intro = False
|
||||
|
||||
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False):
|
||||
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False, target_low_con=False):
|
||||
if has_intro or self.incarnation or self.incarnation_cd:
|
||||
self.logger.info(
|
||||
f'switch priority max because has_intro {has_intro} incarnation {self.incarnation} incarnation_cd {self.incarnation_cd}')
|
||||
|
@ -3,14 +3,14 @@ from src.char.BaseChar import BaseChar
|
||||
|
||||
class Sanhua(BaseChar):
|
||||
def do_perform(self):
|
||||
if self.has_intro:
|
||||
self.continues_normal_attack(1.2)
|
||||
self.click_liberation()
|
||||
if self.click_resonance()[0]:
|
||||
return self.switch_next_char()
|
||||
if self.click_echo():
|
||||
return self.switch_next_char()
|
||||
|
||||
self.task.mouse_down()
|
||||
self.sleep(.7)
|
||||
self.task.mouse_up()
|
||||
self.sleep(0.3)
|
||||
self.heavy_attack(0.75)
|
||||
self.sleep(0.4)
|
||||
self.switch_next_char()
|
||||
|
@ -1,7 +1,7 @@
|
||||
from src.char.BaseChar import BaseChar
|
||||
from src.char.Healer import Healer
|
||||
|
||||
|
||||
class Verina(BaseChar):
|
||||
class Verina(Healer):
|
||||
|
||||
def do_perform(self):
|
||||
self.click_liberation()
|
||||
@ -15,9 +15,3 @@ class Verina(BaseChar):
|
||||
self.heavy_attack()
|
||||
# self.normal_attack()
|
||||
self.switch_next_char()
|
||||
|
||||
def count_base_priority(self):
|
||||
return - 1
|
||||
|
||||
def count_echo_priority(self):
|
||||
return 0
|
||||
|
@ -158,7 +158,7 @@ class BaseCombatTask(BaseWWTask, FindFeature, OCR, CombatCheck):
|
||||
if char == current_char:
|
||||
priority = Priority.CURRENT_CHAR
|
||||
else:
|
||||
priority = char.get_switch_priority(current_char, has_intro)
|
||||
priority = char.get_switch_priority(current_char, has_intro, target_low_con)
|
||||
logger.info(
|
||||
f'switch_next_char priority: {char} {priority} {char.current_con} target_low_con {target_low_con}')
|
||||
if target_low_con:
|
||||
@ -217,6 +217,7 @@ class BaseCombatTask(BaseWWTask, FindFeature, OCR, CombatCheck):
|
||||
|
||||
if post_action:
|
||||
post_action()
|
||||
self.next_frame()
|
||||
logger.info(f'switch_next_char end {(current_char.last_switch_time - start):.3f}s')
|
||||
|
||||
def get_liberation_key(self):
|
||||
@ -376,10 +377,10 @@ class BaseCombatTask(BaseWWTask, FindFeature, OCR, CombatCheck):
|
||||
def get_resonance_percentage(self):
|
||||
return self.calculate_color_percentage(white_color, self.get_box_by_name('box_resonance'))
|
||||
|
||||
def is_con_full(self):
|
||||
return self.get_current_con() == 1
|
||||
def is_con_full(self, char_config=None):
|
||||
return self.get_current_con(char_config) == 1
|
||||
|
||||
def get_current_con(self):
|
||||
def get_current_con(self, char_config=None):
|
||||
box = self.box_of_screen_scaled(3840, 2160, 1422, 1939, to_x=1566, to_y=2076, name='con_full',
|
||||
hcenter=True)
|
||||
box.confidence = 0
|
||||
@ -388,7 +389,9 @@ class BaseCombatTask(BaseWWTask, FindFeature, OCR, CombatCheck):
|
||||
percent = 0
|
||||
max_is_full = False
|
||||
color_index = -1
|
||||
target_index = self.config.get('_ring_color_index', -1)
|
||||
target_index = -1
|
||||
if char_config:
|
||||
target_index = char_config.get('_ring_color_index', target_index)
|
||||
cropped = box.crop_frame(self.frame)
|
||||
for i in range(len(con_colors)):
|
||||
if target_index != -1 and i != target_index:
|
||||
@ -403,20 +406,19 @@ class BaseCombatTask(BaseWWTask, FindFeature, OCR, CombatCheck):
|
||||
if area > max_area:
|
||||
max_area = int(area)
|
||||
if max_is_full:
|
||||
percent = 1
|
||||
if max_is_full and char_config:
|
||||
self.logger.info(
|
||||
f'is_con_full found a full ring {self.config.get("_full_ring_area", 0)} -> {max_area} {color_index}')
|
||||
self.config['_full_ring_area'] = max_area
|
||||
self.config['_ring_color_index'] = color_index
|
||||
f'is_con_full found a full ring {char_config.get("_full_ring_area", 0)} -> {max_area} {color_index}')
|
||||
char_config['_full_ring_area'] = max_area
|
||||
char_config['_ring_color_index'] = color_index
|
||||
self.logger.info(
|
||||
f'is_con_full2 found a full ring {self.config.get("_full_ring_area", 0)} -> {max_area} {color_index}')
|
||||
if self.config.get('_full_ring_area', 0) > 0:
|
||||
percent = max_area / self.config['_full_ring_area']
|
||||
f'is_con_full2 found a full ring {char_config.get("_full_ring_area", 0)} -> {max_area} {color_index}')
|
||||
if percent != 1 and char_config and char_config.get('_full_ring_area', 0) > 0:
|
||||
percent = max_area / char_config['_full_ring_area']
|
||||
if not max_is_full and percent >= 1:
|
||||
self.logger.warning(
|
||||
f'is_con_full not full but percent greater than 1, set to 0.99, {percent} {max_is_full}')
|
||||
# self.task.screenshot(
|
||||
# f'is_con_full not full but percent greater than 1, set to 0.99, {percent} {max_is_full}',
|
||||
# cropped)
|
||||
percent = 0.99
|
||||
if percent > 1:
|
||||
self.logger.error(f'is_con_full percent greater than 1, set to 1, {percent} {max_is_full}')
|
||||
|
@ -41,6 +41,7 @@ class DiagnosisTask(BaseCombatTask):
|
||||
self.info['Echo Available'] = char.current_echo() > 0
|
||||
self.info['Liberation in CD'] = char.has_cd('liberation')
|
||||
self.info['Liberation Available'] = char.current_liberation() > 0
|
||||
self.info['Concerto'] = char.get_current_con()
|
||||
self.next_frame()
|
||||
|
||||
def choose_level(self, start):
|
||||
|
Loading…
x
Reference in New Issue
Block a user