1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-14 11:59:24 +08:00

Merge branch 'Lme/master' into dev

# Conflicts:
#	README.md
#	module/config/argument/args.json
This commit is contained in:
0O0o0oOoO00
2025-09-13 23:04:25 +08:00
115 changed files with 1431 additions and 189 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -257,3 +257,4 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
| 20250814 | event 20250814 cn | Secrets of the Abyss | 奇渊下的秘密 | Secrets of the Abyss | 淵層界の秘密 | - |
| 20250821 | event 20220224 cn | Abyssal Refrain | - | - | - | 復刻深度回音 |
| 20250828 | event 20250814 cn | Secrets of the Abyss | - | - | - | 奇淵下的秘密 |
| 20250912 | event 20250912 cn | A Dance for Amahara Above | 起舞于天原之上 | A Dance for Amahara Above | アマハラに舞い奉れ | - |

View File

@@ -0,0 +1,95 @@
from .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 = 'I8'
MAP.camera_data = ['D2', 'D6', 'F2', 'F6']
MAP.camera_data_spawn_point = ['D2']
MAP.map_data = """
-- ++ -- SP -- SP ++ ++ ++
-- ++ Me -- __ -- Me -- Me
-- Me -- -- MS -- -- ME --
-- -- -- MS -- MS -- -- --
ME ME -- ++ ++ ++ ++ -- ++
++ ++ -- -- ME ++ ME -- ME
++ ++ -- -- -- -- -- 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
"""
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, 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 = []
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_CHAPTER_SWITCH_20241219 = True
STAGE_ENTRANCE = ['half', '20240725']
MAP_HAS_MODE_SWITCH = True
STAGE_INCREASE_AB = True
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 33),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
'height': (255 - 33, 255),
'prominence': 10,
'distance': 50,
'wlen': 1000
}
MAP_SIREN_HAS_BOSS_ICON_SMALL = True
MAP_SWIPE_MULTIPLY = (1.212, 1.235)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.172, 1.194)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.138, 1.158)
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,79 @@
from .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 = 'I8'
MAP.camera_data = ['D2', 'F2', 'E6']
MAP.camera_data_spawn_point = ['D2']
MAP.map_data = """
-- SP ++ -- ME -- ME ++ --
SP -- -- MS -- -- -- ME --
++ -- MS -- ++ ++ ME -- ME
-- MS -- __ MB ++ ++ -- ++
-- Me -- Me -- ME -- -- 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
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 = []
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.224, 1.247)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.184, 1.206)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.149, 1.170)
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_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 = 'J8'
MAP.camera_data = ['D2', 'D6', 'G2', 'G6']
MAP.camera_data_spawn_point = ['D4']
MAP.map_data = """
-- -- ++ ++ ++ ME -- ME -- --
-- Me -- Me -- ME -- ++ ++ --
-- -- MS -- -- -- -- MB ++ ME
SP -- -- MS ++ Me __ -- ME --
SP -- -- MS ++ ME -- -- -- --
-- -- 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 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, 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 = []
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.127, 1.148)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.090, 1.110)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.058, 1.077)
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,97 @@
from .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 = 'J8'
MAP.camera_data = ['E3', 'E6', 'G3', 'G6']
MAP.camera_data_spawn_point = ['E6']
MAP.map_data = """
-- -- ++ ++ ++ Me -- ++ -- --
-- MB -- -- Me -- -- -- ME --
++ ++ -- Me -- -- -- ME -- --
++ ++ -- ++ ME __ ME ++ ++ --
-- -- MS -- MS -- -- ME ++ ME
-- Me -- MS -- 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
"""
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, 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:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_CHAPTER_SWITCH_20241219 = True
STAGE_ENTRANCE = ['half', '20240725']
MAP_HAS_MODE_SWITCH = True
STAGE_INCREASE_AB = True
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 17),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
'height': (255 - 17, 255),
'prominence': 10,
'distance': 50,
'wlen': 1000
}
HOMO_EDGE_COLOR_RANGE = (0, 17)
MAP_WALK_USE_CURRENT_FLEET = True
MAP_SWIPE_MULTIPLY = (1.078, 1.099)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.043, 1.062)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.013, 1.031)
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_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 = ['E2', 'E6', 'G4']
MAP.camera_data_spawn_point = ['G6']
MAP.map_data = """
++ -- ME ++ -- ++ ++ ++ -- --
-- ++ -- -- ME -- MB -- -- --
-- ME -- ME ++ ME -- ME ++ ++
-- ME -- -- Me -- __ -- ME ++
++ ++ ME -- -- MS -- MS -- Me
++ ++ -- -- Me -- MS -- Me --
-- ME -- Me ++ -- -- -- ++ --
-- -- 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 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 = ['BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.086, 1.106)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.050, 1.069)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.019, 1.038)
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,84 @@
from .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 = 'K9'
MAP.camera_data = ['F2', 'F5', 'F7', 'D5']
MAP.camera_data_spawn_point = ['I5']
MAP.map_data = """
-- -- ++ -- -- ME -- ME -- ++ --
-- ++ ++ ME -- ++ ++ ++ -- -- ++
++ ++ ++ ME -- -- Me -- MS -- ++
-- -- ME -- -- Me ++ MS -- -- SP
MB -- -- -- -- -- -- -- -- __ --
-- -- ME -- -- Me ++ MS -- -- SP
++ ++ ++ ME -- -- Me -- MS -- ++
-- ++ ++ 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 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, K1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, K3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, K4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, K5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, K6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, K7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, K8, \
A9, B9, C9, D9, E9, F9, G9, H9, I9, J9, K9, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
HOMO_STORAGE = ((8, 6), [(137.405, 104.804), (1046.044, 104.804), (-12.171, 652.093), (1166.717, 652.093)])
MAP_SWIPE_MULTIPLY = (1.109, 1.130)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.073, 1.093)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.042, 1.060)
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,95 @@
from .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 = 'I8'
MAP.camera_data = ['D2', 'D6', 'F2', 'F6']
MAP.camera_data_spawn_point = ['D2']
MAP.map_data = """
-- ++ -- SP -- SP ++ ++ ++
-- ++ Me -- __ -- Me -- Me
-- Me -- -- MS -- -- ME --
-- -- -- MS -- MS -- -- --
ME ME -- ++ ++ ++ ++ -- ++
++ ++ -- -- ME ++ ME -- ME
++ ++ -- -- -- -- -- 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
"""
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, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
= MAP.flatten()
class Config:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = []
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_CHAPTER_SWITCH_20241219 = True
STAGE_ENTRANCE = ['half', '20240725']
MAP_HAS_MODE_SWITCH = True
STAGE_INCREASE_AB = True
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 33),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
'height': (255 - 33, 255),
'prominence': 10,
'distance': 50,
'wlen': 1000
}
MAP_SIREN_HAS_BOSS_ICON_SMALL = True
MAP_SWIPE_MULTIPLY = (1.212, 1.235)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.172, 1.194)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.138, 1.158)
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_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 = 'I8'
MAP.camera_data = ['D2', 'F2', 'E6']
MAP.camera_data_spawn_point = ['D2']
MAP.map_data = """
-- SP ++ -- ME -- ME ++ --
SP -- -- MS -- -- -- ME --
++ -- MS -- ++ ++ ME -- ME
-- MS -- __ MB ++ ++ -- ++
-- Me -- Me -- ME -- -- 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
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, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = []
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.224, 1.247)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.184, 1.206)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.149, 1.170)
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_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 = 'J8'
MAP.camera_data = ['D2', 'D6', 'G2', 'G6']
MAP.camera_data_spawn_point = ['D4']
MAP.map_data = """
-- -- ++ ++ ++ ME -- ME -- --
-- Me -- Me -- ME -- ++ ++ --
-- -- MS -- -- -- -- MB ++ ME
SP -- -- MS ++ Me __ -- ME --
SP -- -- MS ++ ME -- -- -- --
-- -- 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 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, 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 = []
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.127, 1.148)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.090, 1.110)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.058, 1.077)
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,11 @@
from module.ui.page import page_event
from module.campaign.campaign_base import CampaignBase as CampaignBase_
class CampaignBase(CampaignBase_):
def handle_exp_info(self):
# Random background hits EXP_INFO_B
if self.ui_page_appear(page_event):
return False
return super().handle_exp_info()

