mirror of
https://github.com/ok-oldking/ok-wuthering-waves.git
synced 2025-06-07 01:15:18 +00:00
optimize farm world boss
This commit is contained in:
parent
1809648cac
commit
58fc267986
@ -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):
|
||||
|
@ -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(
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user