140 lines
5.2 KiB
Python
140 lines
5.2 KiB
Python
import cv2
|
|
|
|
from mower.data import agent_list
|
|
from mower.utils import config
|
|
from mower.utils import typealias as tp
|
|
from mower.utils.character_recognize import match_portrait
|
|
from mower.utils.graph import SceneGraphSolver
|
|
from mower.utils.image import cropimg, loadres, thres2
|
|
from mower.utils.log import logger
|
|
from mower.utils.recognize import Scene
|
|
from mower.utils.vector import ss, va
|
|
|
|
from .utils import generate_image, translate
|
|
|
|
agent = ["无需增调干员", "先锋", "近卫", "重装", "术士", "狙击", "医疗", "辅助", "特种"]
|
|
|
|
|
|
class SSSDROPSolver(SceneGraphSolver):
|
|
def run(self, drops: list, blacklist: list = []) -> bool:
|
|
self.drops = drops
|
|
self.choose = False
|
|
self.blacklist = set(blacklist)
|
|
self.transelate_name()
|
|
super().run()
|
|
|
|
def transelate_name(self):
|
|
for i in range(len(self.drops)):
|
|
if self.drops[i] in translate:
|
|
self.drops[i] = translate[self.drops[i]]
|
|
|
|
def find_EC(self, drop: str, fs: int, scope: tp.Scope):
|
|
img = cropimg(config.recog.gray, scope)
|
|
res = generate_image(drop, fs)
|
|
result = cv2.matchTemplate(img, res, cv2.TM_CCOEFF_NORMED)
|
|
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
|
|
h, w = res.shape
|
|
logger.debug(f"drop:{drop},max_val:{max_val}")
|
|
if max_val > 0.8:
|
|
return va((max_loc[0], max_loc[1]), scope[0])
|
|
|
|
def find_PR_in_fight(self, drop: str, scope: tp.Scope):
|
|
img = cropimg(config.recog.img, scope)
|
|
res = loadres(f"sss/drop/{drop}")
|
|
res = cv2.resize(res, (61, 61), interpolation=cv2.INTER_LINEAR)
|
|
result = cv2.matchTemplate(img, res, cv2.TM_CCOEFF_NORMED)
|
|
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
|
|
h, w, _ = res.shape
|
|
logger.debug(f"drop:{drop},max_val:{max_val}")
|
|
if max_val > 0.8:
|
|
return va((max_loc[0], max_loc[1]), scope[0])
|
|
|
|
def match_operators(self):
|
|
img = cropimg(config.recog.gray, ((50, 231), (1900, 850)))
|
|
img = thres2(img, 38)
|
|
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
|
rect = filter(
|
|
lambda x: x[2] > 200, map(lambda c: cv2.boundingRect(c), contours)
|
|
)
|
|
segment = []
|
|
for x, y, w, h in rect:
|
|
top_left = va((x, y), (50, 350))
|
|
bottom_right = va((x + w + 50, y + h + 231), (0, -230))
|
|
segment.append(ss(2 / 3, 2 / 3, (top_left, bottom_right)))
|
|
match_opers = dict(
|
|
match_portrait(
|
|
cv2.resize(config.recog.gray, (int(1920 / 1.5), int(1080 / 1.5))),
|
|
segment=segment,
|
|
)
|
|
)
|
|
logger.info(match_opers.keys())
|
|
res = {}
|
|
for name, scope in match_opers.items():
|
|
if name and name not in self.blacklist:
|
|
res[translate[agent_list[name]["profession"]]] = self.get_pos(
|
|
ss(1.5, 1.5, scope)
|
|
)
|
|
logger.info(f"不在黑名单的干员:{res}")
|
|
return res
|
|
|
|
def transition(self):
|
|
if (scene := self.scene()) == Scene.SSS_DROP_AGENT_BEFORE_FIGHT:
|
|
if self.choose and (
|
|
self.find("sss/drop_check") or self.find("sss/no_drop_check")
|
|
):
|
|
self.tap((1794, 900))
|
|
self.choose = False
|
|
self.sleep(2)
|
|
return
|
|
else:
|
|
opers = self.match_operators()
|
|
if pos := self.find("sss/drop/无需增调干员"):
|
|
opers["无需增调干员"] = pos
|
|
|
|
for drop in self.drops:
|
|
if drop in opers:
|
|
self.tap(opers[drop])
|
|
self.sleep(0.5)
|
|
self.choose = True
|
|
return
|
|
|
|
elif scene == Scene.SSS_DROP_IN_FIGHT:
|
|
for drop in self.drops:
|
|
if drop not in agent:
|
|
if pos := self.find_EC(drop, 29, ((510, 700), (1480, 770))):
|
|
self.tap(pos)
|
|
self.sleep(0.5)
|
|
self.tap((1750, 550))
|
|
return
|
|
else:
|
|
if pos := self.find_PR_in_fight(drop, ((468, 735), (1321, 797))):
|
|
self.tap(pos)
|
|
self.sleep(0.5)
|
|
self.tap((1750, 550))
|
|
return
|
|
self.tap_element("sss/abandon")
|
|
|
|
elif scene == Scene.SSS_DROP_EC_BEFORE_FIGHT:
|
|
if self.choose and self.find("sss/drop_check"):
|
|
self.tap((1794, 900))
|
|
return
|
|
else:
|
|
for drop in self.drops:
|
|
if drop not in agent:
|
|
if pos := self.find_EC(drop, 30, ((640, 630), (1280, 700))):
|
|
self.tap(pos)
|
|
self.sleep(0.5)
|
|
self.choose = True
|
|
return
|
|
|
|
elif scene == Scene.SSS_ABANDON_DROP_IN_FIGHT:
|
|
self.scene_graph_step(Scene.OPERATOR_FIGHT)
|
|
|
|
elif scene in [Scene.OPERATOR_FIGHT, Scene.SSS_ACTION]:
|
|
return True
|
|
|
|
elif scene in self.waiting_scene:
|
|
self.waiting_solver()
|
|
|
|
else:
|
|
return True
|