View File

@@ -0,0 +1,97 @@
from .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 = 'J8'
MAP.camera_data = ['E3', 'E6', 'G3', 'G6']
MAP.camera_data_spawn_point = ['E6']
MAP.map_data = """
-- -- ++ ++ ++ Me -- ++ -- --
-- MB -- -- Me -- -- -- ME --
++ ++ -- Me -- -- -- ME -- --
++ ++ -- ++ ME __ ME ++ ++ --
-- -- MS -- MS -- -- ME ++ ME
-- Me -- MS -- 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
"""
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, \
= MAP.flatten()
class Config:
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_CHAPTER_SWITCH_20241219 = True
STAGE_ENTRANCE = ['half', '20240725']
MAP_HAS_MODE_SWITCH = True
STAGE_INCREASE_AB = True
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 17),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
'height': (255 - 17, 255),
'prominence': 10,
'distance': 50,
'wlen': 1000
}
HOMO_EDGE_COLOR_RANGE = (0, 17)
MAP_WALK_USE_CURRENT_FLEET = True
MAP_SWIPE_MULTIPLY = (1.078, 1.099)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.043, 1.062)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.013, 1.031)
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_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 = ['E2', 'E6', 'G4']
MAP.camera_data_spawn_point = ['G6']
MAP.map_data = """
++ -- ME ++ -- ++ ++ ++ -- --
-- ++ -- -- ME -- MB -- -- --
-- ME -- ME ++ ME -- ME ++ ++
-- ME -- -- Me -- __ -- ME ++
++ ++ ME -- -- MS -- MS -- Me
++ ++ -- -- Me -- MS -- Me --
-- ME -- Me ++ -- -- -- ++ --
-- -- 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 20 50 10 10 10 50 50
50 50 50 20 10 10 10 10 10 50
50 50 20 20 10 10 10 10 10 20
50 50 50 20 10 10 05 10 10 20
50 50 50 20 50 10 10 10 50 50
50 50 50 50 50 10 10 10 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 = ['BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
MAP_SWIPE_MULTIPLY = (1.086, 1.106)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.050, 1.069)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.019, 1.038)
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,93 @@
from .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 = 'K9'
MAP.camera_data = ['F2', 'F5', 'F7', 'D5']
MAP.camera_data_spawn_point = ['I5']
MAP.map_data = """
-- -- ++ -- -- ME -- ME -- ++ --
-- ++ ++ ME -- ++ ++ ++ -- -- ++
++ ++ ++ ME -- -- Me -- MS -- ++
-- -- ME -- -- Me ++ MS -- -- SP
MB -- -- -- -- -- -- -- -- __ --
-- -- ME -- -- Me ++ MS -- -- SP
++ ++ ++ ME -- -- Me -- MS -- ++
-- ++ ++ 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 10 10 10 10 10 10
50 50 50 50 50 10 10 10 10 10 10
50 50 50 50 50 10 10 10 10 10 10
50 50 50 50 50 10 10 10 10 10 10
50 50 50 50 50 10 10 10 10 10 10
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, K1, \
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, \
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, K3, \
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, K4, \
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, K5, \
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, K6, \
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, K7, \
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, K8, \
A9, B9, C9, D9, E9, F9, G9, H9, I9, J9, K9, \
= MAP.flatten()
class Config(ConfigBase):
# ===== Start of generated config =====
MAP_SIREN_TEMPLATE = ['BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
# ===== End of generated config =====
HOMO_STORAGE = ((8, 6), [(137.405, 104.804), (1046.044, 104.804), (-12.171, 652.093), (1166.717, 652.093)])
MAP_SWIPE_MULTIPLY = (1.109, 1.130)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.073, 1.093)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.042, 1.060)
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,127 @@
from module.campaign.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('SP')
MAP.shape = 'I8'
MAP.camera_data = ['D4', 'F4']
MAP.camera_data_spawn_point = ['F4']
MAP.map_data = """
-- -- ++ ++ -- ++ ++ -- --
-- -- ++ ++ MB ++ ++ -- --
-- -- ME MS -- MS ME -- --
++ ME -- -- 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 10 10 10 50 50 50
50 50 50 10 10 10 50 50 50
50 50 50 10 10 10 50 50 50
50 50 50 50 50 10 50 50 50
50 50 50 50 50 50 50 50 50
"""
MAP.spawn_data = [
{'battle': 0, 'enemy': 8, 'siren': 3},
{'battle': 1},
{'battle': 2},
{'battle': 3},
{'battle': 4},
{'battle': 5},
{'battle': 6},
{'battle': 7, '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 = ['BlackDragonBoss01', 'BlackDragonBoss02']
MOVABLE_ENEMY_TURN = (2,)
MAP_HAS_SIREN = True
MAP_HAS_MOVABLE_ENEMY = True
MAP_HAS_MAP_STORY = False
MAP_HAS_FLEET_STEP = True
MAP_HAS_AMBUSH = False
MAP_HAS_MYSTERY = False
STAR_REQUIRE_1 = 0
STAR_REQUIRE_2 = 0
STAR_REQUIRE_3 = 0
# ===== End of generated config =====
MAP_CHAPTER_SWITCH_20241219 = True
STAGE_ENTRANCE = ['half', '20240725']
STAGE_INCREASE_AB = True
MAP_IS_ONE_TIME_STAGE = True
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
'height': (80, 255 - 17),
'width': (0.9, 10),
'prominence': 10,
'distance': 35,
}
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
'height': (255 - 17, 255),
'prominence': 10,
'distance': 50,
'wlen': 1000
}
HOMO_EDGE_COLOR_RANGE = (0, 17)
MAP_WALK_USE_CURRENT_FLEET = True
MAP_SWIPE_MULTIPLY = (1.096, 1.117)
MAP_SWIPE_MULTIPLY_MINITOUCH = (1.060, 1.080)
MAP_SWIPE_MULTIPLY_MAATOUCH = (1.029, 1.048)
class Campaign(CampaignBase):
MAP = MAP
ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C'
def map_data_init(self, map_):
super().map_data_init(map_)
# enemy
B4.is_enemy = True
B5.is_enemy = True
C3.is_enemy = True
C6.is_enemy = True
G3.is_enemy = True
G6.is_enemy = True
H4.is_enemy = True
H5.is_enemy = True
# siren
D3.is_siren = True
E4.is_siren = True
F3.is_siren = True
def battle_0(self):
if self.clear_siren():
return True
if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=2):
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_7(self):
return self.fleet_boss.clear_boss()

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -20,7 +20,6 @@ class ConfigModel:
GitProxy: Optional[str] = None
SSLVerify: bool = False
AutoUpdate: bool = True
KeepLocalChanges: bool = False
# Python
PythonExecutable: str = "./toolkit/python.exe"

