mirror of
https://gitee.com/sui-feng-cb/AzurLaneAutoScript1
synced 2026-03-30 02:47:13 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -46,7 +46,7 @@ road_boss = RoadGrids([
|
|||||||
[A5, B6], [A4, B5, B6], C4, C5, [C3, D4], D3, # A6 - D3
|
[A5, B6], [A4, B5, B6], C4, C5, [C3, D4], D3, # A6 - D3
|
||||||
[C5, D3], # D5 - D3
|
[C5, D3], # D5 - D3
|
||||||
[B1, B2], [B1, C2], [C1, C2], [C2, D1], [C2, D2], # A2 - D3
|
[B1, B2], [B1, C2], [C1, C2], [C2, D1], [C2, D2], # A2 - D3
|
||||||
[H3, G2], [G3, G4], [F3, G4], [F3, F4], [F2, F3, E4], [E2, F3, E4], E3 # H4 - D3
|
[H3, G4], [G3, G4], [F3, G4], [F3, F4], [F2, F3, E4], [E2, F3, E4], E3 # H4 - D3
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
40
dev_tools/relative_crop.py
Normal file
40
dev_tools/relative_crop.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import os
|
||||||
|
from PIL import Image
|
||||||
|
import time
|
||||||
|
# os.chdir('../')
|
||||||
|
print(os.getcwd())
|
||||||
|
import module.config.server as server
|
||||||
|
|
||||||
|
server.server = 'cn' # Don't need to edit, it's used to avoid error.
|
||||||
|
|
||||||
|
from module.map.grids import Grids
|
||||||
|
from module.config.config import AzurLaneConfig
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
"""
|
||||||
|
Paste the config of map file here
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
cfg = AzurLaneConfig().merge(Config())
|
||||||
|
|
||||||
|
# Folder to save temp images
|
||||||
|
folder = ''
|
||||||
|
# Put Screenshot here
|
||||||
|
file = ''
|
||||||
|
|
||||||
|
i = Image.open(file).convert('RGB')
|
||||||
|
grids = Grids(i, cfg)
|
||||||
|
grids.predict()
|
||||||
|
grids.show()
|
||||||
|
|
||||||
|
for grid in grids:
|
||||||
|
# Find more relative_crop area in module/map/grid_predictor.py
|
||||||
|
# This one is for `predict_enemy_genre`
|
||||||
|
piece = grid.get_relative_image((-1, -1, 1, 0), output_shape=(120, 60))
|
||||||
|
|
||||||
|
file = '%s_%s_%s.png' % (int(time.time()), grid.location[0], grid.location[1])
|
||||||
|
file = os.path.join(folder, file)
|
||||||
|
piece.save(file)
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
# 参与开发 Development
|
# 参与开发 Development
|
||||||
|
|
||||||
- [如何添加一个按钮 How to add a button](#如何添加一个按钮 How to add a button)
|
- 如何添加一个按钮 How to add a button
|
||||||
- [如何适配一张新的地图 How to adapt to a new map](#如何适配一张新的地图 How to adapt to a new map)
|
- 如何适配一张新的地图 How to adapt to a new map
|
||||||
|
- 如何支持其他服务器/语言 How to support other server/language
|
||||||
|
|
||||||
## 如何添加一个按钮 How to add a button
|
## 如何添加一个按钮 How to add a button
|
||||||
|
|
||||||
@@ -108,6 +109,20 @@ BATTLE_PREPARATION = Button(area=(1043, 607, 1241, 667), color=(234, 179, 97), b
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 如何制作用于敌人识别的模板图片 How to make a template image for enemy detection
|
||||||
|
|
||||||
|
首先, 我们不能直接裁切截图来制作模板图片, 因为地图中的物体是有透视的. 我们需要使用 `dev_tools/relative_crop.py` 来获取图片. `get_relative_image` 可以根据透视裁剪出相对位置的图片, 并放大到固定的大小.
|
||||||
|
|
||||||
|
下图展示了`self.get_relative_image((-1, -1, 1, 0), output_shape=(120, 60))`的裁切区域
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
运行 `dev_tools/relative_crop.py` 后, 会得到大量的临时图片, 找到对应格子的图片, 在图片中裁切出需要的模板.
|
||||||
|
|
||||||
|
将模板图片放置于 `assets/<server>/template` 目录下, 文件名需以 `TEMPLATE_` 开头, 最后运行 button_extract.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 如何适配一张新的地图 How to adapt to a new map
|
## 如何适配一张新的地图 How to adapt to a new map
|
||||||
|
|
||||||
下面举例适配 7-2 的简单版, 完整逻辑在 campaign.campaign_main.campaign_7_2
|
下面举例适配 7-2 的简单版, 完整逻辑在 campaign.campaign_main.campaign_7_2
|
||||||
@@ -430,7 +445,7 @@ class AnotherModule(ModuleBase):
|
|||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
||||||
There area also some modules diffcult to change: the commission module.
|
There area also some modules difficult to change: the commission module.
|
||||||
|
|
||||||
In `./module/reward/commission.py`, I use [cnocr](https://github.com/breezedeus/cnocr) to recognize commission name in chinese, it may not works well in other languages.
|
In `./module/reward/commission.py`, I use [cnocr](https://github.com/breezedeus/cnocr) to recognize commission name in chinese, it may not works well in other languages.
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
# Participate in development
|
# Participate in development
|
||||||
|
|
||||||
- [How to add a button] (#How to add a button)
|
- How to add a button
|
||||||
- [How to adapt to a new map] (#How to adapt to a new map)
|
- How to adapt to a new map
|
||||||
|
- How to support other server/language
|
||||||
|
|
||||||
## How to add a asset
|
## How to add a asset
|
||||||
|
|
||||||
@@ -114,6 +115,20 @@ This is a very useful feature, because the script usually needs to analyze the e
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## How to make a template image for enemy detection
|
||||||
|
|
||||||
|
First of all, we can't simply crop the screenshot to make a template image, because things on the map have perspective. We should use `dev_tools/relative_crop.py` to get the image. `get_relative_image` can do a relative crop according to perspective and rescale to an output_size.
|
||||||
|
|
||||||
|
This image shows the cropping area of `self.get_relative_image((-1, -1, 1, 0), output_shape=(120, 60))`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
After running `dev_tools/relative_crop.py` , you will get a lot of temp images. Find the image of target grid, crop the template.
|
||||||
|
|
||||||
|
Paste the image under `dev_tools/relative_crop.py` , filename should start with `TEMPLATE_` , and run button_extract at last.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## How to adapt to a new map
|
## How to adapt to a new map
|
||||||
|
|
||||||
The following example is adapted to the simple version of 7-2. The complete logic is in `campaign/campaign_main/7_2.py`
|
The following example is adapted to the simple version of 7-2. The complete logic is in `campaign/campaign_main/7_2.py`
|
||||||
@@ -126,7 +141,7 @@ The following example is adapted to the simple version of 7-2. The complete logi
|
|||||||
|
|
||||||
Create a new .py file, the file name is the map name, lowercase, starting with a letter, such as sp3, d3.
|
Create a new .py file, the file name is the map name, lowercase, starting with a letter, such as sp3, d3.
|
||||||
|
|
||||||
2. **Import入**
|
2. **Import**
|
||||||
|
|
||||||
```
|
```
|
||||||
from module.campaign.campaign_base import CampaignBase
|
from module.campaign.campaign_base import CampaignBase
|
||||||
@@ -437,7 +452,7 @@ class AnotherModule(ModuleBase):
|
|||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
||||||
There area also some modules diffcult to change: the commission module.
|
There area also some modules difficult to change: the commission module.
|
||||||
|
|
||||||
In `./module/reward/commission.py`, I use [cnocr](https://github.com/breezedeus/cnocr) to recognize commission name in chinese, it may not works well in other languages.
|
In `./module/reward/commission.py`, I use [cnocr](https://github.com/breezedeus/cnocr) to recognize commission name in chinese, it may not works well in other languages.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ class ExerciseCombat(HpDaemon, OpponentChoose, ExerciseEquipment):
|
|||||||
def _in_exercise(self):
|
def _in_exercise(self):
|
||||||
return self.appear(NEW_OPPONENT)
|
return self.appear(NEW_OPPONENT)
|
||||||
|
|
||||||
|
def is_combat_executing(self):
|
||||||
|
"""
|
||||||
|
Returns:
|
||||||
|
bool:
|
||||||
|
"""
|
||||||
|
return self.appear(PAUSE) and np.max(self.device.image.crop(PAUSE_DOUBLE_CHECK.area)) < 153
|
||||||
|
|
||||||
def _combat_preparation(self):
|
def _combat_preparation(self):
|
||||||
logger.info('Combat preparation')
|
logger.info('Combat preparation')
|
||||||
while 1:
|
while 1:
|
||||||
@@ -40,16 +47,17 @@ class ExerciseCombat(HpDaemon, OpponentChoose, ExerciseEquipment):
|
|||||||
while 1:
|
while 1:
|
||||||
self.device.screenshot()
|
self.device.screenshot()
|
||||||
|
|
||||||
# Finish - S or D rank
|
if not self.is_combat_executing():
|
||||||
if self.appear_then_click(BATTLE_STATUS_S):
|
# Finish - S or D rank
|
||||||
success = True
|
if self.appear_then_click(BATTLE_STATUS_S):
|
||||||
end = True
|
success = True
|
||||||
continue
|
end = True
|
||||||
if self.appear_then_click(BATTLE_STATUS_D):
|
continue
|
||||||
success = True
|
if self.appear_then_click(BATTLE_STATUS_D):
|
||||||
end = True
|
success = True
|
||||||
logger.info("Exercise LOST")
|
end = True
|
||||||
continue
|
logger.info("Exercise LOST")
|
||||||
|
continue
|
||||||
if self.appear_then_click(GET_ITEMS_1):
|
if self.appear_then_click(GET_ITEMS_1):
|
||||||
continue
|
continue
|
||||||
if self.appear_then_click(EXP_INFO_S):
|
if self.appear_then_click(EXP_INFO_S):
|
||||||
|
|||||||
@@ -43,18 +43,22 @@ class InfoHandler(ModuleBase):
|
|||||||
"""
|
"""
|
||||||
_popup_offset = (3, 30)
|
_popup_offset = (3, 30)
|
||||||
|
|
||||||
def handle_popup_confirm(self):
|
def handle_popup_confirm(self, name=''):
|
||||||
if self.appear(POPUP_CANCEL, offset=self._popup_offset) \
|
if self.appear(POPUP_CANCEL, offset=self._popup_offset) \
|
||||||
and self.appear(POPUP_CONFIRM, offset=self._popup_offset, interval=2):
|
and self.appear(POPUP_CONFIRM, offset=self._popup_offset, interval=2):
|
||||||
|
POPUP_CONFIRM.name = POPUP_CONFIRM.name + '_' + name
|
||||||
self.device.click(POPUP_CONFIRM)
|
self.device.click(POPUP_CONFIRM)
|
||||||
|
POPUP_CONFIRM.name = POPUP_CONFIRM.name[:-len(name) - 1]
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handle_popup_cancel(self):
|
def handle_popup_cancel(self, name=''):
|
||||||
if self.appear(POPUP_CONFIRM, offset=self._popup_offset) \
|
if self.appear(POPUP_CONFIRM, offset=self._popup_offset) \
|
||||||
and self.appear(POPUP_CANCEL, offset=self._popup_offset, interval=2):
|
and self.appear(POPUP_CANCEL, offset=self._popup_offset, interval=2):
|
||||||
|
POPUP_CANCEL.name = POPUP_CANCEL.name + '_' + name
|
||||||
self.device.click(POPUP_CANCEL)
|
self.device.click(POPUP_CANCEL)
|
||||||
|
POPUP_CANCEL.name = POPUP_CANCEL.name[:-len(name) - 1]
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -83,7 +87,7 @@ class InfoHandler(ModuleBase):
|
|||||||
if not self.config.IGNORE_LOW_EMOTION_WARN:
|
if not self.config.IGNORE_LOW_EMOTION_WARN:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return self.handle_popup_confirm()
|
return self.handle_popup_confirm('IGNORE_LOW_EMOTION')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Story
|
Story
|
||||||
|
|||||||
Reference in New Issue
Block a user