Merge branch 'main' of https://git.zhaozuohong.vip/mower-ng/mower-ng
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful

This commit is contained in:
fuyn101 2024-10-08 09:31:45 +08:00
commit ead4ee3db4
5 changed files with 105 additions and 102 deletions

View file

@ -5,20 +5,23 @@ from scipy.signal import argrelmax
from skimage.metrics import structural_similarity
from mower.models import secret_front
from mower.solvers.navigation import NavigationSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.character_recognize import match_avatar
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, loadres, thres2
from mower.utils.log import logger
from mower.utils.solver import BaseSolver
from mower.utils.scene import Scene
from mower.utils.tile_pos import Calc, find_level
from mower.utils.vector import sa, va
class AutoFight(BaseSolver):
class AutoFight(SceneGraphSolver):
def run(self, level_name, opers, actions):
logger.info("Start: 自动战斗")
logger.info("地图坐标计算https://github.com/yuanyan3060/Arknights-Tile-Pos")
self.level_name = level_name
level = find_level(level_name, None)
self.calc = Calc(1920, 1080, level)
self.actions = actions
@ -101,39 +104,6 @@ class AutoFight(BaseSolver):
logger.debug(f"{min_val=} {min_loc=}")
return min_val <= 0.2
def in_fight(self) -> bool:
"是否在战斗中"
img = cropimg(config.recog.img, ((725, 16), (797, 76)))
img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
img = cv2.inRange(img, (12, 0, 0), (16, 255, 255))
tpl = loadres("fight/enemy", True)
result = cv2.matchTemplate(img, tpl, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
value = 0.4
logger.debug(f"{min_val}小于{value}则判定在战斗")
return min_val < value
def battle_complete(self) -> bool:
"识别行动是否结束"
img = cropimg(config.recog.gray, ((87, 268), (529, 383)))
img = thres2(img, 200)
tpl = loadres("fight/complete", True)
result = cv2.matchTemplate(img, tpl, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
value = 0.4
logger.debug(f"{min_val}小于{value}则判定行动结束/胜利")
return min_val < value
def battle_fail(self) -> bool:
"识别行动是否失败"
img = cropimg(config.recog.gray, ((1129, 455), (1626, 531)))
tpl = loadres("fight/failed_text", True)
result = cv2.matchTemplate(img, tpl, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
value = 0.05
logger.debug(f"{min_val}小于{value}则判定行动失败")
return min_val < value # 测试时数值很低基本为0或有其他方法
def update_operators(self):
"识别可部署的干员"
config.recog.update()
@ -273,21 +243,7 @@ class AutoFight(BaseSolver):
sleep(0.5)
def transition(self):
config.recog.update()
if not self.in_fight():
if self.battle_fail():
logger.warning("行动失败,请检查干员/练度")
return True
elif self.battle_complete():
logger.info("行动结束")
return True
else:
sleep(2)
return
# if self.action is None:
# self.sleep(10)
# return
if (scene := self.scene()) == Scene.OPERATOR_FIGHT:
if self.loading:
self.pause()
self.loading = False
@ -314,3 +270,22 @@ class AutoFight(BaseSolver):
self.deploy()
elif self.action["type"] == "Retreat":
self.withdraw()
elif scene == Scene.OPERATOR_FAILED:
logger.warning("行动失败,请检查干员/练度")
return True
elif scene == Scene.OPERATOR_FINISH:
logger.info("行动结束")
return True
elif scene == Scene.CONFIRM:
logger.warning("被顶号")
return True
elif scene in self.waiting_scene:
self.waiting_solver()
elif scene == Scene.OPERATOR_SELECT:
self.tap((1655, 781))
else:
NavigationSolver().run(self.level_name, mode="copy")

View file

@ -21,7 +21,7 @@ class CreditFight(SceneGraphSolver):
logger.info("Start: 信用作战")
self.support = False
navi_solver = NavigationSolver()
navi_solver.run("OF-1")
navi_solver.run("OF-1", mode="copy")
super().run()
def choose_support(self):
@ -48,16 +48,7 @@ class CreditFight(SceneGraphSolver):
return count.index(max(count)) + 1
def transition(self):
if (scene := self.scene()) == Scene.OPERATOR_BEFORE:
if config.recog.gray[65][1333] < 200:
self.sleep()
return
# 取消代理作战
if config.recog.gray[907][1600] > 127:
self.tap((1776, 908))
return
self.tap_element("ope_start", interval=2)
elif scene == Scene.OPERATOR_SELECT:
if (scene := self.scene()) == Scene.OPERATOR_SELECT:
if self.find("ope_select_start_empty"):
logger.info("编队内没有编入干员,停止OF-1")
return True

View file

@ -59,7 +59,7 @@ class GetOrderRemainingTimeSolver(SceneGraphSolver, BaseMixin):
return value
def read_remain_time(self, pos) -> int:
h, m, s = self.number(pos, 19, 100).split("::")
h, m, s = self.number(pos, 19, 115).split("::")
return int(h) * 3600 + int(m) * 60 + int(s)
def timeout(self) -> bool:

View file

@ -430,8 +430,12 @@ difficulty_str = [
class NavigationSolver(SceneGraphSolver):
def run(self, name: str):
if LastStageNavigation().run(name):
def run(self, name: str, mode: str = "auto"):
"""
mode:默认为auto,抄作业为copy
"""
if LastStageNavigation().run(name, mode):
return True
if name in ActivityNavigation.location:
ActivityNavigation().run(name)
@ -440,6 +444,7 @@ class NavigationSolver(SceneGraphSolver):
self.success = False
self.act = None
self.name = name
self.mode = mode
prefix = name.split("-")[0]
pr_prefix = ""
if prefix == "PR":
@ -617,6 +622,7 @@ class NavigationSolver(SceneGraphSolver):
self.success = True
self.tap(va(target, (60, 20)))
elif scene == Scene.OPERATOR_BEFORE:
if self.mode == "auto":
if self.act == 2:
if self.change_to is not None:
logger.info(f"{self.name} 无法代理")
@ -634,5 +640,20 @@ class NavigationSolver(SceneGraphSolver):
return True
else:
self.back()
elif self.mode == "copy":
if config.recog.gray[65][1333] < 200:
self.sleep()
return
# 取消代理作战
if config.recog.gray[907][1600] > 127 and not self.find(
"ope_agency_lock"
):
self.tap((1776, 908))
return
self.tap_element("ope_start", interval=2)
elif scene == Scene.OPERATOR_SELECT and self.success:
return True
else:
self.scene_graph_step(Scene.TERMINAL_MAIN)

View file

@ -10,8 +10,9 @@ from .utils import last_letters
class LastStageNavigation(SceneGraphSolver):
def run(self, name: str) -> None:
def run(self, name: str, mode: str) -> None:
self.name = name
self.mode = mode
self.success = True
if self.name != "":
self.scene_graph_navigation(Scene.TERMINAL_MAIN)
@ -59,6 +60,21 @@ class LastStageNavigation(SceneGraphSolver):
self.success = False
return True
elif scene == Scene.OPERATOR_BEFORE:
if self.mode == "auto":
return True
else:
if config.recog.gray[65][1333] < 200:
self.sleep()
return
# 取消代理作战
if config.recog.gray[907][1600] > 127 and not self.find(
"ope_agency_lock"
):
self.tap((1776, 908))
return
self.tap_element("ope_start", interval=2)
elif scene == Scene.OPERATOR_SELECT and self.mode == "copy":
return True
else:
self.scene_graph_step(Scene.TERMINAL_MAIN)