1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-09 12:49:03 +08:00

Compare commits

...

12 Commits

Author SHA1 Message Date
sui-feng-cb
a1342048bc Fix: use _raid_has_oil_icon for new UI design 2026-02-05 21:00:49 +08:00
sui-feng-cb
a4fec2e2a0 Upd: raid_20240328 rerun 2026-02-05 20:47:33 +08:00
guoh064
eb33bdd747
Fix: slow retrial for MISSION_OVERVIEW_ACCEPT(_SINGLE) (#5487) 2026-02-04 18:26:41 +08:00
LmeSzinc
bb349af001 Upd: [TW] Coalition assets 2026-01-31 03:25:17 +08:00
LmeSzinc
87a031ed97 Upd: [TW] Event entrance of coalition_20260122 2026-01-31 03:18:38 +08:00
ArecaSapling
52444569a4
Add: war_archives_20230223_cn (#5479) 2026-01-30 10:56:16 +08:00
LmeSzinc
f23d4fb681 Fix: Handle map event in port_enter() 2026-01-28 11:29:37 +08:00
LmeSzinc
912c74b8e1 Fix: [ALAS] handle serial like 5555,16384 2026-01-28 03:38:28 +08:00
LmeSzinc
f552360951 Fix: Startup at coalition fleet preparation 2026-01-23 17:43:04 +08:00
LmeSzinc
6d47f626d1 Opt: Disable event if current event type is raid or coalition 2026-01-23 17:39:46 +08:00
LmeSzinc
0b8d1a5b57 Fix: Empty fleet check should after switching fleet mode 2026-01-23 17:26:14 +08:00
guoh064
e01b77c6e5
Fix: more clear _coalition_has_oil_icon usage (#5473) 2026-01-23 17:25:15 +08:00
49 changed files with 1210 additions and 115 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
assets/cn/raid/RPG_BACK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
assets/en/raid/RPG_BACK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
assets/jp/raid/RPG_BACK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
assets/tw/raid/RPG_BACK.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -57,6 +57,7 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
| 20251016 | war archives 20231026 cn | Tempesta and the Fountain of Youth | 飓风与青春之泉 | Tempesta and the Fountain of Youth | テンペスタと若返りの泉 | 飓風與青春之泉 |
| 20251106 | war archives 20220915 cn | Violet Tempest Blooming Lycoris | 紫绛槿岚 | Violet Tempest Blooming Lycoris | 赫の涙月 菫の暁風 | 紫絳槿嵐 |
| 20251218 | war archives 20221222 cn | Parallel Superimposition | 定向折叠 | Parallel Superimposition | 積重なる事象の幻界 | 定向折疊 |
| 20260129 | war archives 20230223 cn | Revelations of Dust | 湮烬尘墟 | Revelations of Dust | 黙示の遺構 | 湮燼塵墟 |
| 20200227 | event 20200227 cn | Northern Overture | 北境序曲 | Northern Overture | 凍絶の北海 | - |
| 20200312 | event 20200312 cn | The Solomon Ranger | 复刻斯图尔特的硝烟 | The Solomon Ranger Rerun | 南洋に靡く硝煙(復刻) | - |
| 20200326 | event 20200326 cn | Microlayer Medley | 微层混合 | Microlayer Medley | 闇靄払う銀翼 | - |
@ -277,3 +278,5 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
| 20260115 | event 20231221 cn | Light-Chasing Sea of Stars Rerun | 复刻星海逐光 | Light-Chasing Sea of Stars Rerun | 光追う星の海(復刻) | - |
| 20260122 | coalition 20260122 | Light & Shadow Fashion Shoot! | 光影风尚-拍摄进行时 | Light & Shadow Fashion Shoot! | 特集写真-撮影進行中 | - |
| 20260122 | event 20220526 cn | Pledge of the Radiant Court | - | - | - | 泠誓光庭 |
| 20260129 | coalition 20260122 | Light & Shadow Fashion Shoot! | - | - | - | 光影風尚-拍攝進行時 |
| 20260205 | raid 20240328 | From Zero to Hero | 复刻从零开始的魔王讨伐之旅 | From Zero to Hero Rerun | ゼロから頑張る魔王討伐(復刻) | - |

View File

@ -0,0 +1,78 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
MAP = CampaignMap('A1')
MAP.shape = 'H8'
MAP.camera_data = ['D2', 'D5', 'E2', 'E5']
MAP.camera_data_spawn_point = ['D6']
MAP.map_data = """
++ -- -- -- ME -- ME --
-- MB -- ME ++ ME -- ++
ME -- -- Me ++ Me -- ME
ME -- -- -- MS -- -- --
-- ME Me -- -- __ ++ ++
-- ++ ++ ++ Me -- MS ++
-- -- Me -- -- -- -- --
++ -- -- SP SP -- -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 1},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 1},
{'battle': 3, 'enemy': 1, 'boss': 1},
{'battle': 4, 'enemy': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, \
A2, B2, C2, D2, E2, F2, G2, H2, \
A3, B3, C3, D3, E3, F3, G3, H3, \
A4, B4, C4, D4, E4, F4, G4, H4, \
A5, B5, C5, D5, E5, F5, G5, H5, \
A6, B6, C6, D6, E6, F6, G6, H6, \
A7, B7, C7, D7, E7, F7, G7, H7, \
A8, B8, C8, D8, E8, F8, G8, H8, \
= MAP.flatten()
class Config:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['Joffre']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (0.993, 1.011)
MAP_SWIPE_MULTIPLY_MINITOUCH = (0.960, 0.978)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.932, 0.949)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_3(self):
return self.clear_boss()

View File

@ -0,0 +1,76 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .a1 import Config as ConfigBase
MAP = CampaignMap('A2')
MAP.shape = 'I7'
MAP.camera_data = ['F2', 'F5']
MAP.camera_data_spawn_point = ['D5']
MAP.map_data = """
++ ++ -- Me -- ME ++ ++ ++
++ ++ Me -- -- -- -- MB --
SP -- MS -- Me ME __ -- ME
-- -- MS ++ ++ ++ ME ME ++
SP -- MS -- -- -- -- -- ++
++ -- -- -- ME Me ME -- --
++ -- Me ME -- ++ -- ME --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 1},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 1},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['LeMars']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.053, 1.073)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.018, 1.037)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.989, 1.006)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_4(self):
return self.clear_boss()

View File

@ -0,0 +1,79 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .a1 import Config as ConfigBase
MAP = CampaignMap('A3')
MAP.shape = 'I8'
MAP.camera_data = ['D2', 'F2', 'F5']
MAP.camera_data_spawn_point = ['D5']
MAP.map_data = """
ME -- ME -- -- -- -- ME --
-- ME -- Me -- ME ME -- ++
-- ++ ME __ -- ++ ++ ME ME
-- ++ MS -- MB ++ ++ -- --
-- -- -- MS -- Me -- -- ME
-- SP -- -- MS -- -- ME ++
-- -- SP -- Me -- ME -- ++
-- -- -- -- ++ ++ ++ -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 1},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 1},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['LaGalissonniere']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.016, 1.035)
MAP_SWIPE_MULTIPLY_MINITOUCH = (0.982, 1.000)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.954, 0.971)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_4(self):
return self.clear_boss()

View File

@ -0,0 +1,94 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
MAP = CampaignMap('B1')
MAP.shape = 'I8'
MAP.camera_data = ['D3', 'D6', 'F3', 'F6']
MAP.camera_data_spawn_point = ['D2']
MAP.map_data = """
++ SP SP -- ++ -- -- ++ ++
-- -- -- -- ++ ME ME ++ ++
MS -- MS -- MS -- -- ME --
-- Me ++ -- -- -- ME -- ME
-- ++ ++ Me __ Me ++ ++ --
-- ME -- -- -- -- ++ ++ --
++ -- ME -- Me -- MB MB --
++ -- -- ME ++ -- -- -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 1},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 2, 'boss': 1},
{'battle': 5, 'enemy': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
= MAP.flatten()
class Config:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['CL', 'CA']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 33),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
MAP_ENEMY_GENRE_DETECTION_SCALING = {
'DD': 1.111,
'CL': 1.111,
'CA': 1.111,
'CV': 1.111,
'BB': 1.111,
}
MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom'
MAP_WALK_USE_CURRENT_FLEET = True
MAP_SWIPE_MULTIPLY = (1.195, 1.217)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.156, 1.177)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.122, 1.142)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_4(self):
return self.clear_boss()

View File

@ -0,0 +1,80 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .b1 import Config as ConfigBase
MAP = CampaignMap('B2')
MAP.shape = 'J8'
MAP.camera_data = ['D2', 'D6']
MAP.camera_data_spawn_point = ['F3']
MAP.map_data = """
-- -- ++ ++ -- ME -- ME -- --
-- ME ++ ++ Me -- MS ++ ++ --
ME -- -- __ -- -- -- -- SP --
-- ME Me -- ME MS ME -- -- ++
-- ++ ++ -- ++ -- -- -- SP --
-- ++ ++ -- Me -- MS ++ ++ --
-- MB MB -- -- ME -- ++ ++ --
ME -- -- ME ++ ++ ME -- -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 1},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 2},
{'battle': 5, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['CA', 'BB']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.069, 1.089)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.034, 1.053)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.004, 1.022)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_5(self):
return self.fleet_boss.clear_boss()

View File

@ -0,0 +1,83 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .b1 import Config as ConfigBase
MAP = CampaignMap('B3')
MAP.shape = 'J9'
MAP.camera_data = ['E3', 'E7', 'F3', 'F7']
MAP.camera_data_spawn_point = ['E7']
MAP.map_data = """
-- -- ++ -- -- -- -- ++ -- --
-- -- -- ME ++ ++ ME -- -- --
++ ++ Me -- ++ ++ -- Me ++ ++
++ ++ -- -- MB MB -- -- ++ ++
-- Me -- __ -- -- __ -- Me --
-- -- ME MS ++ ++ MS ME -- --
-- -- ME MS -- -- MS ME -- --
++ ME -- -- -- -- -- -- ME ++
++ -- ME ++ SP SP ++ ME -- ++
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 2},
{'battle': 5, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, \
A9, B9, C9, D9, E9, F9, G9, H9, I9, J9, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['CA', 'BB']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (0.969, 0.987)
MAP_SWIPE_MULTIPLY_MINITOUCH = (0.937, 0.955)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.910, 0.926)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_5(self):
return self.fleet_boss.clear_boss()

