mirror of
https://github.com/ok-oldking/ok-wuthering-waves.git
synced 2025-06-06 17:05:54 +00:00
optimzie jue farming
This commit is contained in:
parent
fa57eebc24
commit
f38fe7708f
@ -126,6 +126,7 @@ class BaseChar:
|
||||
def switch_out(self):
|
||||
self.is_current_char = False
|
||||
self.has_intro = False
|
||||
self.liberation_available_mark = self.liberation_available()
|
||||
if self.current_con == 1:
|
||||
self.logger.info(f'switch_out at full con set current_con to 0')
|
||||
self.current_con = 0
|
||||
@ -135,7 +136,6 @@ class BaseChar:
|
||||
|
||||
def switch_next_char(self, post_action=None, free_intro=False, target_low_con=False):
|
||||
self.is_forte_full()
|
||||
self.liberation_available_mark = self.liberation_available()
|
||||
self.last_switch_time = self.task.switch_next_char(self, post_action=post_action, free_intro=free_intro,
|
||||
target_low_con=target_low_con)
|
||||
|
||||
@ -250,24 +250,25 @@ class BaseChar:
|
||||
start = time.time()
|
||||
last_click = start
|
||||
clicked = False
|
||||
self.task.send_key(self.get_liberation_key())
|
||||
while self.liberation_available():
|
||||
if not self.task.in_team()[0]:
|
||||
self.task.next_frame()
|
||||
break
|
||||
self.logger.debug(f'click_liberation liberation_available click')
|
||||
now = time.time()
|
||||
if now - last_click > 0.1:
|
||||
self.task.send_key(self.get_liberation_key())
|
||||
self.liberation_available_mark = False
|
||||
clicked = True
|
||||
last_click = now
|
||||
if time.time() - start > 5:
|
||||
self.task.raise_not_in_combat('too long clicking a liberation')
|
||||
self.task.next_frame()
|
||||
if self.task.in_team()[0]:
|
||||
self.sleep(0.05)
|
||||
if clicked:
|
||||
if self.task.wait_until(lambda: not self.task.in_team()[0], time_out=1):
|
||||
self.logger.debug(f'not in_team successfully casted liberation')
|
||||
else:
|
||||
self.task.in_liberation = False
|
||||
self.logger.error(f'clicked liberation but no effect')
|
||||
return False
|
||||
while not self.task.in_team()[0]:
|
||||
clicked = True
|
||||
if send_click:
|
||||
self.task.click(interval=0.1)
|
||||
if time.time() - start > 7:
|
||||
|
@ -3,7 +3,7 @@ import time
|
||||
|
||||
import cv2
|
||||
|
||||
from ok.color.Color import find_color_rectangles, keep_pixels_in_color_range, is_pure_black
|
||||
from ok.color.Color import find_color_rectangles, get_mask_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
|
||||
@ -15,13 +15,15 @@ class CombatCheck:
|
||||
|
||||
def __init__(self):
|
||||
self._in_combat = False
|
||||
self.boss_lv_edge = None
|
||||
self.boss_lv_template = None
|
||||
self.boss_lv_mask = None
|
||||
self.in_liberation = False # return True
|
||||
self.has_count_down = False
|
||||
self.last_out_of_combat_time = 0
|
||||
self.last_combat_check = 0
|
||||
self.boss_lv_box = None
|
||||
self.boss_health_box = None
|
||||
self.boss_health = None
|
||||
self.out_of_combat_reason = ""
|
||||
|
||||
def reset_to_false(self, recheck=False, reason=""):
|
||||
@ -38,12 +40,14 @@ class CombatCheck:
|
||||
# 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.boss_lv_mask = None
|
||||
self.boss_lv_template = None
|
||||
self.in_liberation = False # return True
|
||||
self.has_count_down = False
|
||||
self.last_out_of_combat_time = 0
|
||||
self.last_combat_check = 0
|
||||
self.boss_lv_box = None
|
||||
self.boss_health = None
|
||||
self.boss_health_box = None
|
||||
return False
|
||||
|
||||
@ -75,10 +79,10 @@ class CombatCheck:
|
||||
return self.has_count_down
|
||||
|
||||
def check_boss(self):
|
||||
current, area = self.keep_boss_text_white()
|
||||
current = self.boss_lv_box.crop_frame(self.frame)
|
||||
max_val = 0
|
||||
if current is not None:
|
||||
res = cv2.matchTemplate(current, self.boss_lv_edge, cv2.TM_CCOEFF_NORMED)
|
||||
res = cv2.matchTemplate(current, self.boss_lv_template, cv2.TM_CCOEFF_NORMED, mask=self.boss_lv_mask)
|
||||
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
|
||||
if max_val < 0.8:
|
||||
if self.debug:
|
||||
@ -92,7 +96,7 @@ class CombatCheck:
|
||||
logger.info(f'out of combat because of boss_health disappeared, res:{max_val}')
|
||||
return False
|
||||
else:
|
||||
self.boss_lv_edge = None
|
||||
self.boss_lv_template = None
|
||||
self.boss_lv_box = None
|
||||
logger.info(f'boss_health disappeared, but still in combat')
|
||||
return True
|
||||
@ -104,12 +108,12 @@ class CombatCheck:
|
||||
|
||||
def screenshot_boss_lv(self, current, name):
|
||||
if self.debug:
|
||||
if self.boss_lv_box is not None and self.boss_lv_edge is not None and current is not None:
|
||||
if self.boss_lv_box is not None and self.boss_lv_template is not None and current is not None:
|
||||
frame = self.frame.copy()
|
||||
frame[self.boss_lv_box.y:self.boss_lv_box.y + self.boss_lv_box.height,
|
||||
self.boss_lv_box.x:self.boss_lv_box.x + self.boss_lv_box.width] = current
|
||||
x, y, w, h = self.boss_lv_box.x, self.boss_lv_box.height + 50 + self.boss_lv_box.y, self.boss_lv_box.width, self.boss_lv_box.height
|
||||
frame[y:y + h, x:x + w] = self.boss_lv_edge
|
||||
frame[y:y + h, x:x + w] = self.boss_lv_template
|
||||
self.screenshot(name, frame)
|
||||
|
||||
def find_target_enemy(self):
|
||||
@ -132,7 +136,7 @@ class CombatCheck:
|
||||
self.last_combat_check = now
|
||||
if not self.in_team()[0]:
|
||||
return self.reset_to_false(recheck=False, reason="not in team")
|
||||
if self.boss_lv_edge is not None:
|
||||
if self.boss_lv_template is not None:
|
||||
if self.check_boss():
|
||||
return True
|
||||
else:
|
||||
@ -154,14 +158,14 @@ class CombatCheck:
|
||||
else:
|
||||
in_combat = self.in_team()[0] and self.check_health_bar()
|
||||
if in_combat:
|
||||
in_combat = self.boss_health_box is not None or self.boss_lv_edge is not None or self.has_count_down
|
||||
in_combat = self.boss_health_box is not None or self.boss_lv_template is not None or self.has_count_down
|
||||
if in_combat:
|
||||
self.target_enemy(wait=False)
|
||||
else:
|
||||
in_combat = self.target_enemy()
|
||||
if in_combat:
|
||||
logger.info(
|
||||
f'enter combat boss_lv_edge:{self.boss_lv_edge is not None} boss_health_box:{self.boss_health_box} has_count_down:{self.has_count_down}')
|
||||
f'enter combat boss_lv_template:{self.boss_lv_template is not None} boss_health_box:{self.boss_health_box} has_count_down:{self.has_count_down}')
|
||||
self._in_combat = True
|
||||
return True
|
||||
|
||||
@ -210,24 +214,24 @@ class CombatCheck:
|
||||
if len(boss_lv_texts) > 0:
|
||||
logger.debug(f'boss_lv_texts: {boss_lv_texts}')
|
||||
self.boss_lv_box = boss_lv_texts[0]
|
||||
self.boss_lv_edge, area = self.keep_boss_text_white()
|
||||
if self.boss_lv_edge is None:
|
||||
self.boss_lv_template, self.boss_lv_mask = self.keep_boss_text_white()
|
||||
if self.boss_lv_template is None:
|
||||
self.boss_lv_box = None
|
||||
return False
|
||||
return True
|
||||
|
||||
def keep_boss_text_white(self):
|
||||
corpped = self.boss_lv_box.crop_frame(self.frame)
|
||||
image, area = keep_pixels_in_color_range(corpped, boss_white_text_color)
|
||||
if area / image.shape[0] * image.shape[1] < 0.05:
|
||||
image, area = keep_pixels_in_color_range(corpped, boss_orange_text_color)
|
||||
if area / image.shape[0] * image.shape[1] < 0.05:
|
||||
image, area = keep_pixels_in_color_range(corpped,
|
||||
boss_red_text_color)
|
||||
if area / image.shape[0] * image.shape[1] < 0.05:
|
||||
cropped = self.boss_lv_box.crop_frame(self.frame)
|
||||
mask, area = get_mask_in_color_range(cropped, boss_white_text_color)
|
||||
if area / mask.shape[0] * mask.shape[1] < 0.05:
|
||||
mask, area = get_mask_in_color_range(cropped, boss_orange_text_color)
|
||||
if area / mask.shape[0] * mask.shape[1] < 0.05:
|
||||
mask, area = get_mask_in_color_range(cropped,
|
||||
boss_red_text_color)
|
||||
if area / mask.shape[0] * mask.shape[1] < 0.05:
|
||||
logger.error(f'keep_boss_text_white cant find text with the correct color')
|
||||
return None, 0
|
||||
return image, area
|
||||
return cropped, mask
|
||||
|
||||
|
||||
count_down_re = re.compile(r'\d\d')
|
||||
|
@ -57,6 +57,27 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
|
||||
self.screenshot(f'out of combat break {self.out_of_combat_reason}')
|
||||
break
|
||||
|
||||
def run_in_circle_to_find_echo(self, circle_count=3):
|
||||
directions = ['w', 'a', 's', 'd']
|
||||
step = 1
|
||||
duration = 1
|
||||
total_index = 0
|
||||
for count in range(circle_count):
|
||||
logger.debug(f'running first circle_count{circle_count} circle {total_index} duration:{duration}')
|
||||
for direction in directions:
|
||||
if total_index > 2 and (total_index + 1) % 2 == 0:
|
||||
duration += step
|
||||
# self.send_key_down(direction)
|
||||
# self.sleep(0.02)
|
||||
# self.mouse_down(key="right")
|
||||
picked = self.send_key_and_wait_f(direction, False, time_out=duration, running=True)
|
||||
# self.mouse_up(key="right")
|
||||
# self.send_key_up(direction)
|
||||
if picked:
|
||||
self.mouse_up(key="right")
|
||||
return True
|
||||
total_index += 1
|
||||
|
||||
# @property
|
||||
# def frame(self):
|
||||
# frame = super().frame
|
||||
@ -178,26 +199,34 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
|
||||
self.screenshot('not_in_combat_calling_check_combat')
|
||||
self.raise_not_in_combat('combat check not in combat')
|
||||
|
||||
def send_key_and_wait_f(self, direction, raise_if_not_found, time_out):
|
||||
def send_key_and_wait_f(self, direction, raise_if_not_found, time_out, running=False):
|
||||
if time_out <= 0:
|
||||
return
|
||||
start = time.time()
|
||||
if running:
|
||||
self.mouse_down(key='right')
|
||||
self.send_key_down(direction)
|
||||
f_found = self.wait_feature('pick_up_f', horizontal_variance=0.1, vertical_variance=0.1,
|
||||
f_found = self.wait_feature('pick_up_f', horizontal_variance=0.05, vertical_variance=0.05,
|
||||
use_gray_scale=True, threshold=0.8,
|
||||
wait_until_before_delay=0, time_out=time_out, raise_if_not_found=False)
|
||||
self.send_key_up(direction)
|
||||
if running:
|
||||
self.mouse_up(key='right')
|
||||
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.handle_claim_button():
|
||||
self.send_key_down(direction)
|
||||
if running:
|
||||
self.mouse_down(key='right')
|
||||
self.sleep(time.time() - start)
|
||||
if running:
|
||||
self.mouse_up(key='right')
|
||||
self.send_key_up(direction)
|
||||
return False
|
||||
return f_found
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import re
|
||||
|
||||
from ok.logging.Logger import get_logger
|
||||
from src.task.BaseCombatTask import BaseCombatTask, NotInCombatException
|
||||
from src.task.BaseCombatTask import BaseCombatTask
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@ -26,6 +26,7 @@ class FarmEchoTask(BaseCombatTask):
|
||||
self.last_drop = False
|
||||
|
||||
def run(self):
|
||||
# return self.run_in_circle_to_find_echo()
|
||||
self.handler.post(self.mouse_reset, 0.01)
|
||||
# self.find_echo_drop()
|
||||
# return
|
||||
@ -64,30 +65,19 @@ class FarmEchoTask(BaseCombatTask):
|
||||
# self.log_error('Can not find a level to enter', notify=True)
|
||||
# return
|
||||
|
||||
self.wait_until(lambda: self.in_combat(), time_out=40, raise_if_not_found=True)
|
||||
self.sleep(2)
|
||||
self.wait_until(lambda: self.in_combat(), time_out=3, raise_if_not_found=True)
|
||||
self.load_chars()
|
||||
while self.in_combat():
|
||||
try:
|
||||
logger.debug(f'farm echo loop {self.chars}')
|
||||
self.get_current_char().perform()
|
||||
except NotInCombatException as e:
|
||||
logger.info(f'farm echo loop out of combat break {e}')
|
||||
# if self.debug:
|
||||
self.screenshot(f'out of combat break {e}')
|
||||
break
|
||||
self.combat_once()
|
||||
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.config.get('Entrance Direction') == 'Forward' else 6,
|
||||
raise_if_not_found=False): # find and pick echo
|
||||
if self.config.get('Entrance Direction') == 'Forward':
|
||||
dropped = self.walk_until_f(time_out=3,
|
||||
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)
|
||||
elif not self.last_drop: # only search for the guaranteed drop
|
||||
self.incr_drop(self.find_echo_drop())
|
||||
else:
|
||||
self.incr_drop(False)
|
||||
self.sleep(2)
|
||||
dropped = self.run_in_circle_to_find_echo(3)
|
||||
self.incr_drop(dropped)
|
||||
self.sleep(0.5)
|
||||
self.send_key('esc')
|
||||
self.wait_click_feature('gray_confirm_exit_button', relative_x=-1, raise_if_not_found=True,
|
||||
@ -133,16 +123,15 @@ class FarmEchoTask(BaseCombatTask):
|
||||
highest_index = 0
|
||||
for i in range(4):
|
||||
self.middle_click_relative(0.5, 0.5)
|
||||
self.sleep(2)
|
||||
color_percent = self.calculate_color_percentage(echo_color, box)
|
||||
if color_percent > highest_percent:
|
||||
highest_percent = color_percent
|
||||
highest_index = i
|
||||
self.screenshot(f'find_echo_{highest_index}_{float(color_percent):.3f}_{float(highest_percent):.3}')
|
||||
self.sleep(1)
|
||||
self.next_frame()
|
||||
if self.debug:
|
||||
self.screenshot(f'find_echo_{highest_index}_{float(color_percent):.3f}_{float(highest_percent):.3}')
|
||||
logger.debug(f'searching for echo {i} {float(color_percent):.3f} {float(highest_percent):.3}')
|
||||
# self.click_relative(0.25, 0.25)
|
||||
self.sleep(1)
|
||||
self.send_key('a', down_time=0.05)
|
||||
self.sleep(1)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user