0
0
mirror of https://github.com/ok-oldking/ok-wuthering-waves.git synced 2025-06-07 09:25:34 +00:00

optimize farm world boss

This commit is contained in:
firedcto@gmail.com 2024-07-10 10:14:05 +08:00
parent 1809648cac
commit 58fc267986
5 changed files with 91 additions and 58 deletions

View File

@ -114,10 +114,10 @@ class BaseChar:
else:
invalid_count += 1
has_cd = invalid_count == 0 and (has_dot and 2 <= number_count <= 3)
if self.task.debug:
msg = f"{self}_{has_cd}_{box_name} number_count {number_count} big_count {big_area_count} invalid_count {invalid_count} has_dot {has_dot}"
# self.task.screenshot(msg, frame=cropped)
self.logger.debug(msg)
# if self.task.debug:
# msg = f"{self}_{has_cd}_{box_name} number_count {number_count} big_count {big_area_count} invalid_count {invalid_count} has_dot {has_dot}"
# self.task.screenshot(msg, frame=cropped)
# self.logger.debug(msg)
return has_cd
def is_available(self, percent, box_name):

View File

@ -3,7 +3,7 @@ import time
import cv2
from ok.color.Color import find_color_rectangles, keep_pixels_in_color_range
from ok.color.Color import find_color_rectangles, keep_pixels_in_color_range, is_pure_black
from ok.feature.Box import find_boxes_by_name
from ok.logging.Logger import get_logger
from src import text_white_color
@ -22,8 +22,12 @@ class CombatCheck:
self.last_combat_check = 0
self.boss_lv_box = None
self.boss_health_box = None
self.out_of_combat_reason = ""
def reset_to_false(self, recheck=False):
def reset_to_false(self, recheck=False, reason=""):
if is_pure_black(self.frame):
logger.error('getting a pure black frame for unknown reason, reset_to_false return true')
return True
if recheck and time.time() - self.last_out_of_combat_time > 2.1:
logger.info('out of combat start double check')
if self.debug:
@ -32,6 +36,7 @@ class CombatCheck:
return True
else:
# logger.info('out of combat start double check sleep end')
self.out_of_combat_reason = reason
self._in_combat = False
self.boss_lv_edge = None
self.in_liberation = False # return True
@ -110,7 +115,7 @@ class CombatCheck:
def find_target_enemy(self):
start = time.time()
target_enemy = self.find_one('target_enemy_white', box=self.box_of_screen(0.14, 0.12, 0.8, 0.8),
use_gray_scale=True, threshold=0.92,
use_gray_scale=True, threshold=0.83,
frame_processor=process_target_enemy_area)
# if self.debug and target_enemy is not None:
# self.screenshot('find_target_enemy')
@ -126,19 +131,19 @@ class CombatCheck:
if now - self.last_combat_check > 1:
self.last_combat_check = now
if not self.in_team()[0]:
return self.reset_to_false(recheck=True)
return self.reset_to_false(recheck=False, reason="not in team")
if self.boss_lv_edge is not None:
if self.check_boss():
return True
else:
return self.reset_to_false(recheck=False)
return self.reset_to_false(recheck=False, reason="boss disappear")
if self.check_count_down():
return True
if not self.check_health_bar():
logger.debug('not in team or no health bar')
if not self.target_enemy():
logger.error('target_enemy failed, break out of combat')
return self.reset_to_false()
return self.reset_to_false(reason='target enemy failed')
return True
else:
logger.debug(

View File

@ -13,9 +13,9 @@ class AutoCombatTask(BaseCombatTask, TriggerTask):
logger.debug(f'autocombat loop {self.chars}')
self.get_current_char().perform()
except NotInCombatException as e:
logger.info(f'out of combat break {e}')
logger.info(f'auto_combat_task_out_of_combat {e}')
if self.debug:
self.screenshot(f'out of combat break {e}')
self.screenshot(f'auto_combat_task_out_of_combat {e}')
break
def trigger(self):

View File

@ -40,11 +40,13 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
def raise_not_in_combat(self, message):
logger.error(message)
self.reset_to_false()
self.reset_to_false(reason=message)
raise NotInCombatException(message)
def combat_once(self, wait_combat_time=180):
def combat_once(self, wait_combat_time=180, wait_before=2):
self.wait_until(lambda: self.in_combat(), time_out=wait_combat_time, raise_if_not_found=True)
self.sleep(wait_before)
self.wait_until(lambda: self.in_combat(), time_out=3, raise_if_not_found=True)
self.load_chars()
while self.in_combat():
try:
@ -52,9 +54,30 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
self.get_current_char().perform()
except NotInCombatException as e:
logger.info(f'combat_once out of combat break {e}')
self.screenshot(f'out of combat break {e}')
self.screenshot(f'out of combat break {self.out_of_combat_reason}')
break
# @property
# def frame(self):
# frame = super().frame
# if frame is not None:
# start = time.time()
# # if cv2.countNonZero(cv2.split(frame)) == 0:
# means, stddevs = cv2.meanStdDev(frame)
#
# # Check if all channel means are very close to zero (black)
# all_black_means = np.all(np.isclose(means, 0.0, atol=1e-3))
#
# # Check if all channel standard deviations are low (uniform)
# low_stddevs = np.all(stddevs[0] < 1e-3)
#
# # Return True if all channels are black and uniform
# if all_black_means and low_stddevs:
# logger.error('got a pure black frame!')
# return self.next_frame()
# logger.debug(f'black check:{time.time() - start}')
# return frame
def switch_next_char(self, current_char, post_action=None, free_intro=False, target_low_con=False):
max_priority = Priority.MIN
switch_to = None
@ -152,43 +175,41 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
def check_combat(self):
if not self.in_combat():
if self.debug:
self.screenshot('not_in_combat')
self.screenshot('not_in_combat_calling_check_combat')
self.raise_not_in_combat('combat check not in combat')
def walk_until_f(self, direction='w', time_out=0, raise_if_not_found=True):
def send_key_and_wait_f(self, direction, raise_if_not_found, time_out):
if time_out <= 0:
return
self.send_key_down(direction)
f_found = self.wait_feature('pick_up_f', horizontal_variance=0.1, vertical_variance=0.1,
use_gray_scale=True, threshold=0.8,
wait_until_before_delay=0, time_out=time_out, raise_if_not_found=False)
if not f_found:
if raise_if_not_found:
self.send_key_up(direction)
raise CannotFindException('cant find the f to enter')
else:
logger.warning(f"can't find the f to enter")
self.send_key_up(direction)
return False
self.send_key('f')
self.sleep(0.2)
self.send_key('f')
self.send_key_up(direction)
if self.wait_click_feature('cancel_button', relative_x=1, raise_if_not_found=False,
use_gray_scale=True, time_out=2):
logger.warning(f"found a claim reward")
return False
return f_found
def walk_until_f(self, direction='w', time_out=0, raise_if_not_found=True, backward_time=0):
if not self.find_one('pick_up_f', horizontal_variance=0.1, vertical_variance=0.1, threshold=0.8,
use_gray_scale=True):
self.send_key_down(direction)
f_found = self.wait_feature('pick_up_f', horizontal_variance=0.1, vertical_variance=0.1,
use_gray_scale=True, threshold=0.8,
wait_until_before_delay=0, time_out=time_out, raise_if_not_found=False)
if not f_found:
if raise_if_not_found:
self.send_key_up(direction)
raise CannotFindException('cant find the f to enter')
else:
logger.warning(f"can't find the f to enter")
self.send_key_up(direction)
return False
self.send_key('f')
self.sleep(0.2)
self.send_key('f')
self.send_key_up(direction)
if self.wait_click_feature('cancel_button', relative_x=1, raise_if_not_found=True,
use_gray_scale=True, time_out=2):
logger.warning(f"found a claim reward")
return False
# while self.in_team_and_world():
#
# self.send_key('f')
# count += 1
# if count > 20:
# self.send_key_up(direction)
# logger.error('failed to enter')
# if raise_if_not_found:
# raise CannotFindException('cant find the f to enter')
# else:
# return False
if backward_time > 0:
if self.send_key_and_wait_f('s', raise_if_not_found, backward_time):
return True
return self.send_key_and_wait_f(direction, raise_if_not_found, time_out) and self.sleep(0.5)
else:
self.send_key('f')
self.sleep(0.5)

View File

@ -17,12 +17,12 @@ class FarmWorldBossTask(BaseCombatTask):
'Feilian Beringal',
'Mourning Aix', 'Impermanence Heron', 'Lampylumen Myriad', 'Mech Abomination',
'Bell-Borne Geochelone']
self.weekly_boss_index = {'Bell-Borne Geochelone': 3}
self.weekly_boss_count = 1 # Bell-Borne Geochelone
default_config = {
'Boss1': 'N/A',
'Boss2': 'N/A',
'Boss3': 'N/A',
'Boss4': 'N/A',
'Repeat Farm Count': 1000
}
default_config.update(self.default_config)
@ -30,7 +30,6 @@ class FarmWorldBossTask(BaseCombatTask):
self.config_type["Boss1"] = {'type': "drop_down", 'options': self.boss_names}
self.config_type["Boss2"] = {'type': "drop_down", 'options': self.boss_names}
self.config_type["Boss3"] = {'type': "drop_down", 'options': self.boss_names}
self.config_type["Boss4"] = {'type': "drop_down", 'options': self.boss_names}
self.config_description = {
'Level': '(1-6) Important, Choose which level to farm, lower levels might not produce a echo',
'Entrance Direction': 'Choose Forward for Dreamless, Backward for Jue'
@ -43,7 +42,6 @@ class FarmWorldBossTask(BaseCombatTask):
index = self.boss_names.index(boss_name)
index -= 1
self.log_info(f'teleport to {boss_name} index {index}')
self.sleep(1)
self.log_info('click f2 to open the book')
self.send_key('f2')
@ -55,7 +53,13 @@ class FarmWorldBossTask(BaseCombatTask):
self.sleep(1.5)
self.click_relative(0.04, 0.29)
self.sleep(1)
self.click_relative(0.21, 0.36)
if index >= (len(self.boss_names) - self.weekly_boss_count - 1): # weekly turtle
logger.info('click weekly boss')
index = self.weekly_boss_index[boss_name]
self.click_relative(0.21, 0.59)
else:
logger.info('click normal boss')
self.click_relative(0.21, 0.36)
# self.wait_click_feature('gray_book_forgery', raise_if_not_found=True, use_gray_scale=True, threshold=0.7)
# self.wait_click_feature('gray_book_boss', raise_if_not_found=True, use_gray_scale=True, threshold=0.7)
self.sleep(1)
@ -79,7 +83,7 @@ class FarmWorldBossTask(BaseCombatTask):
self.click_relative(0.5, 0.5)
self.wait_click_feature('gray_custom_way_point', box=self.box_of_screen(0.62, 0.48, 0.70, 0.66),
raise_if_not_found=True,
use_gray_scale=True, threshold=0.75)
use_gray_scale=True, threshold=0.75, time_out=2)
travel = self.wait_feature('fast_travel_custom', raise_if_not_found=True, use_gray_scale=True, threshold=0.8)
self.click_box(travel, relative_x=1.5)
@ -91,17 +95,20 @@ class FarmWorldBossTask(BaseCombatTask):
return True
def scroll_down_a_page(self):
self.click_relative(0.5, 0.5)
self.sleep(0.2)
source_box = self.box_of_screen(0.38, 0.78, 0.42, 0.85)
source_template = Feature(source_box.crop_frame(self.frame), source_box.x, source_box.y)
target_box = self.box_of_screen(0.38, 0.18, 0.42, 0.31)
start = time.time()
# count = 0
while True:
if time.time() - start > 20:
raise Exception("scroll to long")
self.scroll_relative(0.7, 0.5, -1)
self.sleep(0.2)
# if count % 10 == 0:
self.click_relative(0.5, 0.5)
self.sleep(0.1)
# count += 1
self.scroll_relative(0.7, 0.5, -2)
self.sleep(0.1)
targets = self.find_feature('target_box', box=target_box, template=source_template)
if targets:
self.log_info(f'scroll to targets {targets} successfully')
@ -124,7 +131,7 @@ class FarmWorldBossTask(BaseCombatTask):
logger.info(f'farm echo combat end')
self.wait_in_team_and_world(time_out=20)
logger.info(f'farm echo move forward walk_until_f to find echo')
if self.walk_until_f(time_out=3,
if self.walk_until_f(time_out=6, backward_time=1,
raise_if_not_found=False): # find and pick echo
logger.debug(f'farm echo found echo move forward walk_until_f to find echo')
self.incr_drop(True)