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:
parent
6c3084aa79
commit
1809648cac
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
BIN
assets/4_png.rf.180bb3f2bed38134b1d0bba90c3fcdb0.png
Normal file
BIN
assets/4_png.rf.180bb3f2bed38134b1d0bba90c3fcdb0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
File diff suppressed because it is too large
Load Diff
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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')
|
||||
|
139
src/task/FarmWorldBossTask.py
Normal file
139
src/task/FarmWorldBossTask.py
Normal 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
|
Loading…
x
Reference in New Issue
Block a user