mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-23 17:11:42 +00:00
304 lines
9.4 KiB
Python
304 lines
9.4 KiB
Python
|
from module.logger import logger
|
||
|
from module.map.exception import CampaignEnd
|
||
|
from module.map.fleet import Fleet
|
||
|
from module.map.grid_info import GridInfo
|
||
|
from module.map.map_grids import SelectedGrids, RoadGrids
|
||
|
|
||
|
|
||
|
class Map(Fleet):
|
||
|
def clear_chosen_enemy(self, grid):
|
||
|
"""
|
||
|
Args:
|
||
|
grid (GridInfo):
|
||
|
"""
|
||
|
logger.info('Clear enemy: %s' % grid)
|
||
|
self.show_fleet()
|
||
|
if self.config.ENABLE_EMOTION_REDUCE and self.config.ENABLE_MAP_FLEET_LOCK:
|
||
|
self.emotion.wait()
|
||
|
self.goto(grid, expected='combat')
|
||
|
|
||
|
self.full_scan(battle_count=self.battle_count, mystery_count=self.mystery_count)
|
||
|
self.find_path_initial()
|
||
|
|
||
|
def clear_chosen_mystery(self, grid):
|
||
|
"""
|
||
|
Args:
|
||
|
grid (GridInfo):
|
||
|
"""
|
||
|
logger.info('Clear mystery: %s' % grid)
|
||
|
self.show_fleet()
|
||
|
self.goto(grid, expected='mystery')
|
||
|
# self.mystery_count += 1
|
||
|
|
||
|
def pick_up_ammo(self, grid=None):
|
||
|
"""
|
||
|
Args:
|
||
|
grid (GridInfo):
|
||
|
"""
|
||
|
if grid is None:
|
||
|
grid = self.map.select(may_ammo=True)
|
||
|
if not grid:
|
||
|
logger.warning('Ammo not found')
|
||
|
grid = grid[0]
|
||
|
|
||
|
if self.ammo_count > 0:
|
||
|
logger.info('Pick up ammo: %s' % grid)
|
||
|
self.goto(grid, expected='')
|
||
|
self.goto(grid, expected='')
|
||
|
self.ensure_no_info_bar()
|
||
|
|
||
|
# self.ammo_count -= 5 - self.battle_count
|
||
|
recover = 5 - self.fleet_ammo
|
||
|
recover = 3 if recover > 3 else recover
|
||
|
logger.attr('Got ammo', recover)
|
||
|
|
||
|
self.ammo_count -= recover
|
||
|
self.fleet_ammo += recover
|
||
|
|
||
|
def sort_grids(self, grids, nearby=False, is_accessible=True, scale=(), strongest=False, weakest=False, cost=False, weight=False, ignore=None):
|
||
|
"""
|
||
|
Args:
|
||
|
grids (SelectedGrids):
|
||
|
nearby:
|
||
|
is_accessible:
|
||
|
scale:
|
||
|
strongest:
|
||
|
weakest:
|
||
|
cost:
|
||
|
weight:
|
||
|
ignore:
|
||
|
|
||
|
Returns:
|
||
|
SelectedGrids:
|
||
|
"""
|
||
|
# logger.info(f'nearby={nearby}. is_accessible={is_accessible}.')
|
||
|
# logger.info(f'scale={scale}. strongest={strongest}. weakest={weakest}.')
|
||
|
# logger.info(f'cost={cost}. weight={weight}.')
|
||
|
|
||
|
if nearby:
|
||
|
grids = grids.select(is_nearby=True)
|
||
|
if is_accessible:
|
||
|
grids = grids.select(is_accessible=True)
|
||
|
if ignore is not None:
|
||
|
grids = grids.delete(grids=ignore)
|
||
|
if len(scale):
|
||
|
enemy = SelectedGrids([])
|
||
|
for enemy_scale in scale:
|
||
|
enemy = enemy.add(grids.select(enemy_scale=enemy_scale))
|
||
|
grids = enemy
|
||
|
if strongest:
|
||
|
for scale in [3, 2, 1, 0]:
|
||
|
enemy = grids.select(enemy_scale=scale)
|
||
|
if enemy:
|
||
|
grids = enemy
|
||
|
break
|
||
|
if weakest:
|
||
|
for scale in [1, 2, 3, 0]:
|
||
|
enemy = grids.select(enemy_scale=scale)
|
||
|
if enemy:
|
||
|
grids = enemy
|
||
|
break
|
||
|
|
||
|
if grids:
|
||
|
grids = grids.sort(cost=cost, weight=weight)
|
||
|
|
||
|
return grids
|
||
|
|
||
|
|
||
|
def clear_all_mystery(self, nearby=False, ignore=None):
|
||
|
"""Methods to pick up all mystery.
|
||
|
|
||
|
Args:
|
||
|
nearby (bool): If only walk through ambush save area.
|
||
|
ignore (SelectedGrids): Ignore grids.
|
||
|
|
||
|
Returns:
|
||
|
bool: False, because didn't clear any enemy.
|
||
|
"""
|
||
|
while 1:
|
||
|
self.map.show_cost()
|
||
|
grids = self.map.select(is_mystery=True, is_accessible=True)
|
||
|
if nearby:
|
||
|
grids = grids.select(is_nearby=True)
|
||
|
if ignore is not None:
|
||
|
grids = grids.delete(grids=ignore)
|
||
|
if not grids:
|
||
|
break
|
||
|
|
||
|
logger.hr('Clear all mystery')
|
||
|
grids = grids.sort(cost=True, weight=False)
|
||
|
logger.info('Nearby=%s. grids: %s' % (str(nearby), str(grids)))
|
||
|
self.clear_chosen_mystery(grids[0])
|
||
|
|
||
|
return False
|
||
|
|
||
|
def clear_enemy(self, nearby=False, scale=(), strongest=False):
|
||
|
"""
|
||
|
Methods to clear a enemy. May not do anything if no suitable enemy.
|
||
|
Args:
|
||
|
nearby (bool): If only walk through ambush save area.
|
||
|
scale (tuple[int]): Enemy scale.
|
||
|
strongest (bool): If choose the strongest enemy.
|
||
|
|
||
|
Returns:
|
||
|
bool: True if clear an enemy.
|
||
|
"""
|
||
|
grids = self.map.select(is_enemy=True, is_accessible=True)
|
||
|
if nearby:
|
||
|
grids = grids.select(is_nearby=True)
|
||
|
if len(scale):
|
||
|
enemy = SelectedGrids([])
|
||
|
for enemy_scale in scale:
|
||
|
enemy = enemy.add(grids.select(enemy_scale=enemy_scale))
|
||
|
grids = enemy
|
||
|
if strongest:
|
||
|
for scale in [3, 2, 1, 0]:
|
||
|
enemy = grids.select(enemy_scale=scale)
|
||
|
if enemy:
|
||
|
grids = enemy
|
||
|
break
|
||
|
|
||
|
if grids:
|
||
|
logger.hr('Clear enemy')
|
||
|
grids = grids.sort(cost=True, weight=True)
|
||
|
logger.info(f'Nearby={nearby}. scale={scale}. strongest={strongest}. grids: {grids}')
|
||
|
self.clear_chosen_enemy(grids[0])
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
def clear_roadblocks(self, roads):
|
||
|
"""Clear roadblocks.
|
||
|
|
||
|
Args:
|
||
|
roads(list[RoadGrids]):
|
||
|
|
||
|
Returns:
|
||
|
bool: True if clear an enemy.
|
||
|
"""
|
||
|
grids = SelectedGrids([])
|
||
|
for road in roads:
|
||
|
grids = grids.add(road.roadblocks())
|
||
|
|
||
|
grids = grids.select(is_accessible=True)
|
||
|
|
||
|
if grids:
|
||
|
logger.hr('Clear roadblock')
|
||
|
logger.info('Roadblocks: %s' % str(grids))
|
||
|
grids = grids.sort(cost=False, weight=True)
|
||
|
logger.info('Grids: %s' % str(grids))
|
||
|
self.clear_chosen_enemy(grids[0])
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
def clear_potential_roadblocks(self, roads, **kwargs):
|
||
|
"""Avoid roadblock that only has one grid empty.
|
||
|
|
||
|
Args:
|
||
|
roads(list[RoadGrids]):
|
||
|
|
||
|
Returns:
|
||
|
bool: True if clear an enemy.
|
||
|
"""
|
||
|
grids = SelectedGrids([])
|
||
|
for road in roads:
|
||
|
grids = grids.add(road.potential_roadblocks())
|
||
|
|
||
|
grids = grids.select(is_accessible=True)
|
||
|
|
||
|
if grids:
|
||
|
logger.hr('Avoid potential roadblock')
|
||
|
logger.info(f'Roadblocks potential: {grids}')
|
||
|
grids = grids.sort(cost=False, weight=True)
|
||
|
logger.info('Grids: %s' % str(grids))
|
||
|
self.clear_chosen_enemy(grids[0])
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
def clear_grids_for_faster(self, grids):
|
||
|
"""Clear some grids to walk a shorter distance.
|
||
|
|
||
|
Args:
|
||
|
grids(SelectedGrids):
|
||
|
|
||
|
Returns:
|
||
|
bool: True if clear an enemy.
|
||
|
"""
|
||
|
|
||
|
grids = grids.select(is_enemy=True, is_accessible=True)
|
||
|
|
||
|
if grids:
|
||
|
logger.hr('Clear grids for faster')
|
||
|
grids = grids.sort(cost=True, weight=False)
|
||
|
logger.info('Grids: %s' % str(grids))
|
||
|
self.clear_chosen_enemy(grids[0])
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
def clear_boss(self):
|
||
|
"""Clear BOSS.
|
||
|
|
||
|
Returns:
|
||
|
bool:
|
||
|
"""
|
||
|
grids = self.map.select(is_boss=True, is_accessible=True)
|
||
|
grids = grids.add(self.map.select(may_boss=True, is_enemy=True, is_accessible=True))
|
||
|
logger.info('May boss: %s' % self.map.select(may_boss=True))
|
||
|
logger.info('May boss and is enemy: %s' % self.map.select(may_boss=True, is_enemy=True))
|
||
|
logger.info('Is boss: %s' % self.map.select(is_boss=True))
|
||
|
|
||
|
if grids:
|
||
|
logger.hr('Clear BOSS')
|
||
|
grids = grids.sort(cost=True, weight=True)
|
||
|
logger.info('Grids: %s' % str(grids))
|
||
|
self.clear_chosen_enemy(grids[0])
|
||
|
raise CampaignEnd('BOSS Clear.')
|
||
|
|
||
|
return False
|
||
|
|
||
|
def clear_siren(self):
|
||
|
grids = self.map.select(may_siren=True, is_enemy=True, is_accessible=True)
|
||
|
|
||
|
if grids:
|
||
|
logger.hr('Clear siren')
|
||
|
grids = grids.sort(cost=True, weight=True)
|
||
|
logger.info('Grids: %s' % str(grids))
|
||
|
self.clear_chosen_enemy(grids[0])
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
def fleet_2_step_on(self, grids, roadblocks):
|
||
|
"""Fleet step on a grid which can reduce the ambush frequency another fleet.
|
||
|
Of course, you can simply use 'self.fleet_2.goto(grid)' and do the same thing.
|
||
|
However, roads can be block by enemy and this method can handle that.
|
||
|
|
||
|
Args:
|
||
|
grids (SelectedGrids):
|
||
|
roadblocks (list[RoadGrids]):
|
||
|
|
||
|
Returns:
|
||
|
bool: if clear an enemy.
|
||
|
"""
|
||
|
for grid in grids:
|
||
|
if self.fleet_at(grid=grid, fleet=2):
|
||
|
return False
|
||
|
|
||
|
for grid in grids:
|
||
|
if grid.is_enemy:
|
||
|
continue
|
||
|
if self.check_accessibility(grid=grid, fleet=2):
|
||
|
logger.info('Fleet_2 step on %s' % grid)
|
||
|
self.fleet_2.goto(grid)
|
||
|
self.fleet_1.switch_to()
|
||
|
return False
|
||
|
else:
|
||
|
logger.info('Fleet_2 step on %s got roadblocks.' % grid)
|
||
|
self.fleet_1.clear_roadblocks(roadblocks)
|
||
|
return True
|
||
|
|
||
|
return False
|