View File

@@ -52,8 +52,7 @@ class GitManager(DeployConfig):
return conf
def git_repository_init(
self, repo, source='origin', branch='master',
proxy='', ssl_verify=True, keep_changes=False
self, repo, source='origin', branch='master', proxy='', ssl_verify=True
):
logger.hr('Git Init', 1)
if not self.execute(f'"{self.git}" init', allow_failure=True):
@@ -104,19 +103,6 @@ class GitManager(DeployConfig):
if os.path.exists(lock_file):
logger.info(f'Lock file {lock_file} exists, removing')
os.remove(lock_file)
if keep_changes:
if self.execute(f'"{self.git}" stash', allow_failure=True):
self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
if self.execute(f'"{self.git}" stash pop', allow_failure=True):
pass
else:
# No local changes to existing files, untracked files not included
logger.info('Stash pop failed, there seems to be no local changes, skip instead')
else:
logger.info('Stash failed, this may be the first installation, drop changes instead')
self.execute(f'"{self.git}" reset --hard {source}/{branch}')
self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
else:
self.execute(f'"{self.git}" reset --hard {source}/{branch}')
Progress.GitReset()
# Since `git fetch` is already called, checkout is faster
@@ -149,7 +135,7 @@ class GitManager(DeployConfig):
return
if self.GitOverCdn:
if self.goc_client.update(keep_changes=self.KeepLocalChanges):
if self.goc_client.update():
return
self.git_repository_init(
@@ -158,5 +144,4 @@ class GitManager(DeployConfig):
branch=self.Branch,
proxy=self.GitProxy,
ssl_verify=self.SSLVerify,
keep_changes=self.KeepLocalChanges,
)

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -17,7 +17,6 @@ class ConfigModel:
GitProxy: Optional[str] = None
SSLVerify: bool = False
AutoUpdate: bool = True
KeepLocalChanges: bool = False
# Python
PythonExecutable: str = "./toolkit/python.exe"