View File

@ -0,0 +1,78 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
MAP = CampaignMap('C1')
MAP.shape = 'H8'
MAP.camera_data = ['D2', 'D5', 'E2', 'E5']
MAP.camera_data_spawn_point = ['D6']
MAP.map_data = """
++ -- -- -- ME -- ME --
-- MB -- ME ++ ME -- ++
ME -- -- Me ++ Me -- ME
ME -- -- -- MS -- -- --
-- ME Me -- -- __ ++ ++
-- ++ ++ ++ Me -- MS ++
-- -- Me -- -- -- -- --
++ -- -- SP SP -- -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, \
A2, B2, C2, D2, E2, F2, G2, H2, \
A3, B3, C3, D3, E3, F3, G3, H3, \
A4, B4, C4, D4, E4, F4, G4, H4, \
A5, B5, C5, D5, E5, F5, G5, H5, \
A6, B6, C6, D6, E6, F6, G6, H6, \
A7, B7, C7, D7, E7, F7, G7, H7, \
A8, B8, C8, D8, E8, F8, G8, H8, \
= MAP.flatten()
class Config:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['Joffre']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (0.993, 1.011)
MAP_SWIPE_MULTIPLY_MINITOUCH = (0.960, 0.978)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.932, 0.949)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_4(self):
return self.clear_boss()

View File

@ -0,0 +1,76 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .c1 import Config as ConfigBase
MAP = CampaignMap('C2')
MAP.shape = 'I7'
MAP.camera_data = ['F2', 'F5']
MAP.camera_data_spawn_point = ['D5']
MAP.map_data = """
++ ++ -- Me -- ME ++ ++ ++
++ ++ Me -- -- -- -- MB --
SP -- MS -- Me ME __ -- ME
-- -- MS ++ ++ ++ ME ME ++
SP -- MS -- -- -- -- -- ++
++ -- -- -- ME Me ME -- --
++ -- Me ME -- ++ -- ME --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['LeMars']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.053, 1.073)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.018, 1.037)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.989, 1.006)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_4(self):
return self.clear_boss()

View File

@ -0,0 +1,80 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .c1 import Config as ConfigBase
MAP = CampaignMap('C3')
MAP.shape = 'I8'
MAP.camera_data = ['D2', 'F2', 'F5']
MAP.camera_data_spawn_point = ['D5']
MAP.map_data = """
ME -- ME -- -- -- -- ME --
-- ME -- Me -- ME ME -- ++
-- ++ ME __ -- ++ ++ ME ME
-- ++ MS -- MB ++ ++ -- --
-- -- -- MS -- Me -- -- ME
-- SP -- -- MS -- -- ME ++
-- -- SP -- Me -- ME -- ++
-- -- -- -- ++ ++ ++ -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 1},
{'battle': 5, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['LaGalissonniere']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.016, 1.035)
MAP_SWIPE_MULTIPLY_MINITOUCH = (0.982, 1.000)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.954, 0.971)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_5(self):
return self.fleet_boss.clear_boss()

View File

@ -0,0 +1,94 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
MAP = CampaignMap('D1')
MAP.shape = 'I8'
MAP.camera_data = ['D3', 'D6', 'F3', 'F6']
MAP.camera_data_spawn_point = ['D2']
MAP.map_data = """
++ SP SP -- ++ -- -- ++ ++
-- -- -- -- ++ ME ME ++ ++
MS -- MS -- MS -- -- ME --
-- Me ++ -- -- -- ME -- ME
-- ++ ++ Me __ Me ++ ++ --
-- ME -- -- -- -- ++ ++ --
++ -- ME -- Me -- MB MB --
++ -- -- ME ++ -- -- -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 2},
{'battle': 5, 'enemy': 1, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
= MAP.flatten()
class Config:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['CA', 'BB']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 33),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
MAP_ENEMY_GENRE_DETECTION_SCALING = {
'DD': 1.111,
'CL': 1.111,
'CA': 1.111,
'CV': 1.111,
'BB': 1.111,
}
MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom'
MAP_WALK_USE_CURRENT_FLEET = True
MAP_SWIPE_MULTIPLY = (1.195, 1.217)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.156, 1.177)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.122, 1.142)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_5(self):
return self.fleet_boss.clear_boss()

View File

@ -0,0 +1,89 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .d1 import Config as ConfigBase
MAP = CampaignMap('D2')
MAP.shape = 'J8'
MAP.camera_data = ['D2', 'D6']
MAP.camera_data_spawn_point = ['F3']
MAP.map_data = """
-- -- ++ ++ -- ME -- ME -- --
-- ME ++ ++ Me -- MS ++ ++ --
ME -- -- __ -- -- -- -- SP --
-- ME Me -- ME MS ME -- -- ++
-- ++ ++ -- ++ -- -- -- SP --
-- ++ ++ -- Me -- MS ++ ++ --
-- MB MB -- -- ME -- ++ ++ --
ME -- -- ME ++ ++ ME -- -- --
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2, 'siren': 1},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 2},
{'battle': 5, 'enemy': 1},
{'battle': 6, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['CA', 'BB', 'CV']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.069, 1.089)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.034, 1.053)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.004, 1.022)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=1):
return True
return self.battle_default()
def battle_5(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_6(self):
return self.fleet_boss.clear_boss()

View File

@ -0,0 +1,92 @@
from ..campaign_war_archives.campaign_base import CampaignBase
from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger
from .d1 import Config as ConfigBase
MAP = CampaignMap('D3')
MAP.shape = 'J9'
MAP.camera_data = ['E3', 'E7', 'F3', 'F7']
MAP.camera_data_spawn_point = ['E7']
MAP.map_data = """
-- -- ++ -- -- -- -- ++ -- --
-- -- -- ME ++ ++ ME -- -- --
++ ++ Me -- ++ ++ -- Me ++ ++
++ ++ -- -- MB MB -- -- ++ ++
-- Me -- __ -- -- __ -- Me --
-- -- ME MS ++ ++ MS ME -- --
-- -- ME MS -- -- MS ME -- --
++ ME -- -- -- -- -- -- ME ++
++ -- ME ++ SP SP ++ ME -- ++
"""
MAP.weight_data = """
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
50 50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 2, 'siren': 2},
{'battle': 1, 'enemy': 1},
{'battle': 2, 'enemy': 2, 'siren': 1},
{'battle': 3, 'enemy': 1},
{'battle': 4, 'enemy': 2},
{'battle': 5, 'enemy': 1},
{'battle': 6, 'boss': 1},
]
A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, \
A9, B9, C9, D9, E9, F9, G9, H9, I9, J9, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['CA', 'BB', 'CV']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = True
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (0.969, 0.987)
MAP_SWIPE_MULTIPLY_MINITOUCH = (0.937, 0.955)
MAP_SWIPE_MULTIPLY_MAATOUCH = (0.910, 0.926)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=1):
return True
return self.battle_default()
def battle_5(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0):
return True
return self.battle_default()
def battle_6(self):
return self.fleet_boss.clear_boss()

View File

