mirror of
https://gitee.com/sui-feng-cb/AzurLaneAutoScript1
synced 2026-03-21 13:45:34 +08:00
Fix: Map swipe optimize should use local map view to generate blacklist
- Opt: Take less screenshots during swipe, reuse local view object as possible - Refactor: handle_boss_appear_refocus() - Fix: Update swipe box area in map, avoid clicking auto search
This commit is contained in:
@@ -20,11 +20,10 @@ class Camera(MapOperation):
|
||||
map: CampaignMap
|
||||
camera = (0, 0)
|
||||
grid_class = Grid
|
||||
_correct_camera = False
|
||||
_prev_view = None
|
||||
_prev_swipe = None
|
||||
|
||||
def _map_swipe(self, vector, box=(123, 159, 1193, 628)):
|
||||
def _map_swipe(self, vector, box=(123, 159, 1175, 628)):
|
||||
"""
|
||||
Args:
|
||||
vector (tuple, np.ndarray): float
|
||||
@@ -53,7 +52,9 @@ class Camera(MapOperation):
|
||||
self.device.sleep(0.3)
|
||||
self.update()
|
||||
else:
|
||||
self.update(camera=False)
|
||||
# Drop swipe
|
||||
# self.update(camera=False)
|
||||
pass
|
||||
|
||||
def map_swipe(self, vector):
|
||||
"""
|
||||
@@ -109,7 +110,7 @@ class Camera(MapOperation):
|
||||
self._view_init()
|
||||
try:
|
||||
self.view.load(self.device.image)
|
||||
except (MapDetectionError, AttributeError) as e:
|
||||
except MapDetectionError as e:
|
||||
if self.info_bar_count():
|
||||
logger.info('Perspective error cause by info bar. Waiting.')
|
||||
self.handle_info_bar()
|
||||
@@ -151,9 +152,6 @@ class Camera(MapOperation):
|
||||
self._prev_swipe = None
|
||||
self.show_camera()
|
||||
|
||||
if not self._correct_camera:
|
||||
self.show_camera()
|
||||
return False
|
||||
# Set camera position
|
||||
if self.view.left_edge:
|
||||
x = 0 + self.view.center_loca[0]
|
||||
@@ -173,14 +171,16 @@ class Camera(MapOperation):
|
||||
self.camera = (x, y)
|
||||
self.show_camera()
|
||||
|
||||
def predict(self, mode='normal'):
|
||||
self.predict()
|
||||
|
||||
def predict(self):
|
||||
self.view.predict()
|
||||
self.map.update(grids=self.view, camera=self.camera, mode=mode)
|
||||
self.view.show()
|
||||
|
||||
def show_camera(self):
|
||||
logger.attr_align('Camera', location2node(self.camera))
|
||||
|
||||
def ensure_edge_insight(self, reverse=False, preset=None, swipe_limit=(3, 2)):
|
||||
def ensure_edge_insight(self, reverse=False, preset=None, swipe_limit=(3, 2), skip_first_update=True):
|
||||
"""
|
||||
Swipe to bottom left until two edges insight.
|
||||
Edges are used to locate camera.
|
||||
@@ -189,18 +189,19 @@ class Camera(MapOperation):
|
||||
reverse (bool): Reverse swipes.
|
||||
preset (tuple(int)): Set in map swipe manually.
|
||||
swipe_limit (tuple): (x, y). Limit swipe in (-x, -y, x, y).
|
||||
skip_first_update (bool): Usually to be True. Use False if you are calling ensure_edge_insight manually.
|
||||
|
||||
Returns:
|
||||
list[tuple]: Swipe record.
|
||||
"""
|
||||
logger.info(f'Ensure edge in sight.')
|
||||
record = []
|
||||
self._correct_camera = True
|
||||
x_swipe, y_swipe = np.multiply(swipe_limit, random_direction(self.config.MAP_ENSURE_EDGE_INSIGHT_CORNER))
|
||||
|
||||
while 1:
|
||||
if len(record) == 0:
|
||||
self.update()
|
||||
if not skip_first_update:
|
||||
self.update()
|
||||
if preset is not None:
|
||||
self.map_swipe(preset)
|
||||
record.append(preset)
|
||||
@@ -217,8 +218,6 @@ class Camera(MapOperation):
|
||||
if x == 0 and y == 0:
|
||||
break
|
||||
|
||||
# self._correct_camera = False
|
||||
|
||||
if reverse:
|
||||
logger.info('Reverse swipes.')
|
||||
for vector in record[::-1]:
|
||||
@@ -279,10 +278,9 @@ class Camera(MapOperation):
|
||||
queue = queue.sort_by_camera_distance(self.camera)
|
||||
self.focus_to(queue[0])
|
||||
self.focus_to_grid_center(0.25)
|
||||
self.view.predict()
|
||||
success = self.map.update(grids=self.view, camera=self.camera, mode=mode)
|
||||
if not success:
|
||||
self.ensure_edge_insight()
|
||||
self.ensure_edge_insight(skip_first_update=False)
|
||||
continue
|
||||
|
||||
queue = queue[1:]
|
||||
@@ -405,30 +403,36 @@ class Camera(MapOperation):
|
||||
"""
|
||||
map_vector = np.array(map_vector)
|
||||
|
||||
def filter_grids(globe_grids, pad=0):
|
||||
def local_to_area(local_grid, pad=0):
|
||||
result = []
|
||||
for local in local_grid:
|
||||
# Predict the position of grid after swipe.
|
||||
# Swipe should ends there, to prevent treating swipe as click.
|
||||
area = area_offset((0, 0, 1, 1), offset=-map_vector)
|
||||
corner = local.grid2screen(area2corner(area))
|
||||
area = trapezoid2area(corner, pad=pad)
|
||||
result.append(area)
|
||||
return result
|
||||
|
||||
def globe_to_local(globe_grids):
|
||||
result = []
|
||||
for globe in globe_grids:
|
||||
location = tuple(np.array(globe.location) - self.camera + self.view.center_loca)
|
||||
if location in self.view:
|
||||
# Predict the position of grid after swipe.
|
||||
# Swipe should ends there, to prevent treating swipe as click.
|
||||
local = self.view[location]
|
||||
area = area_offset((0, 0, 1, 1), offset=-map_vector)
|
||||
corner = local.grid2screen(area2corner(area))
|
||||
area = trapezoid2area(corner, pad=pad)
|
||||
result.append(area)
|
||||
result.append(local)
|
||||
return result
|
||||
|
||||
whitelist = self.map.select(is_land=True) \
|
||||
.add(self.map.select(is_current_fleet=True)) \
|
||||
.sort_by_camera_distance(self.camera)
|
||||
blacklist = self.map.select(is_sea=False) \
|
||||
.delete(self.map.select(is_land=True)) \
|
||||
.add(self.map.select(is_fleet=True, is_current_fleet=False)) \
|
||||
.add(self.map.select(is_mystery=True)) \
|
||||
.sort_by_camera_distance(self.camera)
|
||||
blacklist = self.view.select(is_enemy=True) \
|
||||
.add(self.view.select(is_siren=True)) \
|
||||
.add(self.view.select(is_mystery=True)) \
|
||||
.add(self.view.select(is_fleet=True, is_current_fleet=False))
|
||||
|
||||
whitelist = filter_grids(whitelist, pad=25)
|
||||
blacklist = filter_grids(blacklist, pad=-5)
|
||||
# self.view.show()
|
||||
whitelist = local_to_area(globe_to_local(whitelist), pad=25)
|
||||
blacklist = [grid.outer for grid in blacklist] + local_to_area(blacklist, pad=-5)
|
||||
|
||||
return whitelist, blacklist
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import itertools
|
||||
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.exception import MapWalkError, MapEnemyMoved
|
||||
from module.exception import MapWalkError, MapEnemyMoved, MapDetectionError
|
||||
from module.handler.ambush import AmbushHandler
|
||||
from module.logger import logger
|
||||
from module.map.camera import Camera
|
||||
@@ -298,7 +300,8 @@ class Fleet(Camera, AmbushHandler):
|
||||
elif self.map[location].may_enemy:
|
||||
self.map[location].is_cleared = True
|
||||
|
||||
self.handle_boss_appear_refocus()
|
||||
if self.catch_boss_appear():
|
||||
self.handle_boss_appear_refocus()
|
||||
if self.config.MAP_FOCUS_ENEMY_AFTER_BATTLE:
|
||||
self.camera = location
|
||||
self.update()
|
||||
@@ -364,6 +367,7 @@ class Fleet(Camera, AmbushHandler):
|
||||
break
|
||||
if walk_timeout.reached():
|
||||
logger.warning('Walk timeout. Retrying.')
|
||||
self.predict()
|
||||
self.ensure_edge_insight()
|
||||
break
|
||||
|
||||
@@ -382,8 +386,11 @@ class Fleet(Camera, AmbushHandler):
|
||||
self.full_scan_carrier()
|
||||
if result == 'combat':
|
||||
self.round_battle()
|
||||
self.predict()
|
||||
self.round_next()
|
||||
if self.round_is_new:
|
||||
if result != 'combat':
|
||||
self.predict()
|
||||
self.full_scan_movable(enemy_cleared=result == 'combat')
|
||||
self.find_path_initial()
|
||||
raise MapEnemyMoved
|
||||
@@ -422,6 +429,7 @@ class Fleet(Camera, AmbushHandler):
|
||||
self._goto(node, expected=expected if node == nodes[-1] else '')
|
||||
except MapWalkError:
|
||||
logger.warning('Map walk error.')
|
||||
self.predict()
|
||||
self.ensure_edge_insight()
|
||||
nodes_ = self.map.find_path(node, step=1)
|
||||
for node_ in nodes_:
|
||||
@@ -845,7 +853,7 @@ class Fleet(Camera, AmbushHandler):
|
||||
|
||||
logger.warning('Enemy roadblock try exhausted.')
|
||||
|
||||
def handle_boss_appear_refocus(self):
|
||||
def catch_boss_appear(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
@@ -868,14 +876,33 @@ class Fleet(Camera, AmbushHandler):
|
||||
# g.wipe_out()
|
||||
# break
|
||||
|
||||
if appear:
|
||||
camera = self.camera
|
||||
return appear
|
||||
|
||||
def handle_boss_appear_refocus(self, preset=None):
|
||||
"""
|
||||
Refocus to previous camera position after boss appear.
|
||||
|
||||
Args:
|
||||
preset (tuple): (x, y).
|
||||
"""
|
||||
camera = self.camera
|
||||
if preset is None:
|
||||
preset = self.config.MAP_BOSS_APPEAR_REFOCUS_SWIPE
|
||||
|
||||
if preset is not None and np.linalg.norm(preset) > 0:
|
||||
try:
|
||||
self.update()
|
||||
except MapDetectionError:
|
||||
logger.info(f'MapDetectionError occurs after boss appear, trying swipe preset {preset}')
|
||||
# Swipe optimize here may not be accurate.
|
||||
self.map_swipe(preset)
|
||||
self.ensure_edge_insight()
|
||||
logger.info('Refocus to previous camera position.')
|
||||
self.focus_to(camera)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
self.update()
|
||||
self.ensure_edge_insight()
|
||||
|
||||
logger.info('Refocus to previous camera position.')
|
||||
self.focus_to(camera)
|
||||
|
||||
def fleet_checked_reset(self):
|
||||
self.map_fleet_checked = False
|
||||
|
||||
@@ -294,7 +294,7 @@ class CampaignMap:
|
||||
mode (str): Scan mode, such as 'normal', 'carrier', 'movable'
|
||||
"""
|
||||
offset = np.array(camera) - np.array(grids.center_loca)
|
||||
grids.show()
|
||||
# grids.show()
|
||||
|
||||
failed_count = 0
|
||||
for grid in grids.grids.values():
|
||||
|
||||
Reference in New Issue
Block a user