View File

@@ -23,8 +23,7 @@ class GitManager(DeployConfig):
logger.info(f'File not found: {file}')
def git_repository_init(
self, repo, source='origin', branch='master',
proxy='', ssl_verify=True, keep_changes=False
self, repo, source='origin', branch='master', proxy='', ssl_verify=True
):
logger.hr('Git Init', 1)
if not self.execute(f'"{self.git}" init', allow_failure=True):
@@ -63,19 +62,6 @@ class GitManager(DeployConfig):
if os.path.exists(lock_file):
logger.info(f'Lock file {lock_file} exists, removing')
os.remove(lock_file)
if keep_changes:
if self.execute(f'"{self.git}" stash', allow_failure=True):
self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
if self.execute(f'"{self.git}" stash pop', allow_failure=True):
pass
else:
# No local changes to existing files, untracked files not included
logger.info('Stash pop failed, there seems to be no local changes, skip instead')
else:
logger.info('Stash failed, this may be the first installation, drop changes instead')
self.execute(f'"{self.git}" reset --hard {source}/{branch}')
self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
else:
self.execute(f'"{self.git}" reset --hard {source}/{branch}')
self.execute(f'"{self.git}" pull --ff-only {source} {branch}')
@@ -102,7 +88,7 @@ class GitManager(DeployConfig):
return
if self.GitOverCdn:
if self.goc_client.update(keep_changes=self.KeepLocalChanges):
if self.goc_client.update():
return
self.git_repository_init(
@@ -111,7 +97,6 @@ class GitManager(DeployConfig):
branch=self.Branch,
proxy=self.GitProxy,
ssl_verify=self.SSLVerify,
keep_changes=self.KeepLocalChanges,
)