@ -669,7 +669,7 @@
},
"Campaign": {
"Name": "D3",
"Event": "war_archives_20221222_cn",
"Event": "war_archives_20230223_cn",
"Mode": "normal",
"UseClearMode": true,
"UseFleetLock": true,

View File

@ -11,6 +11,22 @@ from module.war_archives.assets import WAR_ARCHIVES_CAMPAIGN_CHECK
class CampaignEvent(CampaignStatus):
def _reset_gems_farming(self, tasks):
"""
Reset GemsFarming to 2-4 when event is over
Args:
tasks (list[str]): Task name
"""
for task in tasks:
if task not in GEMS_FARMINGS:
continue
name = self.config.cross_get(keys=f'{task}.Campaign.Name', default='2-4')
if not self.stage_is_main(name):
logger.info(f'Reset GemsFarming to 2-4')
self.config.cross_set(keys=f'{task}.Campaign.Name', value='2-4')
self.config.cross_set(keys=f'{task}.Campaign.Event', value='campaign_main')
def _disable_tasks(self, tasks):
"""
Args:
@ -26,14 +42,7 @@ class CampaignEvent(CampaignStatus):
self.config.cross_set(keys=keys, value=False)
# Reset GemsFarming
for task in tasks:
if task not in GEMS_FARMINGS:
continue
name = self.config.cross_get(keys=f'{task}.Campaign.Name', default='2-4')
if not self.stage_is_main(name):
logger.info(f'Reset GemsFarming to 2-4')
self.config.cross_set(keys=f'{task}.Campaign.Name', value='2-4')
self.config.cross_set(keys=f'{task}.Campaign.Event', value='campaign_main')
self._reset_gems_farming(tasks)
logger.info(f'Reset event time limit')
self.config.cross_set(keys='EventGeneral.EventGeneral.TimeLimit', value=DEFAULT_TIME)
@ -195,12 +204,31 @@ class CampaignEvent(CampaignStatus):
tasks = RAIDS + COALITIONS + MARITIME_ESCORTS
tasks = [t for t in tasks if self.config.is_task_enabled(t)]
if tasks:
logger.info('New event ongoing, disable old event tasks')
logger.info('New event ongoing, disable old raid event tasks')
self._disable_tasks(tasks)
return True
else:
return False
def disable_event_on_raid(self):
"""
Disable event tasks when entered an raid or coalition,
to be foolproof if user forgot to disable event tasks when event is over and another raid is ongoing
"""
command = self.config.Scheduler_Command
if command not in RAIDS + COALITIONS + MARITIME_ESCORTS:
return False
events = [t for t in EVENTS if self.config.is_task_enabled(t)]
gems = [t for t in GEMS_FARMINGS if self.config.is_task_enabled(t)]
with self.config.multi_set():
if events:
logger.info('New raid event ongoing, disable old event tasks')
self._disable_tasks(events)
if gems:
self._reset_gems_farming(gems)
return events or gems
@staticmethod
def stage_is_main(name) -> bool:
"""

View File

@ -36,17 +36,17 @@ DAL_SWITCH_MULTI = Button(area={'cn': (1060, 473, 1204, 500), 'en': (1061, 474,
DAL_SWITCH_SINGLE = Button(area={'cn': (910, 473, 1055, 500), 'en': (915, 475, 1051, 499), 'jp': (917, 474, 1035, 499), 'tw': (945, 478, 1013, 495)}, color={'cn': (223, 223, 223), 'en': (193, 193, 193), 'jp': (215, 215, 215), 'tw': (168, 168, 168)}, button={'cn': (910, 473, 1055, 500), 'en': (915, 475, 1051, 499), 'jp': (917, 474, 1035, 499), 'tw': (945, 478, 1013, 495)}, file={'cn': './assets/cn/coalition/DAL_SWITCH_SINGLE.png', 'en': './assets/en/coalition/DAL_SWITCH_SINGLE.png', 'jp': './assets/jp/coalition/DAL_SWITCH_SINGLE.png', 'tw': './assets/tw/coalition/DAL_SWITCH_SINGLE.png'})
EMPTY_FLAGSHIP = Button(area={'cn': (247, 237, 277, 267), 'en': (247, 237, 277, 267), 'jp': (247, 237, 277, 267), 'tw': (247, 237, 277, 267)}, color={'cn': (76, 64, 56), 'en': (76, 64, 56), 'jp': (76, 64, 56), 'tw': (76, 64, 56)}, button={'cn': (247, 237, 277, 267), 'en': (247, 237, 277, 267), 'jp': (247, 237, 277, 267), 'tw': (247, 237, 277, 267)}, file={'cn': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'en': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'jp': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'tw': './assets/cn/coalition/EMPTY_FLAGSHIP.png'})
EMPTY_VANGUARD = Button(area={'cn': (515, 237, 545, 267), 'en': (515, 237, 545, 267), 'jp': (515, 237, 545, 267), 'tw': (515, 237, 545, 267)}, color={'cn': (52, 52, 53), 'en': (52, 52, 53), 'jp': (52, 52, 53), 'tw': (52, 52, 53)}, button={'cn': (515, 237, 545, 267), 'en': (515, 237, 545, 267), 'jp': (515, 237, 545, 267), 'tw': (515, 237, 545, 267)}, file={'cn': './assets/cn/coalition/EMPTY_VANGUARD.png', 'en': './assets/cn/coalition/EMPTY_VANGUARD.png', 'jp': './assets/cn/coalition/EMPTY_VANGUARD.png', 'tw': './assets/cn/coalition/EMPTY_VANGUARD.png'})
FASHION_COALITION_CHECK = Button(area={'cn': (102, 19, 177, 51), 'en': (118, 31, 183, 50), 'jp': (101, 18, 175, 51), 'tw': (102, 19, 177, 51)}, color={'cn': (109, 104, 89), 'en': (131, 124, 102), 'jp': (122, 116, 101), 'tw': (109, 104, 89)}, button={'cn': (102, 19, 177, 51), 'en': (118, 31, 183, 50), 'jp': (101, 18, 175, 51), 'tw': (102, 19, 177, 51)}, file={'cn': './assets/cn/coalition/FASHION_COALITION_CHECK.png', 'en': './assets/en/coalition/FASHION_COALITION_CHECK.png', 'jp': './assets/jp/coalition/FASHION_COALITION_CHECK.png', 'tw': './assets/cn/coalition/FASHION_COALITION_CHECK.png'})
FASHION_COALITION_CHECK = Button(area={'cn': (102, 19, 177, 51), 'en': (118, 31, 183, 50), 'jp': (101, 18, 175, 51), 'tw': (101, 17, 177, 51)}, color={'cn': (109, 104, 89), 'en': (131, 124, 102), 'jp': (122, 116, 101), 'tw': (108, 103, 89)}, button={'cn': (102, 19, 177, 51), 'en': (118, 31, 183, 50), 'jp': (101, 18, 175, 51), 'tw': (101, 17, 177, 51)}, file={'cn': './assets/cn/coalition/FASHION_COALITION_CHECK.png', 'en': './assets/en/coalition/FASHION_COALITION_CHECK.png', 'jp': './assets/jp/coalition/FASHION_COALITION_CHECK.png', 'tw': './assets/tw/coalition/FASHION_COALITION_CHECK.png'})
FASHION_EASY = Button(area={'cn': (136, 223, 199, 263), 'en': (136, 223, 199, 263), 'jp': (136, 223, 199, 263), 'tw': (136, 223, 199, 263)}, color={'cn': (225, 199, 197), 'en': (225, 199, 197), 'jp': (225, 199, 197), 'tw': (225, 199, 197)}, button={'cn': (136, 223, 199, 263), 'en': (136, 223, 199, 263), 'jp': (136, 223, 199, 263), 'tw': (136, 223, 199, 263)}, file={'cn': './assets/cn/coalition/FASHION_EASY.png', 'en': './assets/cn/coalition/FASHION_EASY.png', 'jp': './assets/cn/coalition/FASHION_EASY.png', 'tw': './assets/cn/coalition/FASHION_EASY.png'})
FASHION_EX = Button(area={'cn': (844, 246, 923, 301), 'en': (844, 246, 923, 301), 'jp': (844, 246, 923, 301), 'tw': (844, 246, 923, 301)}, color={'cn': (140, 115, 114), 'en': (140, 115, 114), 'jp': (140, 115, 114), 'tw': (140, 115, 114)}, button={'cn': (844, 246, 923, 301), 'en': (844, 246, 923, 301), 'jp': (844, 246, 923, 301), 'tw': (844, 246, 923, 301)}, file={'cn': './assets/cn/coalition/FASHION_EX.png', 'en': './assets/cn/coalition/FASHION_EX.png', 'jp': './assets/cn/coalition/FASHION_EX.png', 'tw': './assets/cn/coalition/FASHION_EX.png'})
FASHION_HARD = Button(area={'cn': (485, 167, 554, 215), 'en': (485, 167, 554, 215), 'jp': (485, 167, 554, 215), 'tw': (485, 167, 554, 215)}, color={'cn': (152, 136, 129), 'en': (152, 136, 129), 'jp': (152, 136, 129), 'tw': (152, 136, 129)}, button={'cn': (485, 167, 554, 215), 'en': (485, 167, 554, 215), 'jp': (485, 167, 554, 215), 'tw': (485, 167, 554, 215)}, file={'cn': './assets/cn/coalition/FASHION_HARD.png', 'en': './assets/cn/coalition/FASHION_HARD.png', 'jp': './assets/cn/coalition/FASHION_HARD.png', 'tw': './assets/cn/coalition/FASHION_HARD.png'})
FASHION_MODE_BATTLE = Button(area={'cn': (152, 635, 213, 669), 'en': (108, 644, 188, 668), 'jp': (150, 636, 215, 668), 'tw': (152, 635, 213, 669)}, color={'cn': (140, 133, 117), 'en': (150, 143, 128), 'jp': (144, 137, 119), 'tw': (140, 133, 117)}, button={'cn': (152, 635, 213, 669), 'en': (108, 644, 188, 668), 'jp': (150, 636, 215, 668), 'tw': (152, 635, 213, 669)}, file={'cn': './assets/cn/coalition/FASHION_MODE_BATTLE.png', 'en': './assets/en/coalition/FASHION_MODE_BATTLE.png', 'jp': './assets/jp/coalition/FASHION_MODE_BATTLE.png', 'tw': './assets/cn/coalition/FASHION_MODE_BATTLE.png'})
FASHION_MODE_STORY = Button(area={'cn': (154, 629, 220, 666), 'en': (117, 642, 195, 667), 'jp': (156, 629, 219, 665), 'tw': (154, 629, 220, 666)}, color={'cn': (141, 134, 116), 'en': (158, 148, 132), 'jp': (151, 143, 123), 'tw': (141, 134, 116)}, button={'cn': (154, 629, 220, 666), 'en': (117, 642, 195, 667), 'jp': (156, 629, 219, 665), 'tw': (154, 629, 220, 666)}, file={'cn': './assets/cn/coalition/FASHION_MODE_STORY.png', 'en': './assets/en/coalition/FASHION_MODE_STORY.png', 'jp': './assets/jp/coalition/FASHION_MODE_STORY.png', 'tw': './assets/cn/coalition/FASHION_MODE_STORY.png'})
FASHION_MODE_BATTLE = Button(area={'cn': (152, 635, 213, 669), 'en': (108, 644, 188, 668), 'jp': (150, 636, 215, 668), 'tw': (150, 637, 212, 667)}, color={'cn': (140, 133, 117), 'en': (150, 143, 128), 'jp': (144, 137, 119), 'tw': (128, 123, 109)}, button={'cn': (152, 635, 213, 669), 'en': (108, 644, 188, 668), 'jp': (150, 636, 215, 668), 'tw': (150, 637, 212, 667)}, file={'cn': './assets/cn/coalition/FASHION_MODE_BATTLE.png', 'en': './assets/en/coalition/FASHION_MODE_BATTLE.png', 'jp': './assets/jp/coalition/FASHION_MODE_BATTLE.png', 'tw': './assets/tw/coalition/FASHION_MODE_BATTLE.png'})
FASHION_MODE_STORY = Button(area={'cn': (154, 629, 220, 666), 'en': (117, 642, 195, 667), 'jp': (156, 629, 219, 665), 'tw': (154, 629, 219, 666)}, color={'cn': (141, 134, 116), 'en': (158, 148, 132), 'jp': (151, 143, 123), 'tw': (139, 132, 115)}, button={'cn': (154, 629, 220, 666), 'en': (117, 642, 195, 667), 'jp': (156, 629, 219, 665), 'tw': (154, 629, 219, 666)}, file={'cn': './assets/cn/coalition/FASHION_MODE_STORY.png', 'en': './assets/en/coalition/FASHION_MODE_STORY.png', 'jp': './assets/jp/coalition/FASHION_MODE_STORY.png', 'tw': './assets/tw/coalition/FASHION_MODE_STORY.png'})
FASHION_NORMAL = Button(area={'cn': (322, 295, 392, 334), 'en': (322, 295, 392, 334), 'jp': (322, 295, 392, 334), 'tw': (322, 295, 392, 334)}, color={'cn': (219, 196, 198), 'en': (219, 196, 198), 'jp': (219, 196, 198), 'tw': (219, 196, 198)}, button={'cn': (322, 295, 392, 334), 'en': (322, 295, 392, 334), 'jp': (322, 295, 392, 334), 'tw': (322, 295, 392, 334)}, file={'cn': './assets/cn/coalition/FASHION_NORMAL.png', 'en': './assets/cn/coalition/FASHION_NORMAL.png', 'jp': './assets/cn/coalition/FASHION_NORMAL.png', 'tw': './assets/cn/coalition/FASHION_NORMAL.png'})
FASHION_PT_OCR = Button(area={'cn': (881, 658, 937, 674), 'en': (881, 658, 937, 674), 'jp': (881, 658, 937, 674), 'tw': (881, 658, 937, 674)}, color={'cn': (136, 127, 122), 'en': (136, 127, 122), 'jp': (136, 127, 122), 'tw': (136, 127, 122)}, button={'cn': (881, 658, 937, 674), 'en': (881, 658, 937, 674), 'jp': (881, 658, 937, 674), 'tw': (881, 658, 937, 674)}, file={'cn': './assets/cn/coalition/FASHION_PT_OCR.png', 'en': './assets/cn/coalition/FASHION_PT_OCR.png', 'jp': './assets/cn/coalition/FASHION_PT_OCR.png', 'tw': './assets/cn/coalition/FASHION_PT_OCR.png'})
FASHION_SP = Button(area={'cn': (704, 194, 762, 242), 'en': (704, 194, 762, 242), 'jp': (704, 194, 762, 242), 'tw': (704, 194, 762, 242)}, color={'cn': (146, 133, 135), 'en': (146, 133, 135), 'jp': (146, 133, 135), 'tw': (146, 133, 135)}, button={'cn': (704, 194, 762, 242), 'en': (704, 194, 762, 242), 'jp': (704, 194, 762, 242), 'tw': (704, 194, 762, 242)}, file={'cn': './assets/cn/coalition/FASHION_SP.png', 'en': './assets/cn/coalition/FASHION_SP.png', 'jp': './assets/cn/coalition/FASHION_SP.png', 'tw': './assets/cn/coalition/FASHION_SP.png'})
FASHION_SWITCH_MULTI = Button(area={'cn': (1075, 457, 1206, 485), 'en': (1076, 457, 1206, 485), 'jp': (1075, 457, 1206, 485), 'tw': (1075, 457, 1206, 485)}, color={'cn': (233, 183, 63), 'en': (201, 158, 54), 'jp': (227, 178, 61), 'tw': (233, 183, 63)}, button={'cn': (1075, 457, 1206, 485), 'en': (1076, 457, 1206, 485), 'jp': (1075, 457, 1206, 485), 'tw': (1075, 457, 1206, 485)}, file={'cn': './assets/cn/coalition/FASHION_SWITCH_MULTI.png', 'en': './assets/en/coalition/FASHION_SWITCH_MULTI.png', 'jp': './assets/jp/coalition/FASHION_SWITCH_MULTI.png', 'tw': './assets/cn/coalition/FASHION_SWITCH_MULTI.png'})
FASHION_SWITCH_SINGLE = Button(area={'cn': (929, 457, 1059, 485), 'en': (929, 457, 1059, 485), 'jp': (929, 457, 1059, 485), 'tw': (929, 457, 1059, 485)}, color={'cn': (230, 181, 62), 'en': (202, 159, 54), 'jp': (227, 178, 61), 'tw': (230, 181, 62)}, button={'cn': (929, 457, 1059, 485), 'en': (929, 457, 1059, 485), 'jp': (929, 457, 1059, 485), 'tw': (929, 457, 1059, 485)}, file={'cn': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png', 'en': './assets/en/coalition/FASHION_SWITCH_SINGLE.png', 'jp': './assets/jp/coalition/FASHION_SWITCH_SINGLE.png', 'tw': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png'})
FASHION_SWITCH_MULTI = Button(area={'cn': (1075, 457, 1206, 485), 'en': (1076, 457, 1206, 485), 'jp': (1075, 457, 1206, 485), 'tw': (1075, 457, 1206, 485)}, color={'cn': (233, 183, 63), 'en': (201, 158, 54), 'jp': (227, 178, 61), 'tw': (229, 181, 62)}, button={'cn': (1075, 457, 1206, 485), 'en': (1076, 457, 1206, 485), 'jp': (1075, 457, 1206, 485), 'tw': (1075, 457, 1206, 485)}, file={'cn': './assets/cn/coalition/FASHION_SWITCH_MULTI.png', 'en': './assets/en/coalition/FASHION_SWITCH_MULTI.png', 'jp': './assets/jp/coalition/FASHION_SWITCH_MULTI.png', 'tw': './assets/tw/coalition/FASHION_SWITCH_MULTI.png'})
FASHION_SWITCH_SINGLE = Button(area={'cn': (929, 457, 1059, 485), 'en': (929, 457, 1059, 485), 'jp': (929, 457, 1059, 485), 'tw': (929, 457, 1059, 485)}, color={'cn': (230, 181, 62), 'en': (202, 159, 54), 'jp': (227, 178, 61), 'tw': (225, 177, 61)}, button={'cn': (929, 457, 1059, 485), 'en': (929, 457, 1059, 485), 'jp': (929, 457, 1059, 485), 'tw': (929, 457, 1059, 485)}, file={'cn': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png', 'en': './assets/en/coalition/FASHION_SWITCH_SINGLE.png', 'jp': './assets/jp/coalition/FASHION_SWITCH_SINGLE.png', 'tw': './assets/tw/coalition/FASHION_SWITCH_SINGLE.png'})
FLEET_NOT_PREPARED = Button(area={'cn': (1008, 310, 1110, 334), 'en': (1008, 310, 1110, 334), 'jp': (1008, 310, 1110, 334), 'tw': (1008, 310, 1110, 334)}, color={'cn': (106, 106, 112), 'en': (106, 106, 112), 'jp': (106, 106, 112), 'tw': (108, 107, 112)}, button={'cn': (1008, 310, 1110, 334), 'en': (1008, 310, 1110, 334), 'jp': (1008, 310, 1110, 334), 'tw': (1008, 310, 1110, 334)}, file={'cn': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'en': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'jp': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'tw': './assets/tw/coalition/FLEET_NOT_PREPARED.png'})
FROSTFALL_COALITION_CHECK = Button(area={'cn': (118, 14, 227, 39), 'en': (118, 16, 221, 36), 'jp': (118, 14, 227, 39), 'tw': (118, 14, 227, 39)}, color={'cn': (145, 161, 200), 'en': (116, 130, 168), 'jp': (150, 166, 204), 'tw': (152, 168, 206)}, button={'cn': (118, 14, 227, 39), 'en': (118, 16, 221, 36), 'jp': (118, 14, 227, 39), 'tw': (118, 14, 227, 39)}, file={'cn': './assets/cn/coalition/FROSTFALL_COALITION_CHECK.png', 'en': './assets/en/coalition/FROSTFALL_COALITION_CHECK.png', 'jp': './assets/jp/coalition/FROSTFALL_COALITION_CHECK.png', 'tw': './assets/tw/coalition/FROSTFALL_COALITION_CHECK.png'})
FROSTFALL_EX = Button(area={'cn': (622, 372, 649, 384), 'en': (622, 372, 649, 384), 'jp': (622, 372, 649, 384), 'tw': (622, 372, 649, 384)}, color={'cn': (198, 152, 252), 'en': (198, 152, 252), 'jp': (198, 152, 252), 'tw': (182, 127, 252)}, button={'cn': (622, 372, 649, 384), 'en': (622, 372, 649, 384), 'jp': (622, 372, 649, 384), 'tw': (622, 372, 649, 384)}, file={'cn': './assets/cn/coalition/FROSTFALL_EX.png', 'en': './assets/en/coalition/FROSTFALL_EX.png', 'jp': './assets/jp/coalition/FROSTFALL_EX.png', 'tw': './assets/tw/coalition/FROSTFALL_EX.png'})

View File

@ -96,8 +96,8 @@ class Coalition(CoalitionCombat, CampaignEvent):
self.config.StopCondition_RunCount = 0
self.config.Scheduler_Enable = False
return True
# Oil limit
if oil_check and self._coalition_has_oil_icon:
# Oil limit in current page
if oil_check:
if self.get_oil() < max(500, self.config.StopCondition_OilLimit):
logger.hr('Triggered stop condition: Oil limit')
self.config.task_delay(minute=(120, 240))
@ -147,7 +147,7 @@ class Coalition(CoalitionCombat, CampaignEvent):
self.coalition_map_exit(event)
raise
if self.triggered_stop_condition(oil_check=True):
if self._coalition_has_oil_icon and self.triggered_stop_condition(oil_check=True):
self.coalition_map_exit(event)
raise ScriptEnd
@ -194,6 +194,7 @@ class Coalition(CoalitionCombat, CampaignEvent):
self.device.stuck_record_clear()
self.device.click_record_clear()
self.ui_goto_coalition()
self.disable_event_on_raid()
self.coalition_ensure_mode(event, 'battle')
# End

View File

@ -67,12 +67,15 @@ class CoalitionUI(Combat):
else:
logger.warning(f'Unknown coalition campaign mode: {mode}')
def coalition_ensure_fleet(self, event, mode):
def coalition_set_fleet(self, event, mode):
"""
Args:
event (str): Event name.
mode (str): 'single' or 'multi'
Returns:
bool: If clicked
Pages:
in: FLEET_PREPARATION
"""
@ -96,12 +99,17 @@ class CoalitionUI(Combat):
logger.error(f'FLEET_SWITCH is not defined in event {event}')
raise ScriptError
if fleet_switch.get(main=self) == mode:
return False
if mode == 'single':
fleet_switch.set('single', main=self)
return True
elif mode == 'multi':
fleet_switch.set('multi', main=self)
return True
else:
logger.warning(f'Unknown coalition fleet mode: {mode}')
return False
@staticmethod
def coalition_get_entrance(event, stage):
@ -279,7 +287,7 @@ class CoalitionUI(Combat):
mode (str): 'single' or 'multi'
Returns:
bool: If success
bool: If clicked
"""
stage = stage.lower()
@ -296,8 +304,20 @@ class CoalitionUI(Combat):
if stage in ['easy', 'sp', 'ex']:
return False
self.coalition_ensure_fleet(event, mode)
return True
clicked = self.coalition_set_fleet(event, mode)
if self.appear(FLEET_NOT_PREPARED, offset=(20, 20)):
logger.critical('FLEET_NOT_PREPARED')
logger.critical('Please prepare you fleets before running coalition battles')
raise RequestHumanTakeover
if self.appear(EMPTY_FLAGSHIP, offset=(20, 20)):
logger.critical('EMPTY_FLAGSHIP, Please prepare you fleets before running coalition battles')
raise RequestHumanTakeover
if self.appear(EMPTY_VANGUARD, offset=(20, 20)):
logger.critical('EMPTY_VANGUARD, Please prepare you fleets before running coalition battles')
raise RequestHumanTakeover
return clicked
def coalition_map_exit(self, event):
"""
@ -367,16 +387,6 @@ class CoalitionUI(Combat):
"This stage can only be farmed once a day, "
"but it's the second time that you are entering")
raise RequestHumanTakeover
if self.appear(FLEET_NOT_PREPARED, offset=(20, 20)):
logger.critical('FLEET_NOT_PREPARED')
logger.critical('Please prepare you fleets before running coalition battles')
raise RequestHumanTakeover
if self.appear(EMPTY_FLAGSHIP, offset=(20, 20)):
logger.critical('EMPTY_FLAGSHIP, Please prepare you fleets before running coalition battles')
raise RequestHumanTakeover
if self.appear(EMPTY_VANGUARD, offset=(20, 20)):
logger.critical('EMPTY_VANGUARD, Please prepare you fleets before running coalition battles')
raise RequestHumanTakeover
# End
if self.appear(BATTLE_PREPARATION, offset=(20, 20)):

View File

@ -2722,21 +2722,23 @@
"type": "state",
"value": "campaign_main",
"option": [
"raid_20240328",
"raid_20250116"
],
"option_cn": [
"raid_20250116"
"raid_20240328"
],
"option_en": [
"raid_20250116"
"raid_20240328"
],
"option_jp": [
"raid_20250116"
"raid_20240328"
],
"option_tw": [
"raid_20250116"
],
"option_bold": [
"raid_20240328",
"raid_20250116"
]
},
@ -3121,7 +3123,6 @@
"type": "state",
"value": "campaign_main",
"option": [
"coalition_20251120",
"coalition_20260122"
],
"option_cn": [
@ -3134,10 +3135,9 @@
"coalition_20260122"
],
"option_tw": [
"coalition_20251120"
"coalition_20260122"
],
"option_bold": [
"coalition_20251120",
"coalition_20260122"
]
},
@ -3461,9 +3461,11 @@
"war_archives_20220728_cn",
"war_archives_20220915_cn",
"war_archives_20221222_cn",
"war_archives_20230223_cn",
"war_archives_20231026_cn"
],
"option_cn": [
"war_archives_20230223_cn",
"war_archives_20221222_cn",
"war_archives_20220915_cn",
"war_archives_20231026_cn",
@ -3509,6 +3511,7 @@
"war_archives_20181020_en"
],
"option_en": [
"war_archives_20230223_cn",
"war_archives_20221222_cn",
"war_archives_20220915_cn",
"war_archives_20231026_cn",
@ -3554,6 +3557,7 @@
"war_archives_20181020_en"
],
"option_jp": [
"war_archives_20230223_cn",
"war_archives_20221222_cn",
"war_archives_20220915_cn",
"war_archives_20231026_cn",
@ -3599,6 +3603,7 @@
"war_archives_20181020_en"
],
"option_tw": [
"war_archives_20230223_cn",
"war_archives_20221222_cn",
"war_archives_20220915_cn",
"war_archives_20231026_cn",
@ -6077,21 +6082,23 @@
"type": "state",
"value": "campaign_main",
"option": [
"raid_20240328",
"raid_20250116"
],
"option_cn": [
"raid_20250116"
"raid_20240328"
],
"option_en": [
"raid_20250116"
"raid_20240328"
],
"option_jp": [
"raid_20250116"
"raid_20240328"
],
"option_tw": [
"raid_20250116"
],
"option_bold": [
"raid_20240328",
"raid_20250116"
]
},
@ -6304,7 +6311,6 @@
"type": "state",
"value": "campaign_main",
"option": [
"coalition_20251120",
"coalition_20260122"
],
"option_cn": [
@ -6317,10 +6323,9 @@
"coalition_20260122"
],
"option_tw": [
"coalition_20251120"
"coalition_20260122"
],
"option_bold": [
"coalition_20251120",
"coalition_20260122"
]
},

View File

@ -773,7 +773,7 @@
"raid_20230118": "Winter Pathfinder",
"raid_20230629": "Reflections of the Oasis",
"raid_20240130": "Spring Festive Fiasco",
"raid_20240328": "From Zero to Hero",
"raid_20240328": "From Zero to Hero Rerun",
"raid_20250116": "Spring Fashion Festa",
"war_archives_20180607_cn": "archives Ink Stained Steel Sakura",
"war_archives_20180726_cn": "archives Iris of Light and Dark",
@ -817,6 +817,7 @@
"war_archives_20220728_cn": "archives Aquilifers Ballade",
"war_archives_20220915_cn": "archives Violet Tempest Blooming Lycoris",
"war_archives_20221222_cn": "archives Parallel Superimposition",
"war_archives_20230223_cn": "archives Revelations of Dust",
"war_archives_20231026_cn": "archives Tempesta and the Fountain of Youth"
},
"Mode": {

View File

@ -773,7 +773,7 @@
"raid_20230118": "冬の案内人",
"raid_20230629": "緑地伽話",
"raid_20240130": "新春宴会狂騒曲",
"raid_20240328": "ゼロから頑張る魔王討伐",
"raid_20240328": "ゼロから頑張る魔王討伐(復刻)",
"raid_20250116": "新春華裳協奏曲",
"war_archives_20180607_cn": "檔案 墨染まりし鋼の桜",
"war_archives_20180726_cn": "檔案 光と影のアイリス",
@ -817,6 +817,7 @@
"war_archives_20220728_cn": "檔案 鋼鷲の冒険譚",
"war_archives_20220915_cn": "檔案 赫の涙月 菫の暁風",
"war_archives_20221222_cn": "檔案 積重なる事象の幻界",
"war_archives_20230223_cn": "檔案 黙示の遺構",
"war_archives_20231026_cn": "檔案 テンペスタと若返りの泉"
},
"Mode": {

View File

@ -773,7 +773,7 @@
"raid_20230118": "冬日的寻路人",
"raid_20230629": "绿洲往事",
"raid_20240130": "寰昌宇定家事忙",
"raid_20240328": "从零开始的魔王讨伐之旅",
"raid_20240328": "复刻从零开始的魔王讨伐之旅",
"raid_20250116": "华裳巧展喜事长",
"war_archives_20180607_cn": "档案 墨染的钢铁之花",
"war_archives_20180726_cn": "档案 光与影的鸢尾之华",
@ -817,6 +817,7 @@
"war_archives_20220728_cn": "档案 雄鹰的叙事歌",
"war_archives_20220915_cn": "档案 紫绛槿岚",
"war_archives_20221222_cn": "档案 定向折叠",
"war_archives_20230223_cn": "档案 湮烬尘墟",
"war_archives_20231026_cn": "档案 飓风与青春之泉"
},
"Mode": {

View File

@ -684,7 +684,7 @@
"coalition_20240627": "歡迎來到童心學院",
"coalition_20250626": "迷彩都市的尋蹤者",
"coalition_20251120": "DATE A LANE",
"coalition_20260122": "Light & Shadow Fashion Shoot!",
"coalition_20260122": "光影風尚-拍攝進行時",
"event_20200227_cn": "Northern Overture",
"event_20200312_cn": "斯圖爾特的硝煙",
"event_20200326_cn": "Microlayer Medley",
@ -817,6 +817,7 @@
"war_archives_20220728_cn": "檔案 雄鷹的敘事歌",
"war_archives_20220915_cn": "檔案 紫絳槿嵐",
"war_archives_20221222_cn": "檔案 定向折疊",
"war_archives_20230223_cn": "檔案 湮燼塵墟",
"war_archives_20231026_cn": "檔案 飓風與青春之泉"
},
"Mode": {

View File

@ -71,28 +71,39 @@ class ConnectionAttr:
self.config.DEVICE_OVER_HTTP = self.is_over_http
@staticmethod
def revise_serial(serial):
serial = serial.replace(' ', '')
def revise_serial(serial: str):
"""
Tons of fool-proof fixes to handle manual serial input
To load a serial:
serial = SerialStr.revise_serial(serial)
"""
serial = serial.strip().replace(' ', '')
# 127。0。0。15555
serial = serial.replace('', '.').replace('', '.').replace(',', '.').replace('', ':')
# 127.0.0.1.5555
serial = serial.replace('127.0.0.1.', '127.0.0.1:')
# Mumu12 5.0 shows double serials, some people may just copy-paste it
# 5555,16384 -> replaced to 5555.16384
# 5555,16384 (actually "5555.16384" because replace(',', '.'))
if '.' in serial:
left, _, right = serial.partition('.')
if left.startswith('55') and right.startswith('16'):
serial = right
try:
left = int(left)
right = int(right)
if 5500 < left < 6000 and 16300 < right < 20000:
serial = str(right)
except ValueError:
pass
# 16384
try:
port = int(serial)
if 1000 < port < 65536:
serial = f'127.0.0.1:{port}'
except ValueError:
pass
if serial.isdigit():
try:
port = int(serial)
if 1000 < port < 65536:
serial = f'127.0.0.1:{port}'
except ValueError:
pass
# 夜神模拟器 127.0.0.1:62001
# MuMu模拟器12127.0.0.1:16384
if '模拟' in serial:
import re
res = re.search(r'(127\.\d+\.\d+\.\d+:\d+)', serial)
if res:
serial = res.group(1)

View File

@ -279,19 +279,19 @@ def get_serial_pair(serial):
serial (str):
Returns:
str, str: `127.0.0.1:5555+{X}` and `emulator-5554+{X}`, 0 <= X <= 32
tuple[Optional[str], Optional[str]]: `127.0.0.1:5555+{X}` and `emulator-5554+{X}`, 0 <= X <= 32
"""
if serial.startswith('127.0.0.1:'):
try:
port = int(serial[10:])
if 5555 <= port <= 5555 + 32:
if 5555 <= port <= 5555 + 64:
return f'127.0.0.1:{port}', f'emulator-{port - 1}'
except (ValueError, IndexError):
pass
if serial.startswith('emulator-'):
try:
port = int(serial[9:])
if 5554 <= port <= 5554 + 32:
if 5554 <= port <= 5554 + 64:
return f'127.0.0.1:{port + 1}', f'emulator-{port}'
except (ValueError, IndexError):
pass

View File

@ -33,6 +33,7 @@ MISSION_MONTHLY_BOSS = Button(area={'cn': (669, 188, 747, 206), 'en': (711, 226,
MISSION_OVERVIEW_ACCEPT = Button(area={'cn': (1072, 12, 1130, 40), 'en': (1082, 16, 1123, 54), 'jp': (1069, 5, 1132, 43), 'tw': (1069, 10, 1131, 42)}, color={'cn': (230, 193, 168), 'en': (228, 174, 128), 'jp': (224, 166, 120), 'tw': (227, 180, 146)}, button={'cn': (1072, 12, 1130, 40), 'en': (1082, 16, 1123, 54), 'jp': (1069, 5, 1132, 43), 'tw': (1069, 10, 1131, 42)}, file={'cn': './assets/cn/os_handler/MISSION_OVERVIEW_ACCEPT.png', 'en': './assets/en/os_handler/MISSION_OVERVIEW_ACCEPT.png', 'jp': './assets/jp/os_handler/MISSION_OVERVIEW_ACCEPT.png', 'tw': './assets/tw/os_handler/MISSION_OVERVIEW_ACCEPT.png'})
MISSION_OVERVIEW_ACCEPT_SINGLE = Button(area={'cn': (1066, 121, 1138, 149), 'en': (1068, 127, 1138, 149), 'jp': (1067, 121, 1138, 149), 'tw': (1066, 121, 1138, 149)}, color={'cn': (145, 182, 231), 'en': (156, 196, 237), 'jp': (133, 173, 227), 'tw': (145, 182, 231)}, button={'cn': (1066, 121, 1138, 149), 'en': (1068, 127, 1138, 149), 'jp': (1067, 121, 1138, 149), 'tw': (1066, 121, 1138, 149)}, file={'cn': './assets/cn/os_handler/MISSION_OVERVIEW_ACCEPT_SINGLE.png', 'en': './assets/en/os_handler/MISSION_OVERVIEW_ACCEPT_SINGLE.png', 'jp': './assets/jp/os_handler/MISSION_OVERVIEW_ACCEPT_SINGLE.png', 'tw': './assets/cn/os_handler/MISSION_OVERVIEW_ACCEPT_SINGLE.png'})
MISSION_OVERVIEW_CHECK = Button(area={'cn': (127, 17, 262, 42), 'en': (128, 18, 300, 37), 'jp': (126, 16, 263, 42), 'tw': (126, 16, 263, 42)}, color={'cn': (148, 165, 209), 'en': (120, 136, 182), 'jp': (95, 109, 148), 'tw': (147, 164, 208)}, button={'cn': (127, 17, 262, 42), 'en': (128, 18, 300, 37), 'jp': (126, 16, 263, 42), 'tw': (126, 16, 263, 42)}, file={'cn': './assets/cn/os_handler/MISSION_OVERVIEW_CHECK.png', 'en': './assets/en/os_handler/MISSION_OVERVIEW_CHECK.png', 'jp': './assets/jp/os_handler/MISSION_OVERVIEW_CHECK.png', 'tw': './assets/tw/os_handler/MISSION_OVERVIEW_CHECK.png'})
MISSION_OVERVIEW_EMPTY = Button(area={'cn': (1052, 320, 1067, 390), 'en': (1052, 320, 1067, 390), 'jp': (1052, 320, 1067, 390), 'tw': (1052, 320, 1067, 390)}, color={'cn': (144, 91, 99), 'en': (144, 91, 99), 'jp': (144, 91, 99), 'tw': (144, 91, 99)}, button={'cn': (1052, 320, 1067, 390), 'en': (1052, 320, 1067, 390), 'jp': (1052, 320, 1067, 390), 'tw': (1052, 320, 1067, 390)}, file={'cn': './assets/cn/os_handler/MISSION_OVERVIEW_EMPTY.png', 'en': './assets/en/os_handler/MISSION_OVERVIEW_EMPTY.png', 'jp': './assets/jp/os_handler/MISSION_OVERVIEW_EMPTY.png', 'tw': './assets/tw/os_handler/MISSION_OVERVIEW_EMPTY.png'})
MISSION_OVERVIEW_ENTER = Button(area={'cn': (1111, 672, 1207, 690), 'en': (1112, 662, 1183, 689), 'jp': (1108, 670, 1224, 691), 'tw': (1110, 671, 1207, 690)}, color={'cn': (66, 68, 72), 'en': (60, 67, 78), 'jp': (38, 43, 50), 'tw': (67, 70, 75)}, button={'cn': (1105, 629, 1255, 693), 'en': (1105, 629, 1254, 693), 'jp': (1105, 629, 1254, 693), 'tw': (1105, 629, 1255, 693)}, file={'cn': './assets/cn/os_handler/MISSION_OVERVIEW_ENTER.png', 'en': './assets/en/os_handler/MISSION_OVERVIEW_ENTER.png', 'jp': './assets/jp/os_handler/MISSION_OVERVIEW_ENTER.png', 'tw': './assets/tw/os_handler/MISSION_OVERVIEW_ENTER.png'})
MISSION_QUIT = Button(area={'cn': (1086, 111, 1152, 155), 'en': (1086, 111, 1152, 155), 'jp': (1086, 111, 1152, 155), 'tw': (1086, 111, 1152, 155)}, color={'cn': (152, 38, 35), 'en': (152, 38, 35), 'jp': (152, 38, 35), 'tw': (152, 38, 35)}, button={'cn': (1086, 111, 1152, 155), 'en': (1086, 111, 1152, 155), 'jp': (1086, 111, 1152, 155), 'tw': (1086, 111, 1152, 155)}, file={'cn': './assets/cn/os_handler/MISSION_QUIT.png', 'en': './assets/en/os_handler/MISSION_QUIT.png', 'jp': './assets/jp/os_handler/MISSION_QUIT.png', 'tw': './assets/tw/os_handler/MISSION_QUIT.png'})
ORDER_CHECK = Button(area={'cn': (60, 623, 98, 659), 'en': (60, 623, 98, 659), 'jp': (60, 623, 98, 659), 'tw': (60, 623, 98, 659)}, color={'cn': (60, 77, 122), 'en': (60, 77, 122), 'jp': (60, 77, 122), 'tw': (60, 77, 122)}, button={'cn': (106, 77, 224, 94), 'en': (101, 79, 306, 93), 'jp': (65, 64, 147, 95), 'tw': (106, 76, 226, 95)}, file={'cn': './assets/cn/os_handler/ORDER_CHECK.png', 'en': './assets/en/os_handler/ORDER_CHECK.png', 'jp': './assets/jp/os_handler/ORDER_CHECK.png', 'tw': './assets/tw/os_handler/ORDER_CHECK.png'})

View File

@ -176,27 +176,28 @@ class MissionHandler(GlobeOperation, ZoneManager):
offset=(200, 20), retry_wait=3, additional=self.handle_manjuu,
skip_first_screenshot=True)
timeout = 5
accept_button_timer = Timer(timeout)
self.interval_timer[MISSION_OVERVIEW_ACCEPT_SINGLE.name] = accept_button_timer
self.interval_timer[MISSION_OVERVIEW_ACCEPT.name] = accept_button_timer
# MISSION_OVERVIEW_CHECK
confirm_timer = Timer(1, count=3).start()
success = True
for _ in self.loop():
if self.handle_manjuu():
confirm_timer.reset()
continue
# End
if self.appear(MISSION_OVERVIEW_EMPTY, offset=(20, 20)):
success = True
break
if self.info_bar_count():
logger.info('Unable to accept missions, because reached the maximum number of missions')
success = False
break
if self.appear_then_click(MISSION_OVERVIEW_ACCEPT, offset=(20, 20), interval=0.2):
confirm_timer.reset()
if self.handle_manjuu():
continue
else:
# End
if confirm_timer.reached():
success = True
break
if self.appear_then_click(MISSION_OVERVIEW_ACCEPT_SINGLE, offset=(20, 20), interval=0.2):
confirm_timer.reset()
# Click
if self.appear_then_click(MISSION_OVERVIEW_ACCEPT, offset=(20, 20), interval=timeout):
continue
if self.appear_then_click(MISSION_OVERVIEW_ACCEPT_SINGLE, offset=(20, 20), interval=timeout):
continue
# is_in_globe

View File

@ -11,13 +11,20 @@ PORT_CHECK = PORT_GOTO_SUPPLY
class PortHandler(OSShop):
def port_enter(self, skip_first_screenshot=True):
def port_enter(self):
"""
Pages:
in: IN_MAP
out: PORT_CHECK
"""
self.ui_click(PORT_ENTER, check_button=PORT_CHECK, skip_first_screenshot=skip_first_screenshot)
logger.info('Port enter')
for _ in self.loop():
if self.appear(PORT_CHECK, offset=(20, 20)):
break
if self.appear_then_click(PORT_ENTER, offset=(20, 20), interval=5):
continue
if self.handle_map_event():
continue
# Buttons at the bottom has an animation to show
pass # Already ensured in ui_click
@ -27,6 +34,7 @@ class PortHandler(OSShop):
in: PORT_CHECK
out: IN_MAP
"""
logger.info('Port quit')
self.ui_back(appear_button=PORT_CHECK, check_button=self.is_in_map,
skip_first_screenshot=skip_first_screenshot)
# Buttons at the bottom has an animation to show

View File

@ -68,6 +68,7 @@ KUYBYSHEY_RAID_HARD = Button(area={'cn': (1073, 345, 1125, 371), 'en': (1074, 34
KUYBYSHEY_RAID_NORMAL = Button(area={'cn': (1045, 423, 1097, 451), 'en': (1036, 424, 1099, 449), 'jp': (1048, 427, 1091, 448), 'tw': (1044, 423, 1096, 452)}, color={'cn': (86, 95, 109), 'en': (81, 92, 105), 'jp': (131, 143, 154), 'tw': (86, 95, 109)}, button={'cn': (1045, 423, 1097, 451), 'en': (1036, 424, 1099, 449), 'jp': (1048, 427, 1091, 448), 'tw': (1044, 423, 1096, 452)}, file={'cn': './assets/cn/raid/KUYBYSHEY_RAID_NORMAL.png', 'en': './assets/en/raid/KUYBYSHEY_RAID_NORMAL.png', 'jp': './assets/jp/raid/KUYBYSHEY_RAID_NORMAL.png', 'tw': './assets/tw/raid/KUYBYSHEY_RAID_NORMAL.png'})
RAID_FLEET_PREPARATION = Button(area={'cn': (983, 577, 1181, 638), 'en': (1041, 592, 1121, 631), 'jp': (983, 579, 1180, 635), 'tw': (983, 577, 1181, 638)}, color={'cn': (236, 188, 115), 'en': (236, 184, 117), 'jp': (235, 183, 103), 'tw': (236, 188, 115)}, button={'cn': (983, 577, 1181, 638), 'en': (1041, 592, 1121, 631), 'jp': (983, 579, 1180, 635), 'tw': (983, 577, 1181, 638)}, file={'cn': './assets/cn/raid/RAID_FLEET_PREPARATION.png', 'en': './assets/en/raid/RAID_FLEET_PREPARATION.png', 'jp': './assets/jp/raid/RAID_FLEET_PREPARATION.png', 'tw': './assets/tw/raid/RAID_FLEET_PREPARATION.png'})
RAID_REWARDS = Button(area={'cn': (836, 127, 900, 169), 'en': (836, 127, 900, 169), 'jp': (836, 127, 900, 169), 'tw': (836, 127, 900, 169)}, color={'cn': (217, 103, 98), 'en': (217, 103, 98), 'jp': (217, 103, 98), 'tw': (217, 103, 98)}, button={'cn': (836, 127, 900, 169), 'en': (836, 127, 900, 169), 'jp': (836, 127, 900, 169), 'tw': (836, 127, 900, 169)}, file={'cn': './assets/cn/raid/RAID_REWARDS.png', 'en': './assets/en/raid/RAID_REWARDS.png', 'jp': './assets/jp/raid/RAID_REWARDS.png', 'tw': './assets/tw/raid/RAID_REWARDS.png'})
RPG_BACK = Button(area={'cn': (40, 30, 59, 57), 'en': (40, 30, 59, 57), 'jp': (40, 30, 59, 57), 'tw': (40, 30, 59, 57)}, color={'cn': (154, 127, 105), 'en': (154, 127, 105), 'jp': (154, 127, 105), 'tw': (154, 127, 105)}, button={'cn': (40, 30, 59, 57), 'en': (40, 30, 59, 57), 'jp': (40, 30, 59, 57), 'tw': (40, 30, 59, 57)}, file={'cn': './assets/cn/raid/RPG_BACK.png', 'en': './assets/en/raid/RPG_BACK.png', 'jp': './assets/jp/raid/RPG_BACK.png', 'tw': './assets/tw/raid/RPG_BACK.png'})
RPG_GOTO_STAGE = Button(area={'cn': (55, 495, 80, 520), 'en': (55, 495, 80, 520), 'jp': (55, 495, 80, 520), 'tw': (55, 495, 80, 520)}, color={'cn': (174, 168, 160), 'en': (174, 168, 160), 'jp': (174, 168, 160), 'tw': (174, 168, 160)}, button={'cn': (55, 495, 80, 520), 'en': (55, 495, 80, 520), 'jp': (55, 495, 80, 520), 'tw': (55, 495, 80, 520)}, file={'cn': './assets/cn/raid/RPG_GOTO_STAGE.png', 'en': './assets/en/raid/RPG_GOTO_STAGE.png', 'jp': './assets/jp/raid/RPG_GOTO_STAGE.png', 'tw': './assets/tw/raid/RPG_GOTO_STAGE.png'})
RPG_GOTO_STORY = Button(area={'cn': (59, 491, 84, 516), 'en': (59, 491, 84, 516), 'jp': (59, 491, 84, 516), 'tw': (59, 491, 84, 516)}, color={'cn': (182, 122, 105), 'en': (182, 122, 105), 'jp': (182, 122, 105), 'tw': (182, 122, 105)}, button={'cn': (59, 491, 84, 516), 'en': (59, 491, 84, 516), 'jp': (59, 491, 84, 516), 'tw': (59, 491, 84, 516)}, file={'cn': './assets/cn/raid/RPG_GOTO_STORY.png', 'en': './assets/en/raid/RPG_GOTO_STORY.png', 'jp': './assets/jp/raid/RPG_GOTO_STORY.png', 'tw': './assets/tw/raid/RPG_GOTO_STORY.png'})
RPG_HOME = Button(area={'cn': (1222, 29, 1240, 51), 'en': (1222, 29, 1240, 51), 'jp': (1222, 29, 1240, 51), 'tw': (1222, 29, 1240, 51)}, color={'cn': (197, 181, 158), 'en': (197, 181, 158), 'jp': (197, 181, 158), 'tw': (197, 181, 158)}, button={'cn': (1222, 29, 1240, 51), 'en': (1222, 29, 1240, 51), 'jp': (1222, 29, 1240, 51), 'tw': (1222, 29, 1240, 51)}, file={'cn': './assets/cn/raid/RPG_HOME.png', 'en': './assets/en/raid/RPG_HOME.png', 'jp': './assets/jp/raid/RPG_HOME.png', 'tw': './assets/tw/raid/RPG_HOME.png'})

View File

@ -2,11 +2,10 @@ import cv2
import numpy as np
import module.config.server as server
from module.base.decorator import run_once
from module.base.timer import Timer
from module.campaign.campaign_event import CampaignEvent
from module.combat.assets import *
from module.exception import OilExhausted, ScriptError
from module.exception import ScriptError
from module.logger import logger
from module.map.map_operation import MapOperation
from module.ocr.ocr import Digit, DigitCounter
@ -190,6 +189,41 @@ def pt_ocr(raid):
class Raid(MapOperation, RaidCombat, CampaignEvent):
@property
def _raid_has_oil_icon(self):
"""
Game devs are too asshole to drop oil display for UI design
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/5214
"""
if self.config.Campaign_Event == 'raid_20240328':
return False
return True
def triggered_stop_condition(self, oil_check=False, pt_check=False, coin_check=False):
"""
Returns:
bool: If triggered a stop condition.
"""
# Oil limit
if oil_check:
if self.get_oil() < max(500, self.config.StopCondition_OilLimit):
logger.hr('Triggered stop condition: Oil limit')
self.config.task_delay(minute=(120, 240))
return True
# Event limit
if pt_check:
if self.event_pt_limit_triggered():
logger.hr('Triggered stop condition: Event PT limit')
return True
# TaskBalancer
if coin_check:
if self.config.TaskBalancer_Enable and self.triggered_task_balancer():
logger.hr('Triggered stop condition: Coin limit')
self.handle_task_balancer()
return True
return False
def combat_preparation(self, balance_hp=False, emotion_reduce=False, auto='combat_auto', fleet_index=1):
"""
Args:
@ -199,32 +233,17 @@ class Raid(MapOperation, RaidCombat, CampaignEvent):
fleet_index (int):
"""
logger.info('Combat preparation.')
skip_first_screenshot = True
# No need, already waited in `raid_execute_once()`
# if emotion_reduce:
# self.emotion.wait(fleet_index)
@run_once
def check_oil():
if self.get_oil() < max(500, self.config.StopCondition_OilLimit):
logger.hr('Triggered oil limit')
raise OilExhausted
@run_once
def check_coin():
if self.config.TaskBalancer_Enable and self.triggered_task_balancer():
logger.hr('Triggered stop condition: Coin limit')
self.handle_task_balancer()
return True
for _ in self.loop():
if self.appear(BATTLE_PREPARATION, offset=(30, 20)):
if self.handle_combat_automation_set(auto=auto == 'combat_auto'):
continue
check_oil()
check_coin()
if self._raid_has_oil_icon and self.triggered_stop_condition(oil_check=True, coin_check=True):
self.config.task_stop()
if self.handle_raid_ticket_use():
continue
if self.handle_retirement():
@ -281,7 +300,7 @@ class Raid(MapOperation, RaidCombat, CampaignEvent):
if self.appear(entrance, offset=(10, 10), interval=5):
# Items appear from right
# Check PT when entrance appear
if self.event_pt_limit_triggered():
if self.triggered_stop_condition(pt_check=True):
self.config.task_stop()
self.device.click(entrance)
continue

View File

@ -1,17 +1,17 @@
from module.base.timer import Timer
from module.campaign.campaign_event import CampaignEvent
from module.exception import OilExhausted, ScriptEnd, ScriptError
from module.exception import ScriptEnd, ScriptError
from module.logger import logger
from module.raid.assets import RAID_REWARDS
from module.raid.raid import Raid, raid_ocr
from module.ui.page import page_raid, page_rpg_stage
from module.ui.page import page_campaign_menu, page_raid, page_rpg_stage
class RaidRun(Raid, CampaignEvent):
run_count: int
run_limit: int
def triggered_stop_condition(self):
def triggered_stop_condition(self, oil_check=False, pt_check=False, coin_check=False):
"""
Returns:
bool: If triggered a stop condition.
@ -23,7 +23,7 @@ class RaidRun(Raid, CampaignEvent):
self.config.Scheduler_Enable = False
return True
return False
return super().triggered_stop_condition(oil_check=oil_check, pt_check=pt_check, coin_check=coin_check)
def get_remain(self, mode, skip_first_screenshot=True):
"""
@ -93,9 +93,11 @@ class RaidRun(Raid, CampaignEvent):
else:
logger.info(f'Count: {self.run_count}')
# End
if self.triggered_stop_condition():
break
# UI switches
if not self._raid_has_oil_icon:
self.ui_goto(page_campaign_menu)
if self.triggered_stop_condition(oil_check=True, coin_check=True):
break
# UI ensure
self.device.stuck_record_clear()
@ -105,6 +107,7 @@ class RaidRun(Raid, CampaignEvent):
else:
self.ui_ensure(page_rpg_stage)
self.raid_rpg_swipe()
self.disable_event_on_raid()
# End for mode EX
if mode == 'ex':
@ -122,10 +125,6 @@ class RaidRun(Raid, CampaignEvent):
self.device.click_record_clear()
try:
self.raid_execute_once(mode=mode, raid=name)
except OilExhausted:
logger.hr('Triggered stop condition: Oil limit')
self.config.task_delay(minute=(120, 240))
break
except ScriptEnd as e:
logger.hr('Script end')
logger.info(str(e))

View File

@ -328,8 +328,10 @@ page_rpg_stage = Page(RPG_GOTO_STORY)
page_rpg_story = Page(RPG_GOTO_STAGE)
page_rpg_stage.link(button=RPG_GOTO_STORY, destination=page_rpg_story)
page_rpg_stage.link(button=RPG_HOME, destination=page_main)
page_rpg_stage.link(button=RPG_BACK, destination=page_campaign_menu)
page_rpg_story.link(button=RPG_GOTO_STAGE, destination=page_rpg_stage)
page_rpg_story.link(button=RPG_HOME, destination=page_main)
page_rpg_story.link(button=RPG_BACK, destination=page_campaign_menu)
page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_rpg_stage)
# page_main.link(button=MAIN_GOTO_RAID, destination=page_rpg_stage)

View File

@ -559,13 +559,14 @@ class UI(InfoHandler):
# if self.appear_then_click(HOSPITAL_BATTLE_EXIT, offset=(20, 20), interval=2):
# return True
# Neon city (coalition_20250626)
# if self.appear(NEONCITY_FLEET_PREPARATION, offset=(20, 20), interval=3):
# logger.info(f'{NEONCITY_FLEET_PREPARATION} -> {NEONCITY_PREPARATION_EXIT}')
# self.device.click(NEONCITY_PREPARATION_EXIT)
# return True
# DATE A LANE (coalition_20251120)
if self.appear_then_click(DAL_DIFFICULTY_EXIT, offset=(20, 20), interval=3):
# FASHION (coalition_20260122) reuse NEONCITY
if self.appear(NEONCITY_FLEET_PREPARATION, offset=(20, 20), interval=3):
logger.info(f'{NEONCITY_FLEET_PREPARATION} -> {NEONCITY_PREPARATION_EXIT}')
self.device.click(NEONCITY_PREPARATION_EXIT)
return True
# DATE A LANE (coalition_20251120)
# if self.appear_then_click(DAL_DIFFICULTY_EXIT, offset=(20, 20), interval=3):
# return True
# Idle page
if self.handle_idle_page():

View File

@ -30,6 +30,7 @@ TEMPLATE_NORTHERN_OVERTURE = Template(file={'cn': './assets/cn/war_archives/TEMP
TEMPLATE_PARALLEL_SUPERIMPOSITION = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png', 'en': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png', 'jp': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png', 'tw': './assets/cn/war_archives/TEMPLATE_PARALLEL_SUPERIMPOSITION.png'})
TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png', 'en': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png', 'jp': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png', 'tw': './assets/cn/war_archives/TEMPLATE_PLEDGE_OF_THE_RADIANT_COURT.png'})
TEMPLATE_PRELUDE_UNDER_THE_MOON = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png', 'en': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png', 'jp': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png', 'tw': './assets/cn/war_archives/TEMPLATE_PRELUDE_UNDER_THE_MOON.png'})
TEMPLATE_REVELATIONS_OF_DUST = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_REVELATIONS_OF_DUST.png', 'en': './assets/cn/war_archives/TEMPLATE_REVELATIONS_OF_DUST.png', 'jp': './assets/cn/war_archives/TEMPLATE_REVELATIONS_OF_DUST.png', 'tw': './assets/cn/war_archives/TEMPLATE_REVELATIONS_OF_DUST.png'})
TEMPLATE_RONDO_AT_RAINBOWS_END = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_RONDO_AT_RAINBOWS_END.png', 'en': './assets/en/war_archives/TEMPLATE_RONDO_AT_RAINBOWS_END.png', 'jp': './assets/cn/war_archives/TEMPLATE_RONDO_AT_RAINBOWS_END.png', 'tw': './assets/cn/war_archives/TEMPLATE_RONDO_AT_RAINBOWS_END.png'})
TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD.png', 'en': './assets/en/war_archives/TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD.png', 'jp': './assets/cn/war_archives/TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD.png', 'tw': './assets/cn/war_archives/TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD.png'})
TEMPLATE_SKYBOUND_ORATORIO = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_SKYBOUND_ORATORIO.png', 'en': './assets/en/war_archives/TEMPLATE_SKYBOUND_ORATORIO.png', 'jp': './assets/cn/war_archives/TEMPLATE_SKYBOUND_ORATORIO.png', 'tw': './assets/cn/war_archives/TEMPLATE_SKYBOUND_ORATORIO.png'})

View File

@ -44,4 +44,5 @@ dic_archives_template = {
'war_archives_20231026_cn': TEMPLATE_TEMPESTA_AND_THE_FOUNTAIN_OF_YOUTH,
'war_archives_20220915_cn': TEMPLATE_VIOLET_TEMPEST_BLOOMING_LYCORIS,
'war_archives_20221222_cn': TEMPLATE_PARALLEL_SUPERIMPOSITION,
'war_archives_20230223_cn': TEMPLATE_REVELATIONS_OF_DUST,
}