0
0
mirror of https://github.com/ok-oldking/ok-wuthering-waves.git synced 2025-05-14 00:35:11 +00:00

add farm world boss, CombatCheck still need to be faster when boss dies

This commit is contained in:
firedcto@gmail.com 2024-07-10 03:09:49 +08:00
parent 6c3084aa79
commit 1809648cac
10 changed files with 935 additions and 692 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ import os
from ok.util.path import get_path_in_package
from src.task.AutoCombatTask import AutoCombatTask
from src.task.FarmEchoTask import FarmEchoTask
from src.task.FarmWorldBossTask import FarmWorldBossTask
from src.task.SkipDialogTask import AutoDialogTask
version = "v1.1.11"
@ -61,7 +62,8 @@ config = {
'error_log_file': 'logs/ok-script_error.log',
'version': version,
'onetime_tasks': [ # tasks to execute
FarmEchoTask()
FarmEchoTask(),
FarmWorldBossTask()
], 'trigger_tasks': [
AutoCombatTask(),
AutoDialogTask()

View File

@ -18,13 +18,15 @@ class Encore(BaseChar):
target_low_con = False
if self.has_intro:
self.sleep(0.7)
self.wait_down()
if self.can_resonance_step2():
self.wait_down()
elif self.can_resonance_step2(4):
if self.click_resonance()[0]:
self.logger.info('try Encore resonance_step2 success')
self.sleep(0.3)
else:
self.logger.info('try Encore resonance_step2 failure')
self.task.wait_until(self.resonance_available, time_out=1)
wait_success = self.click_resonance()[0]
self.logger.info(f'try Encore resonance_step2 wait_success:{wait_success}')
if self.still_in_liberation():
# if time.time() - self.liberation_time > 7.5 and self.is_forte_full():
@ -57,13 +59,13 @@ class Encore(BaseChar):
def count_echo_priority(self):
return 40
def can_resonance_step2(self):
return time.time() - self.last_resonance < 4
def can_resonance_step2(self, delay=3):
return time.time() - self.last_resonance < delay
def do_get_switch_priority(self, current_char: BaseChar, has_intro=False):
if time.time() - self.last_heavy < 3:
return Priority.MIN
elif self.still_in_liberation() or self.can_resonance_step2() or has_intro:
elif self.still_in_liberation() or self.can_resonance_step2():
self.logger.info(
f'switch priority MIN because still in liberation')
return Priority.MAX

View File

@ -12,16 +12,8 @@ logger = get_logger(__name__)
class CombatCheck:
last_out_of_combat_time = 0
last_combat_check = 0
_in_combat = False
boss_lv_edge = None
boss_lv_box = None
in_liberation = False # return True
has_count_down = False # instant end of combat if count_down goes away
boss_health_box = None
def reset_to_false(self):
def __init__(self):
self._in_combat = False
self.boss_lv_edge = None
self.in_liberation = False # return True
@ -30,7 +22,25 @@ class CombatCheck:
self.last_combat_check = 0
self.boss_lv_box = None
self.boss_health_box = None
return False
def reset_to_false(self, recheck=False):
if recheck and time.time() - self.last_out_of_combat_time > 2.1:
logger.info('out of combat start double check')
if self.debug:
self.screenshot('out of combat start double check')
self.last_out_of_combat_time = time.time()
return True
else:
# logger.info('out of combat start double check sleep end')
self._in_combat = False
self.boss_lv_edge = 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
return False
def check_count_down(self):
count_down_area = self.box_of_screen(1820 / 3840, 266 / 2160, 2100 / 3840,
@ -75,7 +85,7 @@ class CombatCheck:
if self.debug:
self.screenshot_boss_lv(current, 'out_of combat boss_health disappeared')
logger.info(f'out of combat because of boss_health disappeared, res:{max_val}')
return self.reset_to_false()
return False
else:
self.boss_lv_edge = None
self.boss_lv_box = None
@ -100,12 +110,14 @@ 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.8,
use_gray_scale=True, threshold=0.92,
frame_processor=process_target_enemy_area)
# if self.debug and target_enemy is not None:
# self.screenshot('find_target_enemy')
logger.debug(f'find_target_enemy {target_enemy} {time.time() - start}')
return target_enemy is not None
def in_combat(self):
def in_combat(self, rechecked=False):
if self.in_liberation:
logger.debug('in liberation return True')
return True
@ -114,9 +126,12 @@ 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()
return self.reset_to_false(recheck=True)
if self.boss_lv_edge is not None:
return self.check_boss()
if self.check_boss():
return True
else:
return self.reset_to_false(recheck=False)
if self.check_count_down():
return True
if not self.check_health_bar():
@ -128,7 +143,6 @@ class CombatCheck:
else:
logger.debug(
'check in combat pass')
# self.last_out_of_combat_time = 0
return True
else:
return True

View File

@ -43,6 +43,18 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
self.reset_to_false()
raise NotInCombatException(message)
def combat_once(self, wait_combat_time=180):
self.wait_until(lambda: self.in_combat(), time_out=wait_combat_time, raise_if_not_found=True)
self.load_chars()
while self.in_combat():
try:
logger.debug(f'combat_once loop {self.chars}')
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}')
break
def switch_next_char(self, current_char, post_action=None, free_intro=False, target_low_con=False):
max_priority = Priority.MIN
switch_to = None
@ -119,7 +131,8 @@ class BaseCombatTask(BaseTask, FindFeature, OCR, CombatCheck):
self.wait_until(self.in_team_and_world, time_out=time_out, raise_if_not_found=True)
def in_team_and_world(self):
return self.in_team()[0] and self.find_one(f'gray_book_button', threshold=0.7, use_gray_scale=True)
return self.in_team()[
0] # and self.find_one(f'gray_book_button', threshold=0.7, canny_lower=50, canny_higher=150)
def get_current_char(self):
for char in self.chars:

View File

@ -33,10 +33,10 @@ class FarmEchoTask(BaseCombatTask):
self.log_error('must be in game world and in teams', notify=True)
return
if self.config.get('Teleport'):
book = self.find_one('gray_book_button', use_gray_scale=True)
if not book:
self.log_error("can't find the book button")
return
# book = self.find_one('gray_book_button', use_gray_scale=True)
# if not book:
# self.log_error("can't find the book button")
# return
self.sleep(2)
self.log_info('click f2 to open the book')
self.send_key('f2')

View File

@ -0,0 +1,139 @@
import time
from ok.feature.Feature import Feature
from ok.logging.Logger import get_logger
from src.task.BaseCombatTask import BaseCombatTask
logger = get_logger(__name__)
class FarmWorldBossTask(BaseCombatTask):
def __init__(self):
super().__init__()
self.description = "Click Start in Game World"
self.name = "Farm World Boss(Must Drop a WayPoint on the Boss First)"
self.boss_names = ['N/A', 'Crownless', 'Tempest Mephis', 'Thundering Mephis', 'Inferno Rider',
'Feilian Beringal',
'Mourning Aix', 'Impermanence Heron', 'Lampylumen Myriad', 'Mech Abomination',
'Bell-Borne Geochelone']
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)
self.default_config = default_config
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'
}
self.config_type["Entrance Direction"] = {'type': "drop_down", 'options': ['Forward', 'Backward']}
self.crownless_pos = (0.9, 0.4)
self.last_drop = False
def teleport(self, boss_name):
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')
proceeds = self.wait_feature('boss_proceed', vertical_variance=1, use_gray_scale=True, threshold=0.8,
time_out=3)
if not proceeds:
self.log_error("can't find the boss_proceed", notify=True)
raise Exception("can't find boss_proceed")
self.sleep(1.5)
self.click_relative(0.04, 0.29)
self.sleep(1)
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)
while index > 4: # first page
self.log_info(f'index {index} greater than 4, swipe')
self.scroll_down_a_page()
index -= 4
# y = y + (index - 1) * distance
self.log_info(f'index after scrolling down {index}')
proceeds = self.find_feature('boss_proceed', vertical_variance=1, use_gray_scale=True, threshold=0.8)
if self.debug:
self.screenshot('proceeds')
if not proceeds:
raise Exception("can't find the boss proceeds")
# self.click_relative(self.crownless_pos[0], self.crownless_pos[1])
# self.wait_click_feature('gray_teleport', raise_if_not_found=True, use_gray_scale=True)
self.wait_feature('gray_teleport', raise_if_not_found=True, use_gray_scale=True, time_out=120,
pre_action=lambda: self.click_box(proceeds[index], relative_x=-1))
self.sleep(1)
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)
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)
def check_main(self):
if not self.in_team()[0]:
self.send_key('esc')
self.sleep(1)
return self.in_team()[0]
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()
while True:
if time.time() - start > 20:
raise Exception("scroll to long")
self.scroll_relative(0.7, 0.5, -1)
self.sleep(0.2)
targets = self.find_feature('target_box', box=target_box, template=source_template)
if targets:
self.log_info(f'scroll to targets {targets} successfully')
break
def run(self):
if not self.check_main():
self.log_error('must be in game world and in teams', notify=True)
self.handler.post(self.mouse_reset, 0.01)
count = 0
while True:
for i in range(1, 4):
key = 'Boss' + str(i)
if boss_name := self.config.get(key):
if boss_name != 'N/A':
count += 1
self.teleport(boss_name)
logger.info(f'farm echo combat once start')
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,
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)
if count == 0:
self.log_error('must choose at least 1 Boss to Farm', notify=True)
return
def incr_drop(self, dropped):
if dropped:
self.info['Echo Count'] = self.info.get('Echo Count', 0) + 1
self.last_drop = dropped