0
0
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:
firedcto@gmail.com 2024-07-12 12:58:03 +08:00
parent fa57eebc24
commit f38fe7708f
4 changed files with 83 additions and 60 deletions

View File

@ -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:

View File

@ -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')

View File

@ -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

View File

@ -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)