mower-ng/mower/solvers/fight/copy_works.py
zhbaor c86e7ac651
All checks were successful
ci/woodpecker/push/check_format Pipeline was successful
场景图导航改写为solver
2025-01-30 10:14:54 +08:00

132 lines
5 KiB
Python

from datetime import datetime, timedelta
from mower.solvers.fight import FightSolver
from mower.solvers.fight.battle_choose import BattleChooseSolver
from mower.solvers.navigation import NavigationSolver
from mower.utils import config
from mower.utils.email import send_message
from mower.utils.log import logger
from mower.utils.scene import Scene
from mower.utils.solver import BaseSolver
class CopyWorksSolver(BaseSolver):
solver_name = "自动抄作业列表"
def run(self):
if not config.conf.work_enable:
return True
self.conf = config.conf.work
config.load_works()
self.select_data = {}
if self.conf.intelligent_select:
self.init_select_data()
while works := self.conf.works:
for i in range(len(works)):
logger.info(
f"自动战斗列表:({i + 1}/{len(works)}) 关卡:{works[i].stage} 剩余重试次数:{works[i].retry_times}"
)
work = works[0]
copilot = config.works[work.stage]
opers = [oper.model_dump(exclude_none=True) for oper in copilot.opers]
groups = [group.model_dump(exclude_none=True) for group in copilot.groups]
actions = [
action.model_dump(exclude_none=True) for action in copilot.actions
]
self.level_name = work.stage
self.no_potion = False
self.success = False
while work.retry_times + 1 > 0:
if (
self.scheduler_stop_time
and self.scheduler_stop_time - datetime.now() < timedelta(minutes=3)
):
return False
super().run()
if self.no_potion:
break
if self.level_name in self.select_data:
logger.debug(f"智能选择干员 {self.select_data}")
data = self.select_data[self.level_name]
BattleChooseSolver().run(
data["opers"], data["groups"], self.conf.squad, False
)
if not FightSolver().run(
self.level_name, opers, groups, actions, self.conf.squad
):
work.retry_times -= 1
else:
works.pop(0)
self.success = True
break
config.save_conf()
if self.success:
continue
elif work.retry_times < 0:
msg = f"关卡{work.stage}重试次数已用完,请检查相关作业与干员配置"
logger.info(msg)
send_message(msg, level="error")
break
return True # 已清空作业列表|没体力|重试次数用完
def init_select_data(self):
works = self.conf.works
i = 0
while i < len(works):
if "-TR-" in works[i].stage:
i += 1
continue
all_opers = set()
all_groups = set()
data = self.select_data[works[i].stage] = {}
j = i
while j < len(works):
copilot = config.works[works[j].stage]
updated_opers = all_opers | set(copilot.opers)
updated_groups = all_groups | {
group
for group in copilot.groups
if any(oper not in updated_opers for oper in group.opers)
}
if len(updated_opers) + len(updated_groups) > 12:
break
all_opers, all_groups = updated_opers, updated_groups
j += 1
i = j
data["opers"] = [oper.model_dump(exclude_none=True) for oper in all_opers]
data["groups"] = [
group.model_dump(exclude_none=True) for group in all_groups
]
def transition(self):
if (scene := self.scene()) == Scene.OPERATOR_RECOVER_POTION:
if self.conf.use_medicine:
logger.info("体力不足,使用理智药")
self.tap((1635, 865))
return
else:
logger.info("体力不足,未设置使用理智药")
self.no_potion = True
return True
elif scene == Scene.OPERATOR_RECOVER_ORIGINITE:
logger.info("体力不足,没有理智药")
self.no_potion = True
return True
elif scene == Scene.OPERATOR_SELECT:
return True
elif scene == Scene.OPERATOR_BEFORE:
if self.level_name.endswith("#"):
if self.find("ope_ex_mode"):
self.ctap("ope_ex_mode", 3)
return
self.ctap("ope_ex_start", 3)
return
self.ctap("ope_start", 3)
elif scene in self.waiting_scene:
self.waiting_solver()
else:
NavigationSolver().run(self.level_name, mode="copy")