View File

@@ -204,7 +204,7 @@ class GitOverCdnClient:
self.logger.warning(f'TimeoutExpired when calling {cmd}, stdout={stdout}, stderr={stderr}')
return stdout.decode()
def git_reset(self, keep_changes=False):
def git_reset(self):
"""
git reset --hard <commit>
"""
@@ -217,11 +217,6 @@ class GitOverCdnClient:
if os.path.exists(lock_file):
self.logger.info(f'Lock file {lock_file} exists, removing')
os.remove(lock_file)
if keep_changes:
self.git_command('stash')
self.git_command('reset', '--hard', f'{self.source}/{self.branch}')
self.git_command('stash', 'pop')
else:
self.git_command('reset', '--hard', f'{self.source}/{self.branch}')
def get_status(self):
@@ -245,11 +240,8 @@ class GitOverCdnClient:
self.logger.info('Current repo is behind remote')
return 'behind'
def update(self, keep_changes=False):
def update(self):
"""
Args:
keep_changes:
Returns:
bool: If repo is up-to-date
"""
@@ -263,13 +255,13 @@ class GitOverCdnClient:
return False
if self.current_commit == self.latest_commit:
self.logger.info('Already up to date')
self.git_reset(keep_changes=keep_changes)
self.git_reset()
return True
if not self.download_pack():
return False
if not self.update_refs():
return False
self.git_reset(keep_changes=keep_changes)
self.git_reset()
self.logger.info('Update success')
return True

