Add: hazard 1 leveling
4
alas.py
@ -308,6 +308,10 @@ class AzurLaneAutoScript:
|
||||
from module.campaign.os_run import OSCampaignRun
|
||||
OSCampaignRun(config=self.config, device=self.device).opsi_meowfficer_farming()
|
||||
|
||||
def opsi_hazard1_leveling(self):
|
||||
from module.campaign.os_run import OSCampaignRun
|
||||
OSCampaignRun(config=self.config, device=self.device).opsi_hazard1_leveling()
|
||||
|
||||
def main(self):
|
||||
from module.campaign.run import CampaignRun
|
||||
CampaignRun(config=self.config, device=self.device).run(
|
||||
|
BIN
assets/cn/os_handler/ACTION_POINT_REMAIN_OS.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_MAP_OPTION_OFF.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_POPUP_CHECK.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_OFF.BUTTON.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_OFF.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_ON.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_SCROLL_AREA.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_WAIT_2_CHECK.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_WAIT_OFF.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_WAIT_ON.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_OFF.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_ON.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
@ -1550,7 +1550,7 @@
|
||||
"Command": "OpsiAbyssal",
|
||||
"SuccessInterval": 60,
|
||||
"FailureInterval": 60,
|
||||
"ServerUpdate": "00:00"
|
||||
"ServerUpdate": "00:00, 12:00"
|
||||
},
|
||||
"OpsiAbyssal": {
|
||||
"ForceRun": false
|
||||
@ -1585,7 +1585,7 @@
|
||||
"ServerUpdate": "00:00"
|
||||
},
|
||||
"OpsiMeowfficerFarming": {
|
||||
"ActionPointPreserve": 500,
|
||||
"ActionPointPreserve": 1000,
|
||||
"HazardLevel": 5,
|
||||
"TargetZone": 0
|
||||
},
|
||||
@ -1594,6 +1594,24 @@
|
||||
"Submarine": false
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"Scheduler": {
|
||||
"Enable": false,
|
||||
"NextRun": "2020-01-01 00:00:00",
|
||||
"Command": "OpsiHazard1Leveling",
|
||||
"SuccessInterval": 30,
|
||||
"FailureInterval": 60,
|
||||
"ServerUpdate": "00:00"
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"StrategySearch": true,
|
||||
"TargetZone": 0
|
||||
},
|
||||
"OpsiFleet": {
|
||||
"Fleet": 1,
|
||||
"Submarine": false
|
||||
}
|
||||
},
|
||||
"Daemon": {
|
||||
"Daemon": {
|
||||
"EnterMap": true
|
||||
|
@ -54,6 +54,26 @@ class OSCampaignRun(OSMapOperation):
|
||||
logger.info('Just less than 1 day to OpSi reset, delay 2.5 hours')
|
||||
self.config.task_delay(minute=150, server_update=True)
|
||||
|
||||
def opsi_hazard1_leveling(self):
|
||||
self.config.override(
|
||||
OpsiGeneral_AkashiShopFilter='ActionPoint'
|
||||
)
|
||||
self.config.cross_set(keys='OpsiMeowfficerFarming.Scheduler.Enable', value=True)
|
||||
if self.config.cross_get(
|
||||
keys='OpsiMeowfficerFarming.OpsiMeowfficerFarming.ActionPointPreserve',
|
||||
default=0
|
||||
) < 1000:
|
||||
self.config.cross_set(
|
||||
keys='OpsiMeowfficerFarming.OpsiMeowfficerFarming.ActionPointPreserve',
|
||||
value=1000
|
||||
)
|
||||
|
||||
self.load_campaign()
|
||||
try:
|
||||
self.campaign.os_hazard1_leveling()
|
||||
except ActionPointLimit:
|
||||
self.config.task_delay(server_update=True)
|
||||
|
||||
def opsi_obscure(self):
|
||||
self.load_campaign()
|
||||
try:
|
||||
|
@ -3281,10 +3281,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"cn": "event_20201229_cn",
|
||||
"en": "event_20201229_cn",
|
||||
"jp": "event_20201229_cn",
|
||||
"tw": "event_20211111_cn"
|
||||
"tw": "event_20211111_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -7772,7 +7772,7 @@
|
||||
},
|
||||
"ServerUpdate": {
|
||||
"type": "input",
|
||||
"value": "00:00",
|
||||
"value": "00:00, 12:00",
|
||||
"display": "hide"
|
||||
}
|
||||
},
|
||||
@ -7869,7 +7869,7 @@
|
||||
"OpsiMeowfficerFarming": {
|
||||
"ActionPointPreserve": {
|
||||
"type": "input",
|
||||
"value": 500
|
||||
"value": 1000
|
||||
},
|
||||
"HazardLevel": {
|
||||
"type": "select",
|
||||
@ -7904,6 +7904,71 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"Scheduler": {
|
||||
"Enable": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"NextRun": {
|
||||
"type": "datetime",
|
||||
"value": "2020-01-01 00:00:00",
|
||||
"validate": "datetime"
|
||||
},
|
||||
"Command": {
|
||||
"type": "input",
|
||||
"value": "OpsiHazard1Leveling",
|
||||
"display": "hide"
|
||||
},
|
||||
"SuccessInterval": {
|
||||
"type": "input",
|
||||
"value": 30,
|
||||
"display": "hide"
|
||||
},
|
||||
"FailureInterval": {
|
||||
"type": "input",
|
||||
"value": 60,
|
||||
"display": "hide"
|
||||
},
|
||||
"ServerUpdate": {
|
||||
"type": "input",
|
||||
"value": "00:00",
|
||||
"display": "hide"
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"StrategySearch": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
},
|
||||
"TargetZone": {
|
||||
"type": "select",
|
||||
"value": 0,
|
||||
"option": [
|
||||
0,
|
||||
44,
|
||||
22
|
||||
]
|
||||
}
|
||||
},
|
||||
"OpsiFleet": {
|
||||
"Fleet": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
},
|
||||
"Submarine": {
|
||||
"type": "checkbox",
|
||||
"value": false,
|
||||
"display": "hide"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Daemon": {
|
||||
"Daemon": {
|
||||
"EnterMap": {
|
||||
|
@ -569,12 +569,17 @@ OpsiAbyssal:
|
||||
OpsiStronghold:
|
||||
ForceRun: false
|
||||
OpsiMeowfficerFarming:
|
||||
ActionPointPreserve: 500
|
||||
ActionPointPreserve: 1000
|
||||
HazardLevel:
|
||||
value: 5
|
||||
option: [3, 4, 5, 6, 10]
|
||||
TargetZone:
|
||||
value: 0
|
||||
OpsiHazard1Leveling:
|
||||
StrategySearch: True
|
||||
TargetZone:
|
||||
value: 0
|
||||
option: [0, 44, 22]
|
||||
|
||||
# ==================== Tools ====================
|
||||
|
||||
|
@ -57,7 +57,8 @@
|
||||
"OpsiObscure",
|
||||
"OpsiAbyssal",
|
||||
"OpsiStronghold",
|
||||
"OpsiMeowfficerFarming"
|
||||
"OpsiMeowfficerFarming",
|
||||
"OpsiHazard1Leveling"
|
||||
],
|
||||
"Tool": [
|
||||
"Daemon",
|
||||
|
@ -350,7 +350,7 @@ OpsiAbyssal:
|
||||
Scheduler:
|
||||
SuccessInterval: 60
|
||||
FailureInterval: 60
|
||||
ServerUpdate: 00:00
|
||||
ServerUpdate: 00:00, 12:00
|
||||
OpsiStronghold:
|
||||
Scheduler:
|
||||
SuccessInterval: 60
|
||||
@ -361,3 +361,10 @@ OpsiMeowfficerFarming:
|
||||
SuccessInterval: 30
|
||||
FailureInterval: 30
|
||||
ServerUpdate: 00:00
|
||||
OpsiHazard1Leveling:
|
||||
Scheduler:
|
||||
SuccessInterval: 30
|
||||
FailureInterval: 60
|
||||
ServerUpdate: 00:00
|
||||
OpsiFleet:
|
||||
Submarine: false
|
||||
|
@ -263,6 +263,10 @@ OpsiMeowfficerFarming:
|
||||
- Scheduler
|
||||
- OpsiMeowfficerFarming
|
||||
- OpsiFleet
|
||||
OpsiHazard1Leveling:
|
||||
- Scheduler
|
||||
- OpsiHazard1Leveling
|
||||
- OpsiFleet
|
||||
|
||||
# ==================== Tool ====================
|
||||
|
||||
|
@ -379,10 +379,14 @@ class GeneratedConfig:
|
||||
OpsiStronghold_ForceRun = False
|
||||
|
||||
# Group `OpsiMeowfficerFarming`
|
||||
OpsiMeowfficerFarming_ActionPointPreserve = 500
|
||||
OpsiMeowfficerFarming_ActionPointPreserve = 1000
|
||||
OpsiMeowfficerFarming_HazardLevel = 5 # 3, 4, 5, 6, 10
|
||||
OpsiMeowfficerFarming_TargetZone = 0
|
||||
|
||||
# Group `OpsiHazard1Leveling`
|
||||
OpsiHazard1Leveling_StrategySearch = True
|
||||
OpsiHazard1Leveling_TargetZone = 0 # 0, 44, 22
|
||||
|
||||
# Group `Daemon`
|
||||
Daemon_EnterMap = True
|
||||
|
||||
|
@ -24,6 +24,7 @@ class ManualConfig:
|
||||
> Event > Event2 > Raid > Main > Main2 > Main3
|
||||
> OpsiMeowfficerFarming
|
||||
> GemsFarming
|
||||
> OpsiHazard1Leveling
|
||||
"""
|
||||
|
||||
"""
|
||||
|
@ -218,6 +218,10 @@
|
||||
"name": "Meowfficer Farming",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"name": "CL1 Leveling",
|
||||
"help": ""
|
||||
},
|
||||
"Daemon": {
|
||||
"name": "Normal Semi-auto",
|
||||
"help": ""
|
||||
@ -2098,7 +2102,7 @@
|
||||
},
|
||||
"ActionPointPreserve": {
|
||||
"name": "Keep X Amount of AP",
|
||||
"help": "Stops task if total AP (including AP boxes in inventory) is below this number, 500 is recommended\nThis value will be auto reduced to 300 at 3 days before OpSi reset and to 0 at day before reset"
|
||||
"help": "Stops task if total AP (including AP boxes in inventory) is below this number, 1000 is recommended\nThis value will be auto reduced to 300 at 3 days before OpSi reset, or 500 if CL1 leveling enabled, and to 0 at day before reset"
|
||||
},
|
||||
"HazardLevel": {
|
||||
"name": "Target Zone Hazard Level",
|
||||
@ -2114,6 +2118,23 @@
|
||||
"help": "Supports either Zone ID or Name in CN/EN/JP/TW, i.e. \"51\", \"NA Ocean SE Sector E\"\nIf specified, Alas will loop on this same zone after each clear\nUse default value 0 or clear the field to remove the specification\nZone information can be acquired from <./module/os/map_data.py>"
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"_info": {
|
||||
"name": "CL1 leveling",
|
||||
"help": "OpsiHazard1Leveling._info.help"
|
||||
},
|
||||
"StrategySearch": {
|
||||
"name": "Strategic Search",
|
||||
"help": ""
|
||||
},
|
||||
"TargetZone": {
|
||||
"name": "Target Zone ID",
|
||||
"help": "Only attack target zone, which can be used to obtain world achievement stars or avoid the event that the map cannot be refreshed due to game bug",
|
||||
"0": "No Specification",
|
||||
"44": "44 | West Continental Shelf D",
|
||||
"22": "22 | NA Ocean SW Sector B"
|
||||
}
|
||||
},
|
||||
"Daemon": {
|
||||
"_info": {
|
||||
"name": "Semi-auto Clicking",
|
||||
|
@ -218,6 +218,10 @@
|
||||
"name": "Task.OpsiMeowfficerFarming.name",
|
||||
"help": "Task.OpsiMeowfficerFarming.help"
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"name": "Task.OpsiHazard1Leveling.name",
|
||||
"help": "Task.OpsiHazard1Leveling.help"
|
||||
},
|
||||
"Daemon": {
|
||||
"name": "Task.Daemon.name",
|
||||
"help": "Task.Daemon.help"
|
||||
@ -585,7 +589,6 @@
|
||||
"name": "Campaign.Event.name",
|
||||
"help": "Campaign.Event.help",
|
||||
"campaign_main": "campaign_main",
|
||||
"event_20201229_cn": "虚畳なりし限象(復刻)",
|
||||
"event_20211111_cn": "燈火のシニエ",
|
||||
"raid_20221027": "戦え!ロイヤルメイド隊3rd",
|
||||
"event_20210121_cn": "悲歎せし焔海の詩(復刻)",
|
||||
@ -2114,6 +2117,23 @@
|
||||
"help": "OpsiMeowfficerFarming.TargetZone.help"
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"_info": {
|
||||
"name": "OpsiHazard1Leveling._info.name",
|
||||
"help": "OpsiHazard1Leveling._info.help"
|
||||
},
|
||||
"StrategySearch": {
|
||||
"name": "OpsiHazard1Leveling.StrategySearch.name",
|
||||
"help": "OpsiHazard1Leveling.StrategySearch.help"
|
||||
},
|
||||
"TargetZone": {
|
||||
"name": "OpsiHazard1Leveling.TargetZone.name",
|
||||
"help": "OpsiHazard1Leveling.TargetZone.help",
|
||||
"0": "0",
|
||||
"44": "44",
|
||||
"22": "22"
|
||||
}
|
||||
},
|
||||
"Daemon": {
|
||||
"_info": {
|
||||
"name": "Daemon._info.name",
|
||||
|
@ -218,6 +218,10 @@
|
||||
"name": "短猫相接",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"name": "侵蚀1练级",
|
||||
"help": ""
|
||||
},
|
||||
"Daemon": {
|
||||
"name": "半自动点击",
|
||||
"help": ""
|
||||
@ -2098,7 +2102,7 @@
|
||||
},
|
||||
"ActionPointPreserve": {
|
||||
"name": "保留 X 点行动力",
|
||||
"help": "行动力低于 X 后停止,自动打开行动力箱子,X 包含箱子中的行动力,建议保留 500 点行动力\n这个值将在大世界重置前3天自动减少至300点,并在最后一天自动减少至0点"
|
||||
"help": "行动力低于 X 后停止,自动打开行动力箱子,X 包含箱子中的行动力,建议保留1000行动力给侵蚀1练级\n这个值将在大世界重置前3天自动减少至200点,如果启用侵蚀1练级则改为500点,并在最后一天自动减少至0点"
|
||||
},
|
||||
"HazardLevel": {
|
||||
"name": "侵蚀等级",
|
||||
@ -2114,6 +2118,23 @@
|
||||
"help": "仅出击指定的海域,可以用来获取大世界成就星星\n支持海域ID、国服/国际服/日服/台服海域名称,例如 \"51\", \"NA海域东南E\", \"NA Ocean SE Sector E\"\n填入默认值0,或者删除数值即可取消指定"
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"_info": {
|
||||
"name": "侵蚀1练级",
|
||||
"help": "警告:这个功能仅推荐用于练级\n根据海事局最新的结论,侵蚀1产出的行动力刚好跟消耗持平,可以用来无限获取经验\n尝试使用此功能获取额外行动力被视为自负盈亏的赌博行为\n\n这个功能会自动完成地图随机事件并跳过塞壬探测装置\n推荐携带2艘预装填的保姆船以获取最高的时均经验收益\n由于在商店购买行动力需要大量作战补给凭证,启用本功能后会自动启用短猫相接来补充"
|
||||
},
|
||||
"StrategySearch": {
|
||||
"name": "使用计划作战",
|
||||
"help": ""
|
||||
},
|
||||
"TargetZone": {
|
||||
"name": "指定海域",
|
||||
"help": "仅出击指定的海域,可以用来获取大世界成就星星或规避游戏BUG导致的无法刷新海域",
|
||||
"0": "不指定",
|
||||
"44": "44 | 西大陆架D",
|
||||
"22": "22 | NA海域西南B"
|
||||
}
|
||||
},
|
||||
"Daemon": {
|
||||
"_info": {
|
||||
"name": "半自动点击",
|
||||
|
@ -218,6 +218,10 @@
|
||||
"name": "短貓相接",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"name": "侵蝕1練級",
|
||||
"help": ""
|
||||
},
|
||||
"Daemon": {
|
||||
"name": "半自動點擊",
|
||||
"help": ""
|
||||
@ -2098,7 +2102,7 @@
|
||||
},
|
||||
"ActionPointPreserve": {
|
||||
"name": "保留 X 點行動力",
|
||||
"help": "行動力低於 X 後停止,自動打開行動力箱子,X 包含箱子中的行動力,建議保留 500 點行動力\n這個值將在大世界重置前3天自動減少至300點,並在最後一天自動減少至0點"
|
||||
"help": "行動力低於 X 後停止,自動打開行動力箱子,X 包含箱子中的行動力,建議保留 1000 點行動力给侵蝕1練級\n這個值將在大世界重置前3天自動減少至300點,如果啟用侵蝕1練級則改為500點,並在最後一天自動減少至0點"
|
||||
},
|
||||
"HazardLevel": {
|
||||
"name": "侵蝕等級",
|
||||
@ -2114,6 +2118,23 @@
|
||||
"help": "僅出擊指定的海域,可以用來獲取大世界成就星星\n自動更新的數值,填0可重置進度,重置後自動跳過已開荒的海域\n支持海域ID、國服/國際服/日服/台服海域名稱,例如 \"51\", \"NA海域東南E\", \"NA Ocean SE Sector E\"\n填入默認值0,或者刪除數值即可取消指定"
|
||||
}
|
||||
},
|
||||
"OpsiHazard1Leveling": {
|
||||
"_info": {
|
||||
"name": "侵蝕1練級",
|
||||
"help": "OpsiHazard1Leveling._info.help"
|
||||
},
|
||||
"StrategySearch": {
|
||||
"name": "使用計畫作戰",
|
||||
"help": ""
|
||||
},
|
||||
"TargetZone": {
|
||||
"name": "指定海域",
|
||||
"help": "僅出擊指定的海域,可以用來獲取大世界成就星星或規避遊戲BUG導致的無法重繪海域",
|
||||
"0": "不指定",
|
||||
"44": "44 | 西大陸棚D",
|
||||
"22": "22 | NA海域西南B"
|
||||
}
|
||||
},
|
||||
"Daemon": {
|
||||
"_info": {
|
||||
"name": "半自動點擊",
|
||||
@ -2149,7 +2170,7 @@
|
||||
},
|
||||
"AdbncScreenshot": {
|
||||
"name": "測試 ADB 截圖",
|
||||
"help": "Benchmark.AdbncScreenshot.help"
|
||||
"help": ""
|
||||
},
|
||||
"Uiautomator2Screenshot": {
|
||||
"name": "測試 uiautomator2 截圖",
|
||||
|
105
module/os/map.py
@ -1,17 +1,23 @@
|
||||
from sys import maxsize
|
||||
import inflection
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.combat.assets import PAUSE
|
||||
from module.config.utils import get_os_reset_remain
|
||||
from module.exception import CampaignEnd, RequestHumanTakeover
|
||||
from module.exception import GameTooManyClickError
|
||||
from module.exception import GameTooManyClickError, GameStuckError
|
||||
from module.exception import MapWalkError, ScriptError
|
||||
from module.exercise.assets import QUIT_CONFIRM, QUIT_RECONFIRM
|
||||
from module.logger import logger
|
||||
from module.map.map import Map
|
||||
from module.os.assets import FLEET_EMP_DEBUFF
|
||||
from module.os.fleet import OSFleet
|
||||
from module.os.globe_camera import GlobeCamera
|
||||
from module.os.globe_operation import RewardUncollectedError
|
||||
from module.os_handler.assets import AUTO_SEARCH_OS_MAP_OPTION_OFF, AUTO_SEARCH_OS_MAP_OPTION_ON
|
||||
from module.os_handler.assets import AUTO_SEARCH_OS_MAP_OPTION_OFF, \
|
||||
AUTO_SEARCH_OS_MAP_OPTION_ON, AUTO_SEARCH_REWARD
|
||||
from module.ui.assets import GOTO_MAIN
|
||||
from module.ui.page import page_main
|
||||
from module.ui.ui import page_os
|
||||
|
||||
|
||||
@ -72,6 +78,8 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
if self.zone.zone_id == 154:
|
||||
logger.info('In zone 154, skip running first auto search')
|
||||
self.handle_ash_beacon_attack()
|
||||
elif self.zone.zone_id in [22, 44]:
|
||||
pass
|
||||
else:
|
||||
self.run_auto_search(rescan=False)
|
||||
self.handle_after_auto_search()
|
||||
@ -114,7 +122,7 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
if self.zone == zone:
|
||||
if refresh:
|
||||
logger.info('Goto another zone to refresh current zone')
|
||||
return self.globe_goto(self.zone_nearest_azur_port(self.zone),
|
||||
self.globe_goto(self.zone_nearest_azur_port(self.zone),
|
||||
types=('SAFE', 'DANGEROUS'), refresh=False)
|
||||
else:
|
||||
logger.info('Already at target zone')
|
||||
@ -128,7 +136,7 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
# IN_GLOBE
|
||||
if not self.is_in_globe():
|
||||
logger.warning('Trying to move in globe, but not in os globe map')
|
||||
raise ScriptError('Trying to move in globe, but not in os globe map')
|
||||
raise GameStuckError
|
||||
# self.ensure_no_zone_pinned()
|
||||
self.globe_update()
|
||||
self.globe_focus_to(zone)
|
||||
@ -349,32 +357,33 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
logger.warning('Failed to solve EMP debuff after 5 trial, assume solved')
|
||||
return True
|
||||
|
||||
def action_point_limit_override(self):
|
||||
def get_action_point_limit(self):
|
||||
"""
|
||||
Override user config at the end of every month.
|
||||
To consume all action points without manual configuration.
|
||||
|
||||
Returns:
|
||||
bool: If overrode
|
||||
int: ActionPointPreserve
|
||||
"""
|
||||
remain = get_os_reset_remain()
|
||||
if remain <= 0:
|
||||
logger.info('Just less than 1 day to OpSi reset, '
|
||||
'set OpsiMeowfficerFarming.ActionPointPreserve to 0 temporarily')
|
||||
self.config.override(OpsiMeowfficerFarming_ActionPointPreserve=0)
|
||||
return True
|
||||
'set ActionPointPreserve to 0 temporarily')
|
||||
return 0
|
||||
elif self.config.cross_get(
|
||||
keys='OpsiHazard1Leveling.Scheduler.Enable',
|
||||
default=False
|
||||
) and remain <= 2:
|
||||
logger.info('Just less than 3 days to OpSi reset, '
|
||||
'set ActionPointPreserve to 500 temporarily for hazard 1 leveling')
|
||||
return 500
|
||||
elif remain <= 2:
|
||||
logger.info('Just less than 3 days to OpSi reset, '
|
||||
'set OpsiMeowfficerFarming.ActionPointPreserve < 300 temporarily')
|
||||
self.config.override(
|
||||
OpsiMeowfficerFarming_ActionPointPreserve=min(
|
||||
self.config.OpsiMeowfficerFarming_ActionPointPreserve,
|
||||
300)
|
||||
)
|
||||
return True
|
||||
'set ActionPointPreserve to 300 temporarily')
|
||||
return 300
|
||||
else:
|
||||
logger.info('Not close to OpSi reset')
|
||||
return False
|
||||
return maxsize
|
||||
|
||||
def handle_after_auto_search(self):
|
||||
logger.hr('After auto search', level=2)
|
||||
@ -390,7 +399,7 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
|
||||
_auto_search_battle_count = 0
|
||||
|
||||
def os_auto_search_daemon(self, drop=None, skip_first_screenshot=True):
|
||||
def os_auto_search_daemon(self, drop=None, strategy=False, skip_first_screenshot=True):
|
||||
"""
|
||||
Raises:
|
||||
CampaignEnd: If auto search ended
|
||||
@ -404,6 +413,7 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
logger.hr('OS auto search', level=2)
|
||||
self._auto_search_battle_count = 0
|
||||
unlock_checked = False
|
||||
strategy_checked = False
|
||||
unlock_check_timer = Timer(5, count=10).start()
|
||||
self.ash_popup_canceled = False
|
||||
|
||||
@ -437,8 +447,14 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
unlock_checked = True
|
||||
elif self.appear(AUTO_SEARCH_OS_MAP_OPTION_ON, offset=(5, 120)):
|
||||
unlock_checked = True
|
||||
if self.handle_os_auto_search_map_option(drop=drop, enable=success):
|
||||
|
||||
if self.handle_os_auto_search_map_option(
|
||||
drop=drop,
|
||||
enable=success,
|
||||
strategy=strategy and not strategy_checked
|
||||
):
|
||||
unlock_checked = True
|
||||
strategy_checked = True
|
||||
continue
|
||||
if self.handle_retirement():
|
||||
# Retire will interrupt auto search, need a retry
|
||||
@ -447,6 +463,8 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
if self.combat_appear():
|
||||
self._auto_search_battle_count += 1
|
||||
logger.attr('battle_count', self._auto_search_battle_count)
|
||||
if strategy and self.config.task_switched():
|
||||
self.interrupt_auto_search()
|
||||
result = self.auto_search_combat(drop=drop)
|
||||
if not result:
|
||||
success = False
|
||||
@ -456,11 +474,37 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
# Auto search can not handle siren searching device.
|
||||
continue
|
||||
|
||||
def os_auto_search_run(self, drop=None):
|
||||
def interrupt_auto_search(self):
|
||||
logger.info('Interrupting auto search')
|
||||
while 1:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(AUTO_SEARCH_REWARD, offset=(50, 50), interval=3):
|
||||
self.os_auto_search_quit()
|
||||
continue
|
||||
if self.appear_then_click(PAUSE, interval=0.5):
|
||||
continue
|
||||
if self.appear_then_click(QUIT_CONFIRM, offset=(20, 20), interval=5):
|
||||
continue
|
||||
if self.appear_then_click(QUIT_RECONFIRM, offset=True, interval=5):
|
||||
continue
|
||||
|
||||
if self.appear(AUTO_SEARCH_OS_MAP_OPTION_OFF, offset=(5, 120), interval=3) \
|
||||
and AUTO_SEARCH_OS_MAP_OPTION_OFF.match_appear_on(self.device.image):
|
||||
self.device.click(GOTO_MAIN)
|
||||
continue
|
||||
if self.ui_additional():
|
||||
continue
|
||||
# End
|
||||
if self.ui_page_appear(page_main):
|
||||
logger.info('Auto search interrupted')
|
||||
self.config.task_stop()
|
||||
|
||||
def os_auto_search_run(self, drop=None, strategy=False):
|
||||
for _ in range(5):
|
||||
backup = self.config.temporary(Campaign_UseAutoSearch=True)
|
||||
try:
|
||||
self.os_auto_search_daemon(drop=drop)
|
||||
self.os_auto_search_daemon(drop=drop, strategy=strategy)
|
||||
except CampaignEnd:
|
||||
logger.info('OS auto search finished')
|
||||
finally:
|
||||
@ -470,6 +514,7 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
# Break if zone cleared
|
||||
if self.config.OpsiAshBeacon_AshAttack:
|
||||
if self.handle_ash_beacon_attack() or self.ash_popup_canceled:
|
||||
strategy = False
|
||||
continue
|
||||
else:
|
||||
break
|
||||
@ -481,7 +526,7 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
else:
|
||||
break
|
||||
|
||||
def clear_question(self, drop):
|
||||
def clear_question(self, drop=None):
|
||||
"""
|
||||
Clear nearly (and 3 grids from above) question marks on radar.
|
||||
Try 3 times at max to avoid loop tries on 2 adjacent fleet mechanism.
|
||||
@ -582,6 +627,19 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
_solved_map_event = set()
|
||||
_solved_fleet_mechanism = 0
|
||||
|
||||
def run_strategy_search(self):
|
||||
self.handle_ash_beacon_attack()
|
||||
|
||||
logger.info('Run strategy search')
|
||||
self.os_auto_search_run(strategy=True)
|
||||
|
||||
self.hp_reset()
|
||||
self.hp_get()
|
||||
self._solved_map_event = set()
|
||||
self._solved_fleet_mechanism = False
|
||||
self.clear_question()
|
||||
self.map_rescan()
|
||||
|
||||
def map_rescan_current(self, drop=None):
|
||||
"""
|
||||
|
||||
@ -626,7 +684,8 @@ class OSMap(OSFleet, Map, GlobeCamera):
|
||||
grid = grids[0]
|
||||
logger.info(f'Found scanning device on {grid}')
|
||||
self.device.click(grid)
|
||||
result = self.wait_until_walk_stable(drop=drop, walk_out_of_step=False, confirm_timer=Timer(1.5, count=4))
|
||||
result = self.wait_until_walk_stable(drop=drop, walk_out_of_step=False,
|
||||
confirm_timer=Timer(1.5, count=4))
|
||||
self.os_auto_search_run(drop=drop)
|
||||
if 'event' in result:
|
||||
self._solved_map_event.add('is_scanning_device')
|
||||
|
@ -1,5 +1,6 @@
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.config.utils import (get_os_next_reset,
|
||||
get_os_reset_remain,
|
||||
DEFAULT_TIME)
|
||||
@ -9,6 +10,7 @@ from module.map.map_grids import SelectedGrids
|
||||
from module.os.fleet import BossFleet
|
||||
from module.os.globe_operation import OSExploreError
|
||||
from module.os.map import OSMap
|
||||
from module.os_handler.shop import OCR_SHOP_YELLOW_COINS
|
||||
|
||||
|
||||
class OperationSiren(OSMap):
|
||||
@ -130,9 +132,12 @@ class OperationSiren(OSMap):
|
||||
Recommend 3 or 5 for higher meowfficer searching point per action points ratio.
|
||||
"""
|
||||
logger.hr(f'OS meowfficer farming, hazard_level={self.config.OpsiMeowfficerFarming_HazardLevel}', level=1)
|
||||
self.action_point_limit_override()
|
||||
preserve = min(self.get_action_point_limit(), self.config.OpsiMeowfficerFarming_ActionPointPreserve)
|
||||
if preserve == 0:
|
||||
self.config.override(OpsiFleet_Submarine=False)
|
||||
|
||||
while 1:
|
||||
self.config.OS_ACTION_POINT_PRESERVE = self.config.OpsiMeowfficerFarming_ActionPointPreserve
|
||||
self.config.OS_ACTION_POINT_PRESERVE = preserve
|
||||
if self.config.OpsiAshBeacon_AshAttack \
|
||||
and not self._ash_fully_collected \
|
||||
and self.config.OpsiAshBeacon_EnsureFullyCollected:
|
||||
@ -149,6 +154,7 @@ class OperationSiren(OSMap):
|
||||
raise RequestHumanTakeover('wrong input, task stopped')
|
||||
else:
|
||||
logger.hr(f'OS meowfficer farming, zone_id={zone.zone_id}', level=1)
|
||||
self.set_action_point(zone, 'SAFE')
|
||||
self.globe_goto(zone)
|
||||
self.fleet_set(self.config.OpsiFleet_Fleet)
|
||||
self.os_order_execute(
|
||||
@ -165,6 +171,7 @@ class OperationSiren(OSMap):
|
||||
.sort_by_clock_degree(center=(1252, 1012), start=self.zone.location)
|
||||
|
||||
logger.hr(f'OS meowfficer farming, zone_id={zones[0].zone_id}', level=1)
|
||||
self.set_action_point(zones[0], 'SAFE')
|
||||
self.globe_goto(zones[0])
|
||||
self.fleet_set(self.config.OpsiFleet_Fleet)
|
||||
self.os_order_execute(
|
||||
@ -174,6 +181,68 @@ class OperationSiren(OSMap):
|
||||
self.handle_after_auto_search()
|
||||
self.config.check_task_switch()
|
||||
|
||||
def os_hazard1_leveling(self):
|
||||
logger.hr('OS hazard 1 leveling', level=1)
|
||||
while 1:
|
||||
# Limited action point preserve of hazard 1 to 200
|
||||
self.config.OS_ACTION_POINT_PRESERVE = 200
|
||||
if self.config.OpsiAshBeacon_AshAttack \
|
||||
and not self._ash_fully_collected \
|
||||
and self.config.OpsiAshBeacon_EnsureFullyCollected:
|
||||
logger.info('Ash beacon not fully collected, ignore action point limit temporarily')
|
||||
self.config.OS_ACTION_POINT_PRESERVE = 0
|
||||
logger.attr('OS_ACTION_POINT_PRESERVE', self.config.OS_ACTION_POINT_PRESERVE)
|
||||
|
||||
timeout = Timer(2).start()
|
||||
skip_first_screenshot = True
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
yellow_coins = OCR_SHOP_YELLOW_COINS.ocr(self.device.image)
|
||||
if yellow_coins < 100 and not timeout.reached():
|
||||
logger.info('Yellow coins less than 100, assuming it is an ocr error')
|
||||
continue
|
||||
elif yellow_coins < 100000:
|
||||
logger.info('Reach the limit of yellow coins, preserve=100000')
|
||||
self.config.task_delay(server_update=True)
|
||||
self.config.task_stop()
|
||||
else:
|
||||
break
|
||||
|
||||
self.get_current_zone()
|
||||
if self.config.OpsiHazard1Leveling_StrategySearch:
|
||||
# Preset action point to 100
|
||||
self.set_action_point(cost=100)
|
||||
if self.config.OpsiHazard1Leveling_TargetZone != 0:
|
||||
zone = self.config.OpsiHazard1Leveling_TargetZone
|
||||
else:
|
||||
zone = 44
|
||||
|
||||
logger.hr(f'OS hazard 1 leveling, zone_id={zone}', level=1)
|
||||
if self.zone.zone_id != zone or not self.is_zone_name_hidden:
|
||||
self.globe_goto(self.name_to_zone(zone), types='SAFE', refresh=True)
|
||||
self.fleet_set(self.config.OpsiFleet_Fleet)
|
||||
self.run_strategy_search()
|
||||
else:
|
||||
if self.config.OpsiHazard1Leveling_TargetZone != 0:
|
||||
zone = self.config.OpsiHazard1Leveling_TargetZone
|
||||
logger.hr(f'OS hazard 1 leveling, zone_id={zone}', level=1)
|
||||
self.globe_goto(self.name_to_zone(zone), types='SAFE', refresh=True)
|
||||
else:
|
||||
zones = self.zone_select(hazard_level=1) \
|
||||
.delete(SelectedGrids([self.zone])) \
|
||||
.delete(SelectedGrids(self.zones.select(is_port=True)))
|
||||
logger.hr(f'OS hazard 1 leveling, zone_id={zones[0].zone_id}', level=1)
|
||||
self.globe_goto(zones[0])
|
||||
|
||||
self.fleet_set(self.config.OpsiFleet_Fleet)
|
||||
self.run_auto_search()
|
||||
self.handle_after_auto_search()
|
||||
self.config.check_task_switch()
|
||||
|
||||
def _os_explore_task_delay(self):
|
||||
"""
|
||||
Delay other OpSi tasks during os_explore
|
||||
@ -311,6 +380,15 @@ class OperationSiren(OSMap):
|
||||
else:
|
||||
break
|
||||
|
||||
def delay_abyssal(self):
|
||||
# No obscure coordinates, delay next run to tomorrow.
|
||||
if get_os_reset_remain() > 0:
|
||||
self.config.task_delay(server_update=True)
|
||||
else:
|
||||
logger.info('Just less than 1 day to OpSi reset, delay 2.5 hours')
|
||||
self.config.task_delay(minute=150, server_update=True)
|
||||
self.config.task_stop()
|
||||
|
||||
def clear_abyssal(self):
|
||||
"""
|
||||
Get one abyssal logger in storage,
|
||||
@ -325,13 +403,7 @@ class OperationSiren(OSMap):
|
||||
logger.hr('OS clear abyssal', level=1)
|
||||
result = self.storage_get_next_item('ABYSSAL', use_logger=self.config.OpsiGeneral_UseLogger)
|
||||
if not result:
|
||||
# No obscure coordinates, delay next run to tomorrow.
|
||||
if get_os_reset_remain() > 0:
|
||||
self.config.task_delay(server_update=True)
|
||||
else:
|
||||
logger.info('Just less than 1 day to OpSi reset, delay 2.5 hours')
|
||||
self.config.task_delay(minute=150, server_update=True)
|
||||
self.config.task_stop()
|
||||
self.delay_abyssal()
|
||||
|
||||
self.config.override(
|
||||
OpsiGeneral_DoRandomMapEvent=False,
|
||||
@ -344,6 +416,7 @@ class OperationSiren(OSMap):
|
||||
raise RequestHumanTakeover
|
||||
|
||||
self.fleet_repair(revert=False)
|
||||
self.delay_abyssal()
|
||||
|
||||
def os_abyssal(self):
|
||||
while 1:
|
||||
|
@ -1,5 +1,6 @@
|
||||
import module.config.server as server
|
||||
from module.base.button import ButtonGrid
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import *
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Digit, DigitCounter
|
||||
@ -9,6 +10,8 @@ from module.ui.assets import OS_CHECK
|
||||
from module.ui.ui import UI
|
||||
|
||||
OCR_ACTION_POINT_REMAIN = Digit(ACTION_POINT_REMAIN, letter=(255, 219, 66), name='OCR_ACTION_POINT_REMAIN')
|
||||
OCR_ACTION_POINT_REMAIN_OS = Digit(ACTION_POINT_REMAIN_OS, letter=(239, 239, 239),
|
||||
threshold=160, name='OCR_SHOP_YELLOW_COINS_OS')
|
||||
if server.server != 'jp':
|
||||
# Letters in ACTION_POINT_BUY_REMAIN are not the numeric fonts usually used in azur lane.
|
||||
OCR_ACTION_POINT_BUY_REMAIN = DigitCounter(
|
||||
@ -51,6 +54,12 @@ ACTION_POINTS_BUY = {
|
||||
4: 1000,
|
||||
5: 1000,
|
||||
}
|
||||
ACTION_POINT_BOX = {
|
||||
0: 0,
|
||||
1: 20,
|
||||
2: 50,
|
||||
3: 100,
|
||||
}
|
||||
|
||||
|
||||
class ActionPointLimit(Exception):
|
||||
@ -95,7 +104,7 @@ class ActionPointHandler(UI):
|
||||
current = OCR_ACTION_POINT_REMAIN.ocr(self.device.image)
|
||||
total = current
|
||||
if self.config.OS_ACTION_POINT_BOX_USE:
|
||||
total += np.sum(np.array(box) * (0, 20, 50, 100))
|
||||
total += np.sum(np.array(box) * tuple(ACTION_POINT_BOX.values()))
|
||||
oil = box[0]
|
||||
|
||||
logger.info(f'Action points: {current}({total}), oil: {oil}')
|
||||
@ -103,6 +112,23 @@ class ActionPointHandler(UI):
|
||||
self._action_point_box = box
|
||||
self._action_point_total = total
|
||||
|
||||
def action_point_safe_get(self, skip_first_screenshot=True):
|
||||
timeout = Timer(1, count=2).start()
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if timeout.reached():
|
||||
logger.warning('Get action points timeout')
|
||||
break
|
||||
|
||||
self.action_point_update()
|
||||
|
||||
if sum(self._action_point_box[1:]) > 0 and self._action_point_box[0] > 0:
|
||||
break
|
||||
|
||||
@staticmethod
|
||||
def action_point_get_cost(zone, pinned):
|
||||
"""
|
||||
@ -208,11 +234,12 @@ class ActionPointHandler(UI):
|
||||
"""
|
||||
self.ui_click(ACTION_POINT_CANCEL, check_button=OS_CHECK, skip_first_screenshot=skip_first_screenshot)
|
||||
|
||||
def handle_action_point(self, zone, pinned):
|
||||
def handle_action_point(self, zone, pinned, cost=None):
|
||||
"""
|
||||
Args:
|
||||
zone (Zone): Zone to enter.
|
||||
pinned (str): Zone type. Available types: DANGEROUS, SAFE, OBSCURE, ABYSSAL, STRONGHOLD.
|
||||
cost (int): Custom action point cost value.
|
||||
|
||||
Returns:
|
||||
bool: If handled.
|
||||
@ -227,11 +254,15 @@ class ActionPointHandler(UI):
|
||||
return False
|
||||
|
||||
# AP boxes have an animation to show
|
||||
self.device.sleep(0.3)
|
||||
self.device.screenshot()
|
||||
self.action_point_update()
|
||||
self.action_point_safe_get()
|
||||
if cost is None:
|
||||
cost = self.action_point_get_cost(zone, pinned)
|
||||
buy_checked = False
|
||||
if self._action_point_total <= self.config.OS_ACTION_POINT_PRESERVE:
|
||||
logger.info(f'Reach the limit of action points, preserve={self.config.OS_ACTION_POINT_PRESERVE}')
|
||||
self.action_point_quit()
|
||||
raise ActionPointLimit
|
||||
|
||||
for _ in range(12):
|
||||
# Having enough action points
|
||||
if self._action_point_current >= cost:
|
||||
@ -246,8 +277,16 @@ class ActionPointHandler(UI):
|
||||
else:
|
||||
buy_checked = True
|
||||
|
||||
# Sort action point boxes
|
||||
box = []
|
||||
for index in [1, 2, 3]:
|
||||
if self._action_point_box[index] > 0:
|
||||
if self._action_point_current + ACTION_POINT_BOX[index] >= 200:
|
||||
box.append(index)
|
||||
else:
|
||||
box.insert(0, index)
|
||||
|
||||
# Use action point boxes
|
||||
box = [index for index in [3, 2, 1] if self._action_point_box[index] > 0]
|
||||
if len(box):
|
||||
if self._action_point_total > self.config.OS_ACTION_POINT_PRESERVE:
|
||||
self.action_point_set_button(box[0])
|
||||
@ -264,3 +303,22 @@ class ActionPointHandler(UI):
|
||||
|
||||
logger.warning('Failed to get action points after 12 trial')
|
||||
return False
|
||||
|
||||
def set_action_point(self, zone=None, pinned=None, cost=None):
|
||||
"""
|
||||
Args:
|
||||
zone (Zone): Zone to enter.
|
||||
pinned (str): Zone type. Available types: DANGEROUS, SAFE, OBSCURE, ABYSSAL, STRONGHOLD.
|
||||
cost (int): Custom action point cost value.
|
||||
|
||||
Returns:
|
||||
bool: If handled.
|
||||
"""
|
||||
self.ui_click(ACTION_POINT_REMAIN_OS, ACTION_POINT_USE, OS_CHECK)
|
||||
if not self.handle_action_point(zone, pinned, cost):
|
||||
return False
|
||||
|
||||
while 1:
|
||||
if self.appear(IN_MAP, offset=(200, 5)):
|
||||
return True
|
||||
self.device.screenshot()
|
||||
|
@ -7,6 +7,7 @@ from module.base.template import Template
|
||||
ACTION_POINT_BUY_REMAIN = Button(area={'cn': (803, 458, 833, 482), 'en': (907, 458, 941, 483), 'jp': (891, 464, 927, 484), 'tw': (803, 458, 833, 482)}, color={'cn': (108, 138, 125), 'en': (106, 145, 116), 'jp': (135, 142, 153), 'tw': (108, 138, 125)}, button={'cn': (803, 458, 833, 482), 'en': (907, 458, 941, 483), 'jp': (891, 464, 927, 484), 'tw': (803, 458, 833, 482)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_BUY_REMAIN.png', 'en': './assets/en/os_handler/ACTION_POINT_BUY_REMAIN.png', 'jp': './assets/jp/os_handler/ACTION_POINT_BUY_REMAIN.png', 'tw': './assets/tw/os_handler/ACTION_POINT_BUY_REMAIN.png'})
|
||||
ACTION_POINT_CANCEL = Button(area={'cn': (370, 528, 542, 585), 'en': (375, 531, 537, 584), 'jp': (369, 527, 544, 587), 'tw': (371, 528, 541, 586)}, color={'cn': (167, 168, 171), 'en': (170, 172, 175), 'jp': (161, 163, 165), 'tw': (168, 169, 172)}, button={'cn': (370, 528, 542, 585), 'en': (375, 531, 537, 584), 'jp': (369, 527, 544, 587), 'tw': (371, 528, 541, 586)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_CANCEL.png', 'en': './assets/en/os_handler/ACTION_POINT_CANCEL.png', 'jp': './assets/jp/os_handler/ACTION_POINT_CANCEL.png', 'tw': './assets/tw/os_handler/ACTION_POINT_CANCEL.png'})
|
||||
ACTION_POINT_REMAIN = Button(area={'cn': (892, 220, 952, 241), 'en': (892, 220, 952, 241), 'jp': (908, 220, 979, 240), 'tw': (892, 220, 952, 241)}, color={'cn': (124, 127, 113), 'en': (124, 127, 113), 'jp': (119, 121, 113), 'tw': (124, 127, 113)}, button={'cn': (892, 220, 952, 241), 'en': (892, 220, 952, 241), 'jp': (908, 220, 979, 240), 'tw': (892, 220, 952, 241)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_REMAIN.png', 'en': './assets/en/os_handler/ACTION_POINT_REMAIN.png', 'jp': './assets/jp/os_handler/ACTION_POINT_REMAIN.png', 'tw': './assets/tw/os_handler/ACTION_POINT_REMAIN.png'})
|
||||
ACTION_POINT_REMAIN_OS = Button(area={'cn': (878, 28, 928, 46), 'en': (878, 28, 928, 46), 'jp': (878, 28, 928, 46), 'tw': (878, 28, 928, 46)}, color={'cn': (78, 89, 100), 'en': (78, 89, 100), 'jp': (78, 89, 100), 'tw': (78, 89, 100)}, button={'cn': (878, 28, 928, 46), 'en': (878, 28, 928, 46), 'jp': (878, 28, 928, 46), 'tw': (878, 28, 928, 46)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_REMAIN_OS.png', 'en': './assets/cn/os_handler/ACTION_POINT_REMAIN_OS.png', 'jp': './assets/cn/os_handler/ACTION_POINT_REMAIN_OS.png', 'tw': './assets/cn/os_handler/ACTION_POINT_REMAIN_OS.png'})
|
||||
ACTION_POINT_USE = Button(area={'cn': (738, 528, 910, 585), 'en': (742, 531, 909, 584), 'jp': (737, 528, 911, 586), 'tw': (739, 528, 909, 585)}, color={'cn': (93, 142, 203), 'en': (107, 152, 208), 'jp': (92, 141, 203), 'tw': (95, 144, 205)}, button={'cn': (738, 528, 910, 585), 'en': (742, 531, 909, 584), 'jp': (737, 528, 911, 586), 'tw': (739, 528, 909, 585)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_USE.png', 'en': './assets/en/os_handler/ACTION_POINT_USE.png', 'jp': './assets/jp/os_handler/ACTION_POINT_USE.png', 'tw': './assets/tw/os_handler/ACTION_POINT_USE.png'})
|
||||
ASH_POPUP_CHECK = Button(area={'cn': (665, 318, 759, 340), 'en': (372, 324, 601, 342), 'jp': (438, 311, 534, 346), 'tw': (665, 298, 759, 320)}, color={'cn': (154, 163, 172), 'en': (174, 179, 184), 'jp': (146, 154, 161), 'tw': (157, 166, 176)}, button={'cn': (665, 318, 759, 340), 'en': (372, 324, 601, 342), 'jp': (438, 311, 534, 346), 'tw': (665, 298, 759, 320)}, file={'cn': './assets/cn/os_handler/ASH_POPUP_CHECK.png', 'en': './assets/en/os_handler/ASH_POPUP_CHECK.png', 'jp': './assets/jp/os_handler/ASH_POPUP_CHECK.png', 'tw': './assets/tw/os_handler/ASH_POPUP_CHECK.png'})
|
||||
AUTO_SEARCH_OS_MAP_OPTION_OFF = Button(area={'cn': (1205, 549, 1275, 566), 'en': (1201, 524, 1274, 534), 'jp': (1204, 572, 1276, 593), 'tw': (1206, 573, 1275, 591)}, color={'cn': (196, 169, 169), 'en': (167, 140, 142), 'jp': (180, 154, 157), 'tw': (167, 143, 147)}, button={'cn': (1205, 549, 1275, 566), 'en': (1201, 524, 1274, 534), 'jp': (1204, 572, 1276, 593), 'tw': (1206, 573, 1275, 591)}, file={'cn': './assets/cn/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png', 'en': './assets/en/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png', 'jp': './assets/jp/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png', 'tw': './assets/tw/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png'})
|
||||
@ -57,6 +58,16 @@ STORAGE_COORDINATE_CHECKOUT = Button(area={'cn': (554, 493, 726, 550), 'en': (56
|
||||
STORAGE_ENTER = Button(area={'cn': (770, 636, 880, 699), 'en': (761, 640, 876, 695), 'jp': (757, 636, 880, 699), 'tw': (618, 638, 725, 698)}, color={'cn': (240, 199, 121), 'en': (238, 191, 115), 'jp': (237, 187, 100), 'tw': (240, 197, 125)}, button={'cn': (770, 636, 880, 699), 'en': (761, 640, 876, 695), 'jp': (757, 636, 880, 699), 'tw': (618, 638, 725, 698)}, file={'cn': './assets/cn/os_handler/STORAGE_ENTER.png', 'en': './assets/en/os_handler/STORAGE_ENTER.png', 'jp': './assets/jp/os_handler/STORAGE_ENTER.png', 'tw': './assets/tw/os_handler/STORAGE_ENTER.png'})
|
||||
STORAGE_USE = Button(area={'cn': (709, 506, 769, 536), 'en': (729, 509, 786, 533), 'jp': (764, 506, 856, 536), 'tw': (709, 506, 769, 536)}, color={'cn': (161, 186, 220), 'en': (164, 189, 222), 'jp': (142, 178, 224), 'tw': (161, 186, 220)}, button={'cn': (687, 493, 860, 550), 'en': (693, 495, 858, 549), 'jp': (686, 492, 861, 552), 'tw': (687, 493, 860, 550)}, file={'cn': './assets/cn/os_handler/STORAGE_USE.png', 'en': './assets/en/os_handler/STORAGE_USE.png', 'jp': './assets/jp/os_handler/STORAGE_USE.png', 'tw': './assets/tw/os_handler/STORAGE_USE.png'})
|
||||
STORATE_SCROLL = Button(area={'cn': (1256, 102, 1264, 589), 'en': (1256, 102, 1264, 589), 'jp': (1256, 102, 1264, 589), 'tw': (1256, 102, 1264, 589)}, color={'cn': (119, 109, 60), 'en': (119, 109, 60), 'jp': (119, 109, 60), 'tw': (119, 109, 60)}, button={'cn': (1256, 102, 1264, 589), 'en': (1256, 102, 1264, 589), 'jp': (1256, 102, 1264, 589), 'tw': (1256, 102, 1264, 589)}, file={'cn': './assets/cn/os_handler/STORATE_SCROLL.png', 'en': './assets/en/os_handler/STORATE_SCROLL.png', 'jp': './assets/jp/os_handler/STORATE_SCROLL.png', 'tw': './assets/tw/os_handler/STORATE_SCROLL.png'})
|
||||
STRATEGY_SEARCH_MAP_OPTION_OFF = Button(area={'cn': (1178, 576, 1278, 617), 'en': (1178, 576, 1278, 617), 'jp': (1178, 576, 1278, 617), 'tw': (1178, 576, 1278, 617)}, color={'cn': (96, 102, 122), 'en': (96, 102, 122), 'jp': (96, 102, 122), 'tw': (96, 102, 122)}, button={'cn': (1178, 576, 1278, 617), 'en': (1178, 576, 1278, 617), 'jp': (1178, 576, 1278, 617), 'tw': (1178, 576, 1278, 617)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_MAP_OPTION_OFF.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_MAP_OPTION_OFF.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_MAP_OPTION_OFF.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_MAP_OPTION_OFF.png'})
|
||||
STRATEGY_SEARCH_POPUP_CHECK = Button(area={'cn': (370, 166, 566, 198), 'en': (370, 166, 566, 198), 'jp': (370, 166, 566, 198), 'tw': (370, 166, 566, 198)}, color={'cn': (150, 170, 209), 'en': (150, 170, 209), 'jp': (150, 170, 209), 'tw': (150, 170, 209)}, button={'cn': (370, 166, 566, 198), 'en': (370, 166, 566, 198), 'jp': (370, 166, 566, 198), 'tw': (370, 166, 566, 198)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_POPUP_CHECK.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_POPUP_CHECK.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_POPUP_CHECK.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_POPUP_CHECK.png'})
|
||||
STRATEGY_SEARCH_SAFE_OPTION_OFF = Button(area={'cn': (457, 229, 550, 257), 'en': (457, 229, 550, 257), 'jp': (457, 229, 550, 257), 'tw': (457, 229, 550, 257)}, color={'cn': (111, 141, 195), 'en': (111, 141, 195), 'jp': (111, 141, 195), 'tw': (111, 141, 195)}, button={'cn': (640, 217, 913, 270), 'en': (640, 217, 913, 270), 'jp': (640, 217, 913, 270), 'tw': (640, 217, 913, 270)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_OFF.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_OFF.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_OFF.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_OFF.png'})
|
||||
STRATEGY_SEARCH_SAFE_OPTION_ON = Button(area={'cn': (731, 229, 823, 258), 'en': (731, 229, 823, 258), 'jp': (731, 229, 823, 258), 'tw': (731, 229, 823, 258)}, color={'cn': (105, 136, 192), 'en': (105, 136, 192), 'jp': (105, 136, 192), 'tw': (105, 136, 192)}, button={'cn': (731, 229, 823, 258), 'en': (731, 229, 823, 258), 'jp': (731, 229, 823, 258), 'tw': (731, 229, 823, 258)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_ON.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_ON.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_ON.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_SAFE_OPTION_ON.png'})
|
||||
STRATEGY_SEARCH_SCROLL_AREA = Button(area={'cn': (902, 277, 910, 470), 'en': (902, 277, 910, 470), 'jp': (902, 277, 910, 470), 'tw': (902, 277, 910, 470)}, color={'cn': (151, 145, 102), 'en': (151, 145, 102), 'jp': (151, 145, 102), 'tw': (151, 145, 102)}, button={'cn': (902, 277, 910, 470), 'en': (902, 277, 910, 470), 'jp': (902, 277, 910, 470), 'tw': (902, 277, 910, 470)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_SCROLL_AREA.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_SCROLL_AREA.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_SCROLL_AREA.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_SCROLL_AREA.png'})
|
||||
STRATEGY_SEARCH_WAIT_2_CHECK = Button(area={'cn': (474, 404, 556, 422), 'en': (474, 404, 556, 422), 'jp': (474, 404, 556, 422), 'tw': (474, 404, 556, 422)}, color={'cn': (149, 156, 168), 'en': (149, 156, 168), 'jp': (149, 156, 168), 'tw': (149, 156, 168)}, button={'cn': (474, 404, 556, 422), 'en': (474, 404, 556, 422), 'jp': (474, 404, 556, 422), 'tw': (474, 404, 556, 422)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_2_CHECK.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_2_CHECK.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_2_CHECK.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_2_CHECK.png'})
|
||||
STRATEGY_SEARCH_WAIT_OFF = Button(area={'cn': (519, 443, 535, 458), 'en': (519, 443, 535, 458), 'jp': (519, 443, 535, 458), 'tw': (519, 443, 535, 458)}, color={'cn': (89, 128, 66), 'en': (89, 128, 66), 'jp': (89, 128, 66), 'tw': (89, 128, 66)}, button={'cn': (519, 443, 535, 458), 'en': (519, 443, 535, 458), 'jp': (519, 443, 535, 458), 'tw': (519, 443, 535, 458)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_OFF.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_OFF.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_OFF.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_OFF.png'})
|
||||
STRATEGY_SEARCH_WAIT_ON = Button(area={'cn': (446, 443, 462, 458), 'en': (446, 443, 462, 458), 'jp': (446, 443, 462, 458), 'tw': (446, 443, 462, 458)}, color={'cn': (89, 128, 67), 'en': (89, 128, 67), 'jp': (89, 128, 67), 'tw': (89, 128, 67)}, button={'cn': (446, 443, 462, 458), 'en': (446, 443, 462, 458), 'jp': (446, 443, 462, 458), 'tw': (446, 443, 462, 458)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_ON.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_ON.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_ON.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_WAIT_ON.png'})
|
||||
STRATEGY_SEARCH_ZONE_MODE_OFF = Button(area={'cn': (750, 335, 766, 350), 'en': (750, 335, 766, 350), 'jp': (750, 335, 766, 350), 'tw': (750, 335, 766, 350)}, color={'cn': (89, 128, 67), 'en': (89, 128, 67), 'jp': (89, 128, 67), 'tw': (89, 128, 67)}, button={'cn': (750, 335, 766, 350), 'en': (750, 335, 766, 350), 'jp': (750, 335, 766, 350), 'tw': (750, 335, 766, 350)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_OFF.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_OFF.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_OFF.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_OFF.png'})
|
||||
STRATEGY_SEARCH_ZONE_MODE_ON = Button(area={'cn': (551, 335, 567, 350), 'en': (551, 335, 567, 350), 'jp': (551, 335, 567, 350), 'tw': (551, 335, 567, 350)}, color={'cn': (89, 128, 67), 'en': (89, 128, 67), 'jp': (89, 128, 67), 'tw': (89, 128, 67)}, button={'cn': (551, 335, 567, 350), 'en': (551, 335, 567, 350), 'jp': (551, 335, 567, 350), 'tw': (551, 335, 567, 350)}, file={'cn': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_ON.png', 'en': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_ON.png', 'jp': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_ON.png', 'tw': './assets/cn/os_handler/STRATEGY_SEARCH_ZONE_MODE_ON.png'})
|
||||
TEMPLATE_STORAGE_ABYSSAL = Template(file={'cn': './assets/cn/os_handler/TEMPLATE_STORAGE_ABYSSAL.png', 'en': './assets/en/os_handler/TEMPLATE_STORAGE_ABYSSAL.png', 'jp': './assets/jp/os_handler/TEMPLATE_STORAGE_ABYSSAL.png', 'tw': './assets/tw/os_handler/TEMPLATE_STORAGE_ABYSSAL.png'})
|
||||
TEMPLATE_STORAGE_COMBAT = Template(file={'cn': './assets/cn/os_handler/TEMPLATE_STORAGE_COMBAT.png', 'en': './assets/en/os_handler/TEMPLATE_STORAGE_COMBAT.png', 'jp': './assets/jp/os_handler/TEMPLATE_STORAGE_COMBAT.png', 'tw': './assets/tw/os_handler/TEMPLATE_STORAGE_COMBAT.png'})
|
||||
TEMPLATE_STORAGE_LOGGER = Template(file={'cn': './assets/cn/os_handler/TEMPLATE_STORAGE_LOGGER.gif', 'en': './assets/en/os_handler/TEMPLATE_STORAGE_LOGGER.gif', 'jp': './assets/jp/os_handler/TEMPLATE_STORAGE_LOGGER.gif', 'tw': './assets/tw/os_handler/TEMPLATE_STORAGE_LOGGER.gif'})
|
||||
|
@ -1,4 +1,5 @@
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import get_color
|
||||
from module.combat.assets import *
|
||||
from module.exception import CampaignEnd
|
||||
from module.handler.assets import *
|
||||
@ -7,8 +8,10 @@ from module.os.assets import GLOBE_GOTO_MAP
|
||||
from module.os_handler.assets import *
|
||||
from module.os_handler.enemy_searching import EnemySearchingHandler
|
||||
from module.statistics.azurstats import DropImage
|
||||
from module.ui.scroll import Scroll
|
||||
from module.ui.switch import Switch
|
||||
|
||||
STRATEGY_SEARCH_SCROLL = Scroll(STRATEGY_SEARCH_SCROLL_AREA, color=(247, 211, 66), name='STRATEGY_SEARCH_SCROLL')
|
||||
fleet_lock = Switch('Fleet_Lock', offset=(10, 120))
|
||||
fleet_lock.add_status('on', check_button=OS_FLEET_LOCKED)
|
||||
fleet_lock.add_status('off', check_button=OS_FLEET_UNLOCKED)
|
||||
@ -208,7 +211,8 @@ class MapEventHandler(EnemySearchingHandler):
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.appear_then_click(GLOBE_GOTO_MAP, offset=(20, 20), interval=2):
|
||||
# Sometimes entered globe map after clicking AUTO_SEARCH_REWARD, but don't know why
|
||||
# Sometimes entered globe map after clicking AUTO_SEARCH_REWARD
|
||||
# because of duplicated clicks and clicks to places outside the map
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
|
||||
@ -221,11 +225,13 @@ class MapEventHandler(EnemySearchingHandler):
|
||||
|
||||
return cleared
|
||||
|
||||
def handle_os_auto_search_map_option(self, drop=None, enable=True):
|
||||
def handle_os_auto_search_map_option(self, drop=None, enable=True, strategy=False, quit=True):
|
||||
"""
|
||||
Args:
|
||||
drop (DropImage)
|
||||
drop (DropImage):
|
||||
enable (bool):
|
||||
strategy (bool):
|
||||
quit (bool):
|
||||
|
||||
Returns:
|
||||
bool: If clicked.
|
||||
@ -238,13 +244,15 @@ class MapEventHandler(EnemySearchingHandler):
|
||||
raise CampaignEnd
|
||||
if self.appear(AUTO_SEARCH_REWARD, offset=(50, 50)):
|
||||
self.device.screenshot_interval_set()
|
||||
if self.os_auto_search_quit(drop=drop):
|
||||
if quit and self.os_auto_search_quit(drop=drop):
|
||||
# No more items on current map
|
||||
raise CampaignEnd
|
||||
else:
|
||||
# Auto search stopped but map hasn't been cleared
|
||||
return True
|
||||
if enable:
|
||||
if strategy and enable:
|
||||
return self.handle_strategy_search_map_option()
|
||||
elif enable:
|
||||
if self.appear(AUTO_SEARCH_OS_MAP_OPTION_OFF, offset=(5, 120), interval=3) \
|
||||
and AUTO_SEARCH_OS_MAP_OPTION_OFF.match_appear_on(self.device.image):
|
||||
self.device.click(AUTO_SEARCH_OS_MAP_OPTION_OFF)
|
||||
@ -257,6 +265,76 @@ class MapEventHandler(EnemySearchingHandler):
|
||||
|
||||
return False
|
||||
|
||||
def handle_strategy_search_map_option(self):
|
||||
if STRATEGY_SEARCH_MAP_OPTION_OFF.match_appear_on(self.device.image) \
|
||||
and self.appear_then_click(STRATEGY_SEARCH_MAP_OPTION_OFF, interval=2):
|
||||
return False
|
||||
if not self.appear(STRATEGY_SEARCH_POPUP_CHECK):
|
||||
return False
|
||||
self.handle_strategy_search_setting_option()
|
||||
|
||||
def handle_strategy_search_setting_option(self):
|
||||
while 1:
|
||||
self.device.screenshot()
|
||||
if not self.appear(STRATEGY_SEARCH_POPUP_CHECK):
|
||||
return False
|
||||
|
||||
if self.appear(STRATEGY_SEARCH_SAFE_OPTION_OFF) \
|
||||
and get_color(self.device.image, STRATEGY_SEARCH_SAFE_OPTION_OFF.area)[2] > 185:
|
||||
self.device.click(STRATEGY_SEARCH_SAFE_OPTION_OFF)
|
||||
continue
|
||||
if self.appear(STRATEGY_SEARCH_SAFE_OPTION_ON) \
|
||||
and get_color(self.device.image, STRATEGY_SEARCH_SAFE_OPTION_ON.area)[2] > 185:
|
||||
break
|
||||
|
||||
skip_first_screenshot = True
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
if not self.appear(STRATEGY_SEARCH_POPUP_CHECK):
|
||||
return False
|
||||
|
||||
if self.appear(STRATEGY_SEARCH_ZONE_MODE_ON) \
|
||||
and self.appear(STRATEGY_SEARCH_WAIT_ON):
|
||||
break
|
||||
if self.appear(STRATEGY_SEARCH_ZONE_MODE_OFF):
|
||||
self.device.click(STRATEGY_SEARCH_ZONE_MODE_ON)
|
||||
if self.appear(STRATEGY_SEARCH_WAIT_OFF):
|
||||
self.device.click(STRATEGY_SEARCH_WAIT_ON)
|
||||
|
||||
skip_first_screenshot = True
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
if not self.appear(STRATEGY_SEARCH_POPUP_CHECK):
|
||||
return False
|
||||
|
||||
check = self.appear(STRATEGY_SEARCH_WAIT_2_CHECK, offset=(20, 40), threshold=0.7)
|
||||
if check and self.appear(STRATEGY_SEARCH_WAIT_ON, offset=(30, 60)):
|
||||
break
|
||||
if check and self.appear(STRATEGY_SEARCH_WAIT_OFF, offset=(30, 60)):
|
||||
self.device.click(STRATEGY_SEARCH_WAIT_ON)
|
||||
else:
|
||||
STRATEGY_SEARCH_SCROLL.set_top(main=self)
|
||||
STRATEGY_SEARCH_SCROLL.set(0.33, main=self)
|
||||
|
||||
skip_first_screenshot = True
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
if not self.appear(STRATEGY_SEARCH_POPUP_CHECK):
|
||||
return False
|
||||
|
||||
self.appear_then_click(POPUP_CONFIRM, offset=(30, 30), interval=2)
|
||||
if self.is_in_map():
|
||||
return True
|
||||
|
||||
def handle_os_map_fleet_lock(self, enable=None):
|
||||
"""
|
||||
Args:
|
||||
|