View File

@@ -23,11 +23,6 @@ Deploy:
# Update Alas at startup
# [In most cases] Use true
AutoUpdate: true
# Whether to keep local changes during update
# User settings, logs and screenshots will be kept, no mather this is true or false
# [Developer] Use true, if you modified the code
# [Other] Use false
KeepLocalChanges: false
Python:
# Filepath of python executable `python.exe`

View File

@@ -34,6 +34,9 @@ ASIDE_SWITCH_20241219.add_state('part1', CHAPTER_20241219_PART1)
ASIDE_SWITCH_20241219.add_state('part2', CHAPTER_20241219_PART2)
ASIDE_SWITCH_20241219.add_state('sp', CHAPTER_20241219_SP)
ASIDE_SWITCH_20241219.add_state('ex', CHAPTER_20241219_EX)
# shorten unknown_timer for faster hanlding
# because of game bug that aside indicator will be missing after campaign retreat or finish
ASIDE_SWITCH_20241219.set_unknown_timer = Timer(0.6, count=2)
def is_digit_chapter(chapter):

View File

@@ -337,7 +337,16 @@ class CampaignRun(CampaignEvent, ShopStatus):
# Convert campaign_main to campaign hard if mode is hard and file exists
if mode == 'hard' and folder == 'campaign_main' and name in map_files('campaign_hard'):
folder = 'campaign_hard'
# event_20240912_cn does not have "Threat: Safe" indicator, fallback MapAchievement
if folder == 'event_20240912_cn':
if self.config.StopCondition_MapAchievement == 'threat_safe':
logger.info(
'In event_20240912_cn, MapAchievement=threat_safe fallback to map_3_stars')
self.config.override(StopCondition_MapAchievement='map_3_stars')
if self.config.StopCondition_MapAchievement == 'threat_safe_without_3_stars':
logger.info(
'In event_20240912_cn, MapAchievement=threat_safe_without_3_stars fallback to 100_percent_clear')
self.config.override(StopCondition_MapAchievement='100_percent_clear')
return name, folder
def can_use_auto_search_continue(self):

View File

@@ -3780,10 +3780,12 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"display": "hide",
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -3849,6 +3851,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -3918,6 +3921,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -4127,7 +4131,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -7273,9 +7278,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -7341,6 +7348,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -7410,6 +7418,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -7619,7 +7628,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -8077,9 +8087,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -8145,6 +8157,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -8214,6 +8227,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -8423,7 +8437,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -8881,9 +8896,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -8949,6 +8966,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -9018,6 +9036,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -9227,7 +9246,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -9685,9 +9705,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -9753,6 +9775,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -9822,6 +9845,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -10031,7 +10055,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -10489,9 +10514,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -10557,6 +10584,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -10626,6 +10654,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -10835,7 +10864,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -11293,9 +11323,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -11361,6 +11393,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -11430,6 +11463,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -11639,7 +11673,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -13309,9 +13344,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -13377,6 +13414,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -13446,6 +13484,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -13655,7 +13694,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -14130,9 +14170,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -14198,6 +14240,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -14267,6 +14310,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -14476,7 +14520,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -14951,9 +14996,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -15019,6 +15066,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -15088,6 +15136,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -15297,7 +15346,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -15772,9 +15822,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -15840,6 +15892,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -15909,6 +15962,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -16118,7 +16172,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {
@@ -16583,9 +16638,11 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
],
"option_cn": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -16651,6 +16708,7 @@
"event_20200227_cn"
],
"option_en": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -16720,6 +16778,7 @@
"event_20200227_cn"
],
"option_jp": [
"event_20250912_cn",
"event_20250814_cn",
"event_20221124_cn",
"event_20250724_cn",
@@ -16929,7 +16988,8 @@
"event_20250424_cn",
"event_20250520_cn",
"event_20250724_cn",
"event_20250814_cn"
"event_20250814_cn",
"event_20250912_cn"
]
},
"Mode": {

View File

@@ -1132,6 +1132,7 @@
"event_20250520_cn": "A Rose on the High Tower",
"event_20250724_cn": "The Alchemist and the Tower of Horizons",
"event_20250814_cn": "Secrets of the Abyss",
"event_20250912_cn": "A Dance for Amahara Above",
"raid_20200624": "Air Raid Drills with Essex Rerun",
"raid_20210708": "Cross Wave rerun",
"raid_20220127": "Mystery Investigation",

View File

@@ -1132,6 +1132,7 @@
"event_20250520_cn": "高い塔の薔薇",
"event_20250724_cn": "錬金術士と天空邂逅の塔",
"event_20250814_cn": "淵層界の秘密",
"event_20250912_cn": "アマハラに舞い奉れ",
"raid_20200624": "特別演習超空強襲波(復刻)",
"raid_20210708": "交錯する新たな波 (復刻)",
"raid_20220127": "秘密事件調査",

View File

@@ -1132,6 +1132,7 @@
"event_20250520_cn": "高塔上的蔷薇",
"event_20250724_cn": "优米雅的炼金工房",
"event_20250814_cn": "奇渊下的秘密",
"event_20250912_cn": "起舞于天原之上",
"raid_20200624": "复刻特别演习埃塞克斯级",
"raid_20210708": "复刻穿越彼方的水线",
"raid_20220127": "演习神秘事件调查",

View File

@@ -1132,6 +1132,7 @@
"event_20250520_cn": "高塔上的薔薇",
"event_20250724_cn": "鍊金術士與天際交會之塔",
"event_20250814_cn": "奇淵下的秘密",
"event_20250912_cn": "A Dance for Amahara Above",
"raid_20200624": "特別演習埃塞克斯級(復刻)",
"raid_20210708": "復刻穿越彼方的水線",
"raid_20220127": "演習神秘事件調查",

View File

@@ -318,7 +318,8 @@ class Connection(ConnectionAttr):
# BlueStacks Air is the Mac version of BlueStacks
if not IS_MACINTOSH:
return False
if not self.is_ldplayer_bluestacks_family:
# 127.0.0.1:5555 + 10*n, assume 32 instances at max
if not (5555 <= self.port <= 5875):
return False
# [bst.installed_images]: [Tiramisu64]
# [bst.instance]: [Tiramisu64]

View File

@@ -78,9 +78,9 @@ class ConnectionAttr:
# 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
if ',' in serial:
left, _, right = serial.partition(',')
# 5555,16384 -> replaced to 5555.16384
if '.' in serial:
left, _, right = serial.partition('.')
if left.startswith('55') and right.startswith('16'):
serial = right
# 16384
@@ -165,7 +165,7 @@ class ConnectionAttr:
@cached_property
def is_mumu12_family(self):
# 127.0.0.1:16XXX
# 127.0.0.1:16384 + 32*n, assume 32 instances at max
return 16384 <= self.port <= 17408
@cached_property
@@ -177,7 +177,8 @@ class ConnectionAttr:
@cached_property
def is_ldplayer_bluestacks_family(self):
# Note that LDPlayer and BlueStacks have the same serial range
return self.serial.startswith('emulator-') or 5555 <= self.port <= 5587
# 127.0.0.1:5555 + 2*n, assume 32 instances at max
return self.serial.startswith('emulator-') or 5555 <= self.port <= 5619
@cached_property
def is_nox_family(self):

Some files were not shown because too many files have changed in this diff Show More