From d29f93c1c1e22d157c24f212329881c3b53f05b3 Mon Sep 17 00:00:00 2001 From: somegituser Date: Tue, 23 Jan 2024 14:05:05 +0800 Subject: [PATCH] add: wararchive Dreamwaker's Butterfly & Mirror Involution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增作战档案: 蝶海梦花&镜位螺旋 --- .../TEMPLATE_DREAMWAKERS_BUTTERFLY.png | Bin 0 -> 54064 bytes .../TEMPLATE_MIRROR_INVOLUTION.png | Bin 0 -> 35337 bytes campaign/Readme.md | 2 + .../war_archives_20200917_cn/campaign_base.py | 129 ++++++++++++++++++ campaign/war_archives_20200917_cn/ht1.py | 89 ++++++++++++ campaign/war_archives_20200917_cn/ht2.py | 84 ++++++++++++ campaign/war_archives_20200917_cn/ht3.py | 94 +++++++++++++ campaign/war_archives_20200917_cn/ht4.py | 111 +++++++++++++++ campaign/war_archives_20200917_cn/ht5.py | 105 ++++++++++++++ campaign/war_archives_20200917_cn/ht6.py | 109 +++++++++++++++ campaign/war_archives_20200917_cn/hts1.py | 86 ++++++++++++ campaign/war_archives_20200917_cn/hts2.py | 82 +++++++++++ campaign/war_archives_20200917_cn/t1.py | 86 ++++++++++++ campaign/war_archives_20200917_cn/t2.py | 96 +++++++++++++ campaign/war_archives_20200917_cn/t3.py | 105 ++++++++++++++ campaign/war_archives_20200917_cn/t4.py | 109 +++++++++++++++ campaign/war_archives_20200917_cn/t5.py | 106 ++++++++++++++ campaign/war_archives_20200917_cn/t6.py | 101 ++++++++++++++ campaign/war_archives_20200917_cn/ts1.py | 83 +++++++++++ campaign/war_archives_20200917_cn/ts2.py | 82 +++++++++++ campaign/war_archives_20210527_cn/a1.py | 70 ++++++++++ campaign/war_archives_20210527_cn/a2.py | 75 ++++++++++ campaign/war_archives_20210527_cn/a3.py | 75 ++++++++++ campaign/war_archives_20210527_cn/b1.py | 79 +++++++++++ campaign/war_archives_20210527_cn/b2.py | 76 +++++++++++ campaign/war_archives_20210527_cn/b3.py | 81 +++++++++++ campaign/war_archives_20210527_cn/c1.py | 77 +++++++++++ campaign/war_archives_20210527_cn/c2.py | 81 +++++++++++ campaign/war_archives_20210527_cn/c3.py | 82 +++++++++++ campaign/war_archives_20210527_cn/d1.py | 85 ++++++++++++ campaign/war_archives_20210527_cn/d2.py | 93 +++++++++++++ campaign/war_archives_20210527_cn/d3.py | 100 ++++++++++++++ module/campaign/run.py | 1 + module/config/argument/args.json | 14 +- module/config/i18n/en-US.json | 4 +- module/config/i18n/ja-JP.json | 4 +- module/config/i18n/zh-CN.json | 4 +- module/config/i18n/zh-TW.json | 4 +- module/war_archives/assets.py | 2 + module/war_archives/dictionary.py | 2 + 40 files changed, 2658 insertions(+), 10 deletions(-) create mode 100644 assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png create mode 100644 assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png create mode 100644 campaign/war_archives_20200917_cn/campaign_base.py create mode 100644 campaign/war_archives_20200917_cn/ht1.py create mode 100644 campaign/war_archives_20200917_cn/ht2.py create mode 100644 campaign/war_archives_20200917_cn/ht3.py create mode 100644 campaign/war_archives_20200917_cn/ht4.py create mode 100644 campaign/war_archives_20200917_cn/ht5.py create mode 100644 campaign/war_archives_20200917_cn/ht6.py create mode 100644 campaign/war_archives_20200917_cn/hts1.py create mode 100644 campaign/war_archives_20200917_cn/hts2.py create mode 100644 campaign/war_archives_20200917_cn/t1.py create mode 100644 campaign/war_archives_20200917_cn/t2.py create mode 100644 campaign/war_archives_20200917_cn/t3.py create mode 100644 campaign/war_archives_20200917_cn/t4.py create mode 100644 campaign/war_archives_20200917_cn/t5.py create mode 100644 campaign/war_archives_20200917_cn/t6.py create mode 100644 campaign/war_archives_20200917_cn/ts1.py create mode 100644 campaign/war_archives_20200917_cn/ts2.py create mode 100644 campaign/war_archives_20210527_cn/a1.py create mode 100644 campaign/war_archives_20210527_cn/a2.py create mode 100644 campaign/war_archives_20210527_cn/a3.py create mode 100644 campaign/war_archives_20210527_cn/b1.py create mode 100644 campaign/war_archives_20210527_cn/b2.py create mode 100644 campaign/war_archives_20210527_cn/b3.py create mode 100644 campaign/war_archives_20210527_cn/c1.py create mode 100644 campaign/war_archives_20210527_cn/c2.py create mode 100644 campaign/war_archives_20210527_cn/c3.py create mode 100644 campaign/war_archives_20210527_cn/d1.py create mode 100644 campaign/war_archives_20210527_cn/d2.py create mode 100644 campaign/war_archives_20210527_cn/d3.py diff --git a/assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png b/assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png new file mode 100644 index 0000000000000000000000000000000000000000..363ae71062f8453c1e3a642638a8c785b22337ac GIT binary patch literal 54064 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 literal 0 HcmV?d00001 diff --git a/assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png b/assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png new file mode 100644 index 0000000000000000000000000000000000000000..277834964feac64ecc44358652412b63945dd6bf GIT binary patch literal 35337 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 literal 0 HcmV?d00001 diff --git a/campaign/Readme.md b/campaign/Readme.md index 4adb53c05..71371a3ea 100644 --- a/campaign/Readme.md +++ b/campaign/Readme.md @@ -37,6 +37,8 @@ To add a new event, add a new row in here, and run `python -m module.config.conf | 20230420 | war archives 20220210 cn | Northern Overture | 北境序曲 | Northern Overture | 凍絶の北海 | 北境序曲 | | 20230511 | war archives 20220414 cn | Aurora Noctis | 永夜幻光 | Aurora Noctis | 極夜照らす幻光 | 永夜幻光 | | 20230831 | war archives 20201229 cn | Inverted Orthant | 负象限作战 | Inverted Orthant | 虚畳なりし限象 | - | +| 20240118 | war archives 20200917 cn | Dreamwaker's Butterfly | 蝶海梦花 | Dreamwaker's Butterfly | 刹那觀る胡蝶の夢 | - | +| 20240118 | war archives 20210527 cn | Mirror Involution | 镜位螺旋 | Mirror Involution | 照らす螺旋の鏡海 | - | | 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 | 闇靄払う銀翼 | - | diff --git a/campaign/war_archives_20200917_cn/campaign_base.py b/campaign/war_archives_20200917_cn/campaign_base.py new file mode 100644 index 000000000..97465d2d8 --- /dev/null +++ b/campaign/war_archives_20200917_cn/campaign_base.py @@ -0,0 +1,129 @@ +from module.base.button import Button +from module.base.utils import * +from ..campaign_war_archives.campaign_base import CampaignBase as CampaignBase_ +from module.exception import CampaignNameError +from module.logger import logger + +# Here manually type coordinates, because the ball appears in event Dreamwaker's Butterfly only. +BALL = Button(area=(571, 283, 696, 387), color=(), button=(597, 274, 671, 343)) + + +class CampaignBase(CampaignBase_): + STAGE_INCREASE = [ + 'TS1 > T1 > T2 > T3 > T4 > TS2 > T5 > T6', + 'HTS1 > HT1 > HT2 > HT3', + 'HT4 > HTS2 > HT5 > HT6', + ] + + def campaign_set_chapter(self, name, mode='normal'): + """ + Args: + name (str): Campaign name, such as '7-2', 'd3', 'sp3'. + mode (str): 'normal' or 'hard'. + """ + chapter, stage = self._campaign_separate_name(name) + name = chapter + stage + + if chapter.isdigit(): + self.ui_goto_campaign() + self.campaign_ensure_mode('normal') + self.campaign_ensure_chapter(index=chapter) + if mode == 'hard': + self.campaign_ensure_mode('hard') + + elif chapter in 'abcd' or chapter == 'ex_sp': + self.ui_goto_event() + if chapter in 'ab': + self.campaign_ensure_mode('normal') + elif chapter in 'cd': + self.campaign_ensure_mode('hard') + elif chapter == 'ex_sp': + self.campaign_ensure_mode('ex') + self.campaign_ensure_chapter(index=chapter) + + elif chapter == 'sp': + self.ui_goto_sp() + self.campaign_ensure_chapter(index=chapter) + + elif chapter in ['t', 'ts', 'ht', 'hts']: + self.ui_goto_event() + # Campaign ball + if stage in ['1', '6']: + self._campaign_ball_set('blue') + else: + self._campaign_ball_set('red') + # Campaign mode + if chapter in ['t', 'ts']: + self.campaign_ensure_mode('normal') + if chapter in ['ht', 'hts']: + self.campaign_ensure_mode('hard') + if chapter == 'ex_sp': + self.campaign_ensure_mode('ex') + # Get stage + self.campaign_ensure_chapter(index=1) + else: + logger.warning(f'Unknown campaign chapter: {name}') + + @staticmethod + def _campaign_get_chapter_index(name): + """ + Args: + name (str, int): + + Returns: + int + """ + if isinstance(name, int): + return name + else: + if name.isdigit(): + return int(name) + elif name in ['a', 'c', 'sp', 'ex_sp', 'ts', 't', 'ht', 'hts']: + return 1 + elif name in ['b', 'd', 'ex_ex']: + return 2 + else: + raise CampaignNameError + + def _campaign_ball_get(self): + """ + Returns: + str: 'blue' or 'red'. + """ + color = get_color(self.device.image, BALL.area) + # Blue: (93, 127, 182), Red: (186, 116, 124) + index = np.argmax(color) + if index == 0: + return 'red' + elif index == 2: + return 'blue' + else: + logger.warning(f'Unknown campaign ball color: {color}') + return 'unknown' + + def _campaign_ball_set(self, status): + """ + Args: + status (str): 'blue' or 'red'. + """ + skip_first_screenshot = True + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + current = self._campaign_ball_get() + logger.attr('Campaign_ball', current) + + if current == status: + break + else: + if self.is_in_stage(): + self.device.click(BALL) + self.device.sleep(3) + # wait until is_in_stage + while 1: + self.device.screenshot() + if self.is_in_stage(): + break diff --git a/campaign/war_archives_20200917_cn/ht1.py b/campaign/war_archives_20200917_cn/ht1.py new file mode 100644 index 000000000..47552a5fb --- /dev/null +++ b/campaign/war_archives_20200917_cn/ht1.py @@ -0,0 +1,89 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase + +MAP = CampaignMap('HT1') +MAP.shape = 'K7' +# MAP.camera_data = ['D2', 'D5', 'H2', 'H5'] +MAP.camera_data = ['D3', 'D5', 'H3', 'H5'] +MAP.camera_data_spawn_point = ['H5', 'D5'] +MAP.map_data = """ + -- -- ++ -- -- MB -- -- ++ -- -- + -- ++ ++ ++ Me -- Me ++ ++ ++ -- + ++ Me -- ++ ++ -- ++ ++ -- Me ++ + ME -- ME ++ ++ -- ++ ++ ME -- ME + -- -- -- ME MS -- MS ME -- -- -- + ME -- MS -- -- __ -- -- MS -- 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 +""" +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, 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, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CL', 'SS'] + 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 + # ===== End of generated config ===== + + STAGE_ENTRANCE = ['blue'] + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + MAP_WALK_USE_CURRENT_FLEET = True + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.fleet_2_protect(): + return True + + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ht2.py b/campaign/war_archives_20200917_cn/ht2.py new file mode 100644 index 000000000..9e49b92a3 --- /dev/null +++ b/campaign/war_archives_20200917_cn/ht2.py @@ -0,0 +1,84 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .ht1 import Config as ConfigBase + +MAP = CampaignMap('HT2') +MAP.shape = 'H7' +# MAP.camera_data = ['D2', 'D5', 'E2', 'E5'] +MAP.camera_data = ['D3', 'D5', 'E3', 'E5'] +MAP.camera_data_spawn_point = ['E5'] +MAP.portal_data = [('E5', 'E1'), ('E1', 'E5')] +MAP.map_data = """ + -- ++ -- ME -- ME ++ ++ + ME -- Me __ -- -- MB ++ + -- -- -- -- ME -- ++ ME + ++ ME ++ ++ ++ ++ MS -- + -- ++ Me Me -- Me -- ME + MS -- -- -- -- -- -- ++ + -- ME ++ ++ SP SP -- MS +""" +MAP.map_data_loop = """ + -- ++ -- ME -- ME ++ ++ + ME -- Me __ -- -- MB ++ + -- -- -- -- ME -- ++ ME + ++ ME ++ -- -- -- MS -- + -- ++ Me Me -- Me -- ME + MS -- -- -- -- -- -- ++ + -- ME ++ ++ SP SP -- MS +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 10 20 50 50 + 50 50 50 50 50 50 50 50 + 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, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CL', 'CAred'] + 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_PORTAL = True + # ===== End of generated config ===== + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.fleet_2_protect(): + return True + + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ht3.py b/campaign/war_archives_20200917_cn/ht3.py new file mode 100644 index 000000000..7963c6e05 --- /dev/null +++ b/campaign/war_archives_20200917_cn/ht3.py @@ -0,0 +1,94 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .ht1 import Config as ConfigBase + +MAP = CampaignMap('HT3') +MAP.shape = 'I9' +# MAP.camera_data = ['D2', 'D6', 'D7', 'F2', 'F6', 'F7'] +# MAP.camera_data_spawn_point = ['D7', 'D6'] +MAP.camera_data = ['D3', 'D5', 'D7', 'F3', 'F5', 'F7'] +MAP.camera_data_spawn_point = ['D5'] +MAP.portal_data = [('I2', 'A1'), ('A1', 'I2'), ('I9', 'H1'), ('H1', 'I9')] +MAP.map_data = """ + -- -- -- ++ ME -- ME -- ++ + -- -- MB ++ -- -- -- -- -- + ++ ++ ++ ++ -- ++ ++ -- ME + -- MS -- Me -- Me ++ -- -- + ME -- ++ -- __ -- -- -- ME + -- -- SP -- -- Me ++ ++ ++ + Me -- -- SP ++ -- ++ MB -- + -- MS -- -- -- MS ++ -- -- + ++ -- Me -- ME -- ++ -- -- +""" +MAP.map_data_loop = """ + -- -- -- -- ME -- ME -- ++ + -- -- MB -- -- -- -- -- -- + ++ ++ ++ -- -- ++ ++ -- ME + -- MS -- Me -- Me ++ -- -- + ME -- ++ -- __ -- -- -- ME + -- -- SP -- -- Me -- -- -- + Me -- -- SP ++ -- ++ MB -- + -- MS -- -- -- MS ++ -- -- + ++ -- 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 +""" +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, \ +A9, B9, C9, D9, E9, F9, G9, H9, I9, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CL', 'CAred'] + 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_PORTAL = True + # ===== End of generated config ===== + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.fleet_2_protect(): + return True + + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ht4.py b/campaign/war_archives_20200917_cn/ht4.py new file mode 100644 index 000000000..45f874dfb --- /dev/null +++ b/campaign/war_archives_20200917_cn/ht4.py @@ -0,0 +1,111 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .ht1 import Config as ConfigBase + +MAP = CampaignMap('HT4') +MAP.shape = 'K9' +MAP.camera_data = ['D2', 'D5', 'D7', 'H2', 'H5', 'H7'] +MAP.camera_data_spawn_point = ['D2', 'D7'] +MAP.portal_data = [('I5', 'C5'), ('C5', 'I5'), ('E5', 'E3'), ('E3', 'E5'), ('G5', 'G7'), ('G7', 'G5')] +MAP.map_data = """ + Me -- -- ++ Me -- ME -- ME ++ ++ + -- MS -- ++ -- SP -- __ -- MS -- + -- -- Me ++ -- -- -- ME -- -- -- + ME -- ++ ++ ++ ++ ++ ++ ++ -- ME + -- -- -- ++ -- MB -- ++ -- -- -- + ME -- ++ ++ ++ ++ ++ ++ ++ -- ME + -- -- -- ME -- -- -- ++ Me -- -- + -- MS -- __ -- SP -- ++ -- MS -- + ++ ++ ME -- ME -- Me ++ -- -- Me +""" +MAP.map_data_loop = """ + Me -- -- ++ Me -- ME -- ME ++ ++ + -- MS -- -- -- SP -- __ -- MS -- + -- -- Me ++ -- -- -- ME -- -- -- + ME -- ++ ++ -- ++ -- ++ ++ -- ME + -- -- -- ++ -- MB -- ++ -- -- -- + ME -- ++ ++ -- ++ -- ++ ++ -- ME + -- -- -- ME -- -- -- ++ Me -- -- + -- MS -- __ -- SP -- -- -- MS -- + ++ ++ 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 10 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 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 = ['BB', 'SS'] + 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_PORTAL = True + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.82 + MAP_SWIPE_MULTIPLY = 1.88 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.config.MAP_HAS_MOVABLE_ENEMY: + self.fleet_2_push_forward() + + if self.clear_siren(): + return True + if self.map_is_clear_mode: + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(1,)): + return True + + return self.battle_default() + + def battle_2(self): + if self.clear_siren(): + return True + if self.map_is_clear_mode: + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(1,)): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ht5.py b/campaign/war_archives_20200917_cn/ht5.py new file mode 100644 index 000000000..c928c2252 --- /dev/null +++ b/campaign/war_archives_20200917_cn/ht5.py @@ -0,0 +1,105 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .ht1 import Config as ConfigBase + +MAP = CampaignMap('HT5') +MAP.shape = 'I9' +# MAP.camera_data = ['D2', 'D6', 'D7', 'F2', 'F6', 'F7'] +# MAP.camera_data_spawn_point = ['F7', 'D2'] +MAP.camera_data = ['D3', 'D5', 'D7', 'F3', 'F5', 'F7'] +MAP.camera_data_spawn_point = ['F7', 'D3'] +MAP.portal_data = [('D3', 'F3'), ('G4', 'G6'), ('F7', 'D7'), ('C6', 'C4')] +MAP.map_data = """ + ++ -- -- -- ++ -- MB -- ++ + -- ME -- ME ++ MS -- MS -- + Me -- SP -- ++ -- __ -- -- + -- ME -- Me ++ Me -- ME -- + ++ ++ ++ ++ -- ++ ++ ++ ++ + -- ME -- Me ++ Me -- ME -- + -- -- __ -- ++ -- SP -- Me + -- MS -- MS ++ ME -- ME -- + ++ -- MB -- ++ -- -- -- ++ +""" +MAP.map_data_loop = """ + ++ -- -- -- ++ -- MB -- ++ + -- ME -- ME ++ MS -- MS -- + Me -- SP -- -- -- __ -- -- + -- ME -- Me ++ Me -- ME -- + ++ ++ -- ++ -- ++ -- ++ ++ + -- ME -- Me ++ Me -- ME -- + -- -- __ -- -- -- SP -- Me + -- MS -- MS ++ ME -- ME -- + ++ -- MB -- ++ -- -- -- ++ +""" +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 +""" +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, \ +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, \ +A9, B9, C9, D9, E9, F9, G9, H9, I9, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['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_PORTAL = True + # ===== End of generated config ===== + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + if self.map_is_clear_mode: + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(1,)): + return True + + return self.battle_default() + + def battle_5(self): + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + + return self.battle_default() + + def battle_6(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ht6.py b/campaign/war_archives_20200917_cn/ht6.py new file mode 100644 index 000000000..6e062757f --- /dev/null +++ b/campaign/war_archives_20200917_cn/ht6.py @@ -0,0 +1,109 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .ht1 import Config as ConfigBase + +MAP = CampaignMap('HT6') +MAP.shape = 'K10' +# MAP.camera_data = ['D2', 'D6', 'D8', 'H2', 'H6', 'H8'] +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['D6', 'G6'] +MAP.map_data = """ + -- -- -- ME -- Me -- ME -- -- -- + -- ++ ++ -- MS -- MS -- ++ ++ -- + -- ++ ME -- -- __ -- -- ME ++ -- + Me -- -- ++ ++ -- ++ ++ -- -- Me + ++ ME -- ++ MS -- MS ++ -- ME ++ + ++ ME -- -- -- MB -- -- -- 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 50 50 50 50 50 50 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, 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, \ +A10, B10, C10, D10, E10, F10, G10, H10, I10, J10, K10, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['BB', 'CV', 'SS'] + 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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.446 + MAP_SWIPE_MULTIPLY = 1.495 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.fleet_2_protect(): + return True + + if self.clear_siren(): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(1,)): + return True + + return self.battle_default() + + def battle_2(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(1,)): + return True + + return self.battle_default() + + def battle_5(self): + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + + return self.battle_default() + + def battle_6(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20200917_cn/hts1.py b/campaign/war_archives_20200917_cn/hts1.py new file mode 100644 index 000000000..18d0c2144 --- /dev/null +++ b/campaign/war_archives_20200917_cn/hts1.py @@ -0,0 +1,86 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase + +MAP = CampaignMap('HTS1') +MAP.shape = 'H6' +MAP.camera_data = ['D2', 'D4', 'E2', 'E4'] +MAP.camera_data_spawn_point = ['E4'] +MAP.map_data = """ + MB -- ++ ++ ++ ++ -- -- + -- 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 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 1}, + {'battle': 1, 'enemy': 1}, + # {'battle': 2, 'siren': 1}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, '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, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + # MAP_SIREN_TEMPLATE = ['srzl2'] + # MOVABLE_ENEMY_TURN = (0,) + # MAP_HAS_SIREN = True + # MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = True + MAP_HAS_FLEET_STEP = False + MAP_HAS_AMBUSH = False + STAR_REQUIRE_1 = 0 + STAR_REQUIRE_2 = 0 + STAR_REQUIRE_3 = 0 + # ===== End of generated config ===== + + STAGE_ENTRANCE = ['blue'] + FLEET_2 = 0 + MAP_IS_ONE_TIME_STAGE = True + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_3(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/hts2.py b/campaign/war_archives_20200917_cn/hts2.py new file mode 100644 index 000000000..a8dc704ec --- /dev/null +++ b/campaign/war_archives_20200917_cn/hts2.py @@ -0,0 +1,82 @@ +from module.exception import CampaignEnd +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .hts1 import Config as ConfigBase + +MAP = CampaignMap('HTS2') +MAP.shape = 'H8' +MAP.camera_data = ['D2', 'D6', 'E2', 'E6'] +MAP.camera_data_spawn_point = ['D6'] +MAP.map_data = """ + ++ MM -- -- -- -- -- -- + ++ ++ ++ ++ -- -- -- ++ + -- -- -- -- -- ++ -- ++ + -- -- -- ++ ++ ++ -- ++ + -- ++ -- -- ++ -- -- -- + -- -- ++ -- -- ++ -- ++ + -- -- SP ++ MM ++ -- ++ + MM -- -- ++ ++ ++ -- ++ +""" +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}, +] +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(ConfigBase): + # ===== Start of generated config ===== + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = False + MAP_HAS_AMBUSH = False + STAR_REQUIRE_1 = 0 + STAR_REQUIRE_2 = 0 + STAR_REQUIRE_3 = 0 + # ===== End of generated config ===== + + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + self.goto(A8, expected='story') + self.goto(E7, expected='story') + self.goto(B1, expected='story') + self.goto(G8, expected='story') + + raise CampaignEnd() diff --git a/campaign/war_archives_20200917_cn/t1.py b/campaign/war_archives_20200917_cn/t1.py new file mode 100644 index 000000000..fbbcd2eee --- /dev/null +++ b/campaign/war_archives_20200917_cn/t1.py @@ -0,0 +1,86 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase + +MAP = CampaignMap('T1') +MAP.shape = 'K7' +# MAP.camera_data = ['D2', 'D5', 'H2', 'H5'] +MAP.camera_data = ['D3', 'D5', 'H3', 'H5'] +MAP.camera_data_spawn_point = ['H5', 'D5'] +MAP.map_data = """ + -- -- ++ -- -- MB -- -- ++ -- -- + -- ++ ++ ++ Me -- Me ++ ++ ++ -- + ++ Me -- ++ ++ -- ++ ++ -- Me ++ + ME -- ME ++ ++ -- ++ ++ ME -- ME + -- -- -- ME MS -- MS ME -- -- -- + ME -- MS -- -- __ -- -- MS -- 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 +""" +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, 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, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['DD', 'SS'] + 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 + # ===== End of generated config ===== + + STAGE_ENTRANCE = ['blue'] + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + MAP_WALK_USE_CURRENT_FLEET = True + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_3(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/t2.py b/campaign/war_archives_20200917_cn/t2.py new file mode 100644 index 000000000..adcf86e83 --- /dev/null +++ b/campaign/war_archives_20200917_cn/t2.py @@ -0,0 +1,96 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .t1 import Config as ConfigBase + +MAP = CampaignMap('T2') +MAP.shape = 'H7' +# MAP.camera_data = ['D2', 'D5', 'E2', 'E5'] +MAP.camera_data = ['D3', 'D5', 'E3', 'E5'] +MAP.camera_data_spawn_point = ['E5'] +MAP.portal_data = [('E5', 'E1'), ('E1', 'E5')] +MAP.map_data = """ + -- ++ -- ME -- ME ++ ++ + ME -- Me __ -- -- MB ++ + -- -- -- -- ME -- ++ ME + ++ ME ++ ++ ++ ++ MS -- + -- ++ Me Me -- Me -- ME + MS -- -- -- -- -- -- ++ + -- ME ++ ++ SP SP -- MS +""" +MAP.map_data_loop = """ + -- ++ -- ME -- ME ++ ++ + ME -- Me __ -- -- MB ++ + -- -- -- -- ME -- ++ ME + ++ ME ++ -- -- -- MS -- + -- ++ Me Me -- Me -- ME + MS -- -- -- -- -- -- ++ + -- ME ++ ++ SP SP -- MS +""" +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 +""" +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, \ +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, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CL'] + 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_PORTAL = True + # ===== End of generated config ===== + + 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 + } + HOMO_EDGE_COLOR_RANGE = (0, 33) + MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/t3.py b/campaign/war_archives_20200917_cn/t3.py new file mode 100644 index 000000000..81bf22941 --- /dev/null +++ b/campaign/war_archives_20200917_cn/t3.py @@ -0,0 +1,105 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .t1 import Config as ConfigBase + +MAP = CampaignMap('T3') +MAP.shape = 'I9' +# MAP.camera_data = ['D2', 'D6', 'D7', 'F2', 'F6', 'F7'] +# MAP.camera_data_spawn_point = ['D7', 'D6'] +MAP.camera_data = ['D3', 'D5', 'D7', 'F3', 'F5', 'F7'] +MAP.camera_data_spawn_point = ['D5'] +MAP.portal_data = [('I2', 'A1'), ('A1', 'I2'), ('I9', 'H1'), ('H1', 'I9')] +MAP.map_data = """ + -- -- -- ++ ME -- ME -- ++ + -- -- MB ++ -- -- -- -- -- + ++ ++ ++ ++ -- ++ ++ -- ME + -- MS -- Me -- Me ++ -- -- + ME -- ++ -- __ -- -- -- ME + -- -- SP -- -- Me ++ ++ ++ + Me -- -- SP ++ -- ++ MB -- + -- MS -- -- -- MS ++ -- -- + ++ -- Me -- ME -- ++ -- -- +""" +MAP.map_data_loop = """ + -- -- -- -- ME -- ME -- ++ + -- -- MB -- -- -- -- -- -- + ++ ++ ++ -- -- ++ ++ -- ME + -- MS -- Me -- Me ++ -- -- + ME -- ++ -- __ -- -- -- ME + -- -- SP -- -- Me -- -- -- + Me -- -- SP ++ -- ++ MB -- + -- MS -- -- -- MS ++ -- -- + ++ -- 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 +""" +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, \ +A9, B9, C9, D9, E9, F9, G9, H9, I9, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CAred'] + 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_PORTAL = True + # ===== End of generated config ===== + + 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 + } + HOMO_EDGE_COLOR_RANGE = (0, 33) + MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/t4.py b/campaign/war_archives_20200917_cn/t4.py new file mode 100644 index 000000000..7bed81f24 --- /dev/null +++ b/campaign/war_archives_20200917_cn/t4.py @@ -0,0 +1,109 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .t1 import Config as ConfigBase + +MAP = CampaignMap('T4') +MAP.shape = 'K9' +MAP.camera_data = ['D2', 'D5', 'D7', 'H2', 'H5', 'H7'] +MAP.camera_data_spawn_point = ['D2', 'D7'] +MAP.portal_data = [('I5', 'C5'), ('C5', 'I5'), ('E5', 'E3'), ('E3', 'E5'), ('G5', 'G7'), ('G7', 'G5')] +MAP.map_data = """ + Me -- -- ++ Me -- ME -- ME ++ ++ + -- MS -- ++ -- SP -- __ -- MS -- + -- -- Me ++ -- -- -- ME -- -- -- + ME -- ++ ++ ++ ++ ++ ++ ++ -- ME + -- -- -- ++ -- MB -- ++ -- -- -- + ME -- ++ ++ ++ ++ ++ ++ ++ -- ME + -- -- -- ME -- -- -- ++ Me -- -- + -- MS -- __ -- SP -- ++ -- MS -- + ++ ++ ME -- ME -- Me ++ -- -- Me +""" +MAP.map_data_loop = """ + Me -- -- ++ Me -- ME -- ME ++ ++ + -- MS -- -- -- SP -- __ -- MS -- + -- -- Me ++ -- -- -- ME -- -- -- + ME -- ++ ++ -- ++ -- ++ ++ -- ME + -- -- -- ++ -- MB -- ++ -- -- -- + ME -- ++ ++ -- ++ -- ++ ++ -- ME + -- -- -- ME -- -- -- ++ Me -- -- + -- MS -- __ -- SP -- -- -- MS -- + ++ ++ 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 10 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 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, 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 = ['CL', 'SS'] + 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_PORTAL = True + # ===== End of generated config ===== + + 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 + } + HOMO_EDGE_COLOR_RANGE = (0, 33) + MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.82 + MAP_SWIPE_MULTIPLY = 1.88 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.config.MAP_HAS_MOVABLE_ENEMY: + self.fleet_2_push_forward() + + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/t5.py b/campaign/war_archives_20200917_cn/t5.py new file mode 100644 index 000000000..682d6de26 --- /dev/null +++ b/campaign/war_archives_20200917_cn/t5.py @@ -0,0 +1,106 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .t1 import Config as ConfigBase + +MAP = CampaignMap('T5') +MAP.shape = 'I9' +# MAP.camera_data = ['D2', 'D6', 'D7', 'F2', 'F6', 'F7'] +# MAP.camera_data_spawn_point = ['F7', 'D2'] +MAP.camera_data = ['D3', 'D5', 'D7', 'F3', 'F5', 'F7'] +MAP.camera_data_spawn_point = ['F7', 'D3'] +MAP.portal_data = [('D3', 'F3'), ('G4', 'G6'), ('F7', 'D7'), ('C6', 'C4')] +MAP.map_data = """ + ++ -- -- -- ++ -- MB -- ++ + -- ME -- ME ++ MS -- MS -- + Me -- SP -- ++ -- __ -- -- + -- ME -- Me ++ Me -- ME -- + ++ ++ ++ ++ -- ++ ++ ++ ++ + -- ME -- Me ++ Me -- ME -- + -- -- __ -- ++ -- SP -- Me + -- MS -- MS ++ ME -- ME -- + ++ -- MB -- ++ -- -- -- ++ +""" +MAP.map_data_loop = """ + ++ -- -- -- ++ -- MB -- ++ + -- ME -- ME ++ MS -- MS -- + Me -- SP -- -- -- __ -- -- + -- ME -- Me ++ Me -- ME -- + ++ ++ -- ++ -- ++ -- ++ ++ + -- ME -- Me ++ Me -- ME -- + -- -- __ -- -- -- SP -- Me + -- MS -- MS ++ ME -- ME -- + ++ -- MB -- ++ -- -- -- ++ +""" +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 +""" +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, \ +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, \ +A9, B9, C9, D9, E9, F9, G9, H9, I9, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CL', 'CAred'] + 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_PORTAL = True + # ===== End of generated config ===== + + 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 + } + HOMO_EDGE_COLOR_RANGE = (0, 33) + MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20200917_cn/t6.py b/campaign/war_archives_20200917_cn/t6.py new file mode 100644 index 000000000..586a2c81f --- /dev/null +++ b/campaign/war_archives_20200917_cn/t6.py @@ -0,0 +1,101 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .t1 import Config as ConfigBase + +MAP = CampaignMap('T6') +MAP.shape = 'K10' +# MAP.camera_data = ['D2', 'D6', 'D8', 'H2', 'H6', 'H8'] +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['D6', 'G6'] +MAP.map_data = """ + -- -- -- ME -- Me -- ME -- -- -- + -- ++ ++ -- MS -- MS -- ++ ++ -- + -- ++ ME -- -- __ -- -- ME ++ -- + Me -- -- ++ ++ -- ++ ++ -- -- Me + ++ ME -- ++ MS -- MS ++ -- ME ++ + ++ ME -- -- -- MB -- -- -- 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 50 50 50 50 50 50 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, \ +A10, B10, C10, D10, E10, F10, G10, H10, I10, J10, K10, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['CA', 'SS'] + 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 + # ===== End of generated config ===== + + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.446 + MAP_SWIPE_MULTIPLY = 1.495 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(1,)): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ts1.py b/campaign/war_archives_20200917_cn/ts1.py new file mode 100644 index 000000000..0cbef5675 --- /dev/null +++ b/campaign/war_archives_20200917_cn/ts1.py @@ -0,0 +1,83 @@ +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase + +MAP = CampaignMap('TS1') +MAP.shape = 'H6' +MAP.camera_data = ['D2', 'D4', 'E2', 'E4'] +MAP.camera_data_spawn_point = ['E4'] +MAP.map_data = """ + MB -- ++ ++ ++ ++ -- -- + -- 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 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 1}, + {'battle': 1, 'enemy': 1}, + # {'battle': 2, 'siren': 1}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, '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, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + # MAP_SIREN_TEMPLATE = ['srzl2'] + # MOVABLE_ENEMY_TURN = (0,) + # MAP_HAS_SIREN = True + # MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = True + MAP_HAS_FLEET_STEP = False + MAP_HAS_AMBUSH = False + STAR_REQUIRE_1 = 0 + STAR_REQUIRE_2 = 0 + STAR_REQUIRE_3 = 0 + # ===== End of generated config ===== + + STAGE_ENTRANCE = ['blue'] + FLEET_2 = 0 + MAP_IS_ONE_TIME_STAGE = True + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + return self.battle_default() + + def battle_3(self): + return self.clear_boss() diff --git a/campaign/war_archives_20200917_cn/ts2.py b/campaign/war_archives_20200917_cn/ts2.py new file mode 100644 index 000000000..7fa487ff5 --- /dev/null +++ b/campaign/war_archives_20200917_cn/ts2.py @@ -0,0 +1,82 @@ +from module.exception import CampaignEnd +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .campaign_base import CampaignBase +from .ts1 import Config as ConfigBase + +MAP = CampaignMap('TS2') +MAP.shape = 'H8' +MAP.camera_data = ['D2', 'D6', 'E2', 'E6'] +MAP.camera_data_spawn_point = ['D6'] +MAP.map_data = """ + ++ MM -- -- -- -- -- -- + ++ ++ ++ ++ -- -- -- ++ + -- -- -- -- -- ++ -- ++ + -- -- -- ++ ++ ++ -- ++ + -- ++ -- -- ++ -- -- -- + -- -- ++ -- -- ++ -- ++ + -- -- SP ++ MM ++ -- ++ + MM -- -- ++ ++ ++ -- ++ +""" +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}, +] +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(ConfigBase): + # ===== Start of generated config ===== + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = False + MAP_HAS_AMBUSH = False + STAR_REQUIRE_1 = 0 + STAR_REQUIRE_2 = 0 + STAR_REQUIRE_3 = 0 + # ===== End of generated config ===== + + INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (150, 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_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + self.goto(A8, expected='story') + self.goto(E7, expected='story') + self.goto(B1, expected='story') + self.goto(G8, expected='story') + + raise CampaignEnd() diff --git a/campaign/war_archives_20210527_cn/a1.py b/campaign/war_archives_20210527_cn/a1.py new file mode 100644 index 000000000..f550a6693 --- /dev/null +++ b/campaign/war_archives_20210527_cn/a1.py @@ -0,0 +1,70 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +MAP = CampaignMap('A1') +MAP.shape = 'I7' +MAP.camera_data = ['D2', 'D5', 'F2', 'F5'] +MAP.camera_data_spawn_point = ['F2'] +MAP.map_data = """ + ++ ++ -- ME -- Me ++ -- -- + ++ ++ Me -- -- -- -- -- SP + ME -- -- -- ++ MS -- ME SP + -- -- ME -- ++ __ ME -- ++ + MB -- ++ MS -- 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, '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, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['Dewey'] + 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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.778 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.719 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_3(self): + return self.clear_boss() diff --git a/campaign/war_archives_20210527_cn/a2.py b/campaign/war_archives_20210527_cn/a2.py new file mode 100644 index 000000000..7a4d812ab --- /dev/null +++ b/campaign/war_archives_20210527_cn/a2.py @@ -0,0 +1,75 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .a1 import Config as ConfigBase + +MAP = CampaignMap('A2') +MAP.shape = 'H8' +MAP.camera_data = ['D2', 'D6', 'E2', 'E6'] +MAP.camera_data_spawn_point = ['E6', 'D6'] +MAP.map_data = """ + -- ++ ++ ++ -- MB -- ++ + -- ME -- ME -- ME -- -- + ++ -- MS -- ME ++ Me -- + -- Me ++ -- Me -- -- -- + ME -- ++ ME -- __ ME MS + -- MS -- 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 +""" +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, \ +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(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['DD'] + 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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.512 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.462 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20210527_cn/a3.py b/campaign/war_archives_20210527_cn/a3.py new file mode 100644 index 000000000..f639acd8a --- /dev/null +++ b/campaign/war_archives_20210527_cn/a3.py @@ -0,0 +1,75 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .a1 import Config as ConfigBase + +MAP = CampaignMap('A3') +MAP.shape = 'J8' +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['G6', 'D6'] +MAP.map_data = """ + ++ ++ -- ++ ++ -- -- ME ++ ++ + -- -- MB -- ME -- MS -- ++ ++ + -- ME -- ME MS Me -- ME -- -- + -- ++ -- ++ -- __ -- Me -- MS + ME ++ -- ++ ME Me ++ -- ME -- + -- -- -- Me -- -- ME -- -- -- + -- ME -- -- SP ++ -- ++ SP ++ + -- ++ ++ ++ -- 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': 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 = ['CL'] + 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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.512 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.462 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20210527_cn/b1.py b/campaign/war_archives_20210527_cn/b1.py new file mode 100644 index 000000000..450ed9faf --- /dev/null +++ b/campaign/war_archives_20210527_cn/b1.py @@ -0,0 +1,79 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +MAP = CampaignMap('B1') +MAP.shape = 'J8' +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['D2', 'D6'] +MAP.map_data = """ + -- ME -- ME -- -- -- -- ++ ++ + ++ -- MS -- -- Me -- -- MB ++ + ++ -- -- MS Me ++ -- Me -- -- + SP -- ME -- ME -- ME ++ -- ++ + SP -- ++ ++ -- __ -- ++ -- ME + -- -- ++ ++ Me ME -- ME -- -- + ME -- MS -- -- -- Me -- ++ ++ + -- ++ -- ME -- MS -- ++ ++ ++ +""" +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 = ['Hammann', 'CL'] + 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 + # ===== End of generated config ===== + + MAP_ENEMY_GENRE_DETECTION_SCALING = { + 'DD': 1.111, + 'CL': 1.111, + 'CA': 1.111, + 'CV': 1.111, + 'BB': 1.111, + } + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20210527_cn/b2.py b/campaign/war_archives_20210527_cn/b2.py new file mode 100644 index 000000000..4e55be47b --- /dev/null +++ b/campaign/war_archives_20210527_cn/b2.py @@ -0,0 +1,76 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .b1 import Config as ConfigBase + +MAP = CampaignMap('B2') +MAP.shape = 'J8' +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['G6'] +MAP.map_data = """ + ++ ++ -- ME -- -- MS ++ ++ ++ + ++ ++ -- ++ ++ -- -- -- -- ME + -- Me -- -- ME -- Me -- ++ -- + ME ++ MS MB -- -- ME -- ++ -- + -- ++ -- -- ME __ -- MS ++ ME + -- ++ -- Me -- -- Me -- -- -- + ME -- ME -- -- ++ ++ -- -- SP + ++ ++ ++ MS -- ME -- -- 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 = ['Atlanta', 'CL'] + 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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.523 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.472 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20210527_cn/b3.py b/campaign/war_archives_20210527_cn/b3.py new file mode 100644 index 000000000..0dd6f7a45 --- /dev/null +++ b/campaign/war_archives_20210527_cn/b3.py @@ -0,0 +1,81 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .b1 import Config as ConfigBase + +MAP = CampaignMap('B3') +MAP.shape = 'I9' +MAP.camera_data = ['D2', 'D6', 'D7', 'F2', 'F6', 'F7'] +MAP.camera_data_spawn_point = ['F7', 'D7'] +MAP.map_data = """ + ++ -- ME -- -- -- ME -- ++ + ++ ++ ++ -- MB -- ++ ++ ++ + ME -- -- -- ++ -- -- -- ME + -- ME Me -- Me -- Me ME -- + -- ++ ++ -- __ -- ++ ++ -- + MS ++ ++ -- Me -- ++ ++ MS + -- ME MS -- -- -- MS ME -- + 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 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, \ +A9, B9, C9, D9, E9, F9, G9, H9, I9, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['Dewey', 'Northampton', '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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.477 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.428 + INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 + # EDGE_LINES_HOUGHLINES_THRESHOLD = 40 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20210527_cn/c1.py b/campaign/war_archives_20210527_cn/c1.py new file mode 100644 index 000000000..b74817698 --- /dev/null +++ b/campaign/war_archives_20210527_cn/c1.py @@ -0,0 +1,77 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +MAP = CampaignMap('C1') +MAP.shape = 'I7' +MAP.camera_data = ['D2', 'D5', 'F2', 'F5'] +MAP.camera_data_spawn_point = ['F2'] +MAP.map_data = """ + ++ ++ -- ME -- Me ++ -- -- + ++ ++ Me -- -- -- -- -- SP + ME -- -- -- ++ MS -- ME SP + -- -- ME -- ++ __ ME -- ++ + MB -- ++ MS -- 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: + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['Dewey', '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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.778 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.719 + MAP_ENEMY_GENRE_DETECTION_SCALING = { + 'DD': 1.111, + 'CL': 1.111, + 'CA': 1.111, + 'CV': 1.111, + 'BB': 1.111, + } + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20210527_cn/c2.py b/campaign/war_archives_20210527_cn/c2.py new file mode 100644 index 000000000..583f5ffb8 --- /dev/null +++ b/campaign/war_archives_20210527_cn/c2.py @@ -0,0 +1,81 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .c1 import Config as ConfigBase + +MAP = CampaignMap('C2') +MAP.shape = 'H8' +MAP.camera_data = ['D2', 'D6', 'E2', 'E6'] +MAP.camera_data_spawn_point = ['E6', 'D6'] +MAP.map_data = """ + -- ++ ++ ++ -- MB -- ++ + -- ME -- ME -- ME -- -- + ++ -- MS -- ME ++ Me -- + -- Me ++ -- Me -- -- -- + ME -- ++ ME -- __ ME MS + -- MS -- 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 +""" +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(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['Atlanta', '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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.512 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.462 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/war_archives_20210527_cn/c3.py b/campaign/war_archives_20210527_cn/c3.py new file mode 100644 index 000000000..8d7870d0f --- /dev/null +++ b/campaign/war_archives_20210527_cn/c3.py @@ -0,0 +1,82 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .c1 import Config as ConfigBase + +MAP = CampaignMap('C3') +MAP.shape = 'J8' +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['G6', 'D6'] +MAP.map_data = """ + ++ ++ -- ++ ++ -- -- ME ++ ++ + -- -- MB -- ME -- MS -- ++ ++ + -- ME -- ME MS Me -- ME -- -- + -- ++ -- ++ -- __ -- Me -- MS + ME ++ -- ++ ME Me ++ -- ME -- + -- -- -- Me -- -- ME -- -- -- + -- ME -- -- SP ++ -- ++ SP ++ + -- ++ ++ ++ -- 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': 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 = ['Northampton', '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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.512 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.462 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20210527_cn/d1.py b/campaign/war_archives_20210527_cn/d1.py new file mode 100644 index 000000000..28114906d --- /dev/null +++ b/campaign/war_archives_20210527_cn/d1.py @@ -0,0 +1,85 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +MAP = CampaignMap('D1') +MAP.shape = 'J8' +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['D2', 'D6'] +MAP.map_data = """ + -- ME -- ME -- -- -- -- ++ ++ + ++ -- MS -- -- Me -- -- MB ++ + ++ -- -- MS Me ++ -- Me -- -- + SP -- ME -- ME -- ME ++ -- ++ + SP -- ++ ++ -- __ -- ++ -- ME + -- -- ++ ++ Me ME -- ME -- -- + ME -- MS -- -- -- Me -- ++ ++ + -- ++ -- ME -- MS -- ++ ++ ++ +""" +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 = ['Hammann', 'Atlanta', 'CA'] + 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 + # ===== End of generated config ===== + + MAP_ENEMY_GENRE_DETECTION_SCALING = { + 'DD': 1.111, + 'CL': 1.111, + 'CA': 1.111, + 'CV': 1.111, + 'BB': 1.111, + } + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20210527_cn/d2.py b/campaign/war_archives_20210527_cn/d2.py new file mode 100644 index 000000000..5029fd762 --- /dev/null +++ b/campaign/war_archives_20210527_cn/d2.py @@ -0,0 +1,93 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .d1 import Config as ConfigBase + +MAP = CampaignMap('D2') +MAP.shape = 'J8' +MAP.camera_data = ['D2', 'D6', 'G2', 'G6'] +MAP.camera_data_spawn_point = ['G6'] +MAP.map_data = """ + ++ ++ -- ME -- -- MS ++ ++ ++ + ++ ++ -- ++ ++ -- -- -- -- ME + -- Me -- -- ME -- Me -- ++ -- + ME ++ MS MB -- -- ME -- ++ -- + -- ++ -- -- ME __ -- MS ++ ME + -- ++ -- Me -- -- Me -- -- -- + ME -- ME -- -- ++ ++ -- -- SP + ++ ++ ++ MS -- ME -- -- 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': 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 = ['Dewey', 'Northampton', '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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.523 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.472 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_5(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_6(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/war_archives_20210527_cn/d3.py b/campaign/war_archives_20210527_cn/d3.py new file mode 100644 index 000000000..b8c4419c9 --- /dev/null +++ b/campaign/war_archives_20210527_cn/d3.py @@ -0,0 +1,100 @@ +from ..campaign_war_archives.campaign_base import CampaignBase +from module.logger import logger +from module.map.map_base import CampaignMap +from module.map.map_grids import RoadGrids, SelectedGrids + +from .d1 import Config as ConfigBase + +MAP = CampaignMap('D3') +MAP.shape = 'I9' +MAP.camera_data = ['D2', 'D6', 'D7', 'F2', 'F6', 'F7'] +MAP.camera_data_spawn_point = ['F7', 'D7'] +MAP.map_data = """ + ++ -- ME -- -- -- ME -- ++ + ++ ++ ++ -- MB -- ++ ++ ++ + ME -- -- -- ++ -- -- -- ME + -- ME Me -- Me -- Me ME -- + -- ++ ++ -- __ -- ++ ++ -- + MS ++ ++ -- Me -- ++ ++ MS + -- ME MS -- -- -- MS ME -- + 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 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, \ +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, \ +A9, B9, C9, D9, E9, F9, G9, H9, I9, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['Atlanta', 'Northampton', '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 + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.477 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.428 + INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 + # EDGE_LINES_HOUGHLINES_THRESHOLD = 40 + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.fleet_2_protect(): + return True + if self.clear_siren(): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_5(self): + if self.clear_siren(): + return True + if self.clear_enemy(scale=(1,)): + return True + if self.clear_enemy(scale=(2,)): + return True + if self.clear_enemy(scale=(3,)): + return True + + return self.battle_default() + + def battle_6(self): + return self.fleet_boss.clear_boss() diff --git a/module/campaign/run.py b/module/campaign/run.py index b1956f5b1..134c0f121 100644 --- a/module/campaign/run.py +++ b/module/campaign/run.py @@ -228,6 +228,7 @@ class CampaignRun(CampaignEvent): 'event_20200917_cn', 'event_20221124_cn', 'event_20230525_cn', + 'war_archives_20200917_cn', # chapter T 'event_20211125_cn', 'event_20231026_cn', diff --git a/module/config/argument/args.json b/module/config/argument/args.json index b13a783d9..d142d4ffa 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -3383,16 +3383,18 @@ "war_archives_20211014_cn", "war_archives_20211028_cn", "war_archives_20220210_cn", - "war_archives_20220414_cn" + "war_archives_20220414_cn", + "war_archives_20200917_cn", + "war_archives_20210527_cn" ], "option_bold": [ "war_archives_20201229_cn", - "war_archives_20220414_cn" + "war_archives_20210527_cn" ], - "cn": "war_archives_20201229_cn", - "en": "war_archives_20201229_cn", - "jp": "war_archives_20201229_cn", - "tw": "war_archives_20220414_cn" + "cn": "war_archives_20210527_cn", + "en": "war_archives_20210527_cn", + "jp": "war_archives_20210527_cn", + "tw": "war_archives_20210527_cn" }, "Mode": { "type": "select", diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index c387bdfbb..9066dbd56 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -740,7 +740,9 @@ "war_archives_20211014_cn": "archives Crescendo of Polaris", "war_archives_20211028_cn": "archives Skybound Oratorio", "war_archives_20220210_cn": "archives Northern Overture", - "war_archives_20220414_cn": "archives Aurora Noctis" + "war_archives_20220414_cn": "archives Aurora Noctis", + "war_archives_20200917_cn": "archives Dreamwaker's Butterfly", + "war_archives_20210527_cn": "archives Mirror Involution" }, "Mode": { "name": "Level Mode", diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 3033718fe..81efc15ac 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -740,7 +740,9 @@ "war_archives_20211014_cn": "檔案 激奏のポラリス", "war_archives_20211028_cn": "檔案 神穹を衝く聖歌", "war_archives_20220210_cn": "檔案 凍絶の北海", - "war_archives_20220414_cn": "檔案 極夜照らす幻光" + "war_archives_20220414_cn": "檔案 極夜照らす幻光", + "war_archives_20200917_cn": "檔案 刹那觀る胡蝶の夢", + "war_archives_20210527_cn": "檔案 照らす螺旋の鏡海" }, "Mode": { "name": "Campaign.Mode.name", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index 08ef51932..d11475c64 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -740,7 +740,9 @@ "war_archives_20211014_cn": "档案 激奏的Polaris", "war_archives_20211028_cn": "档案 穹顶下的圣咏曲", "war_archives_20220210_cn": "档案 北境序曲", - "war_archives_20220414_cn": "档案 永夜幻光" + "war_archives_20220414_cn": "档案 永夜幻光", + "war_archives_20200917_cn": "档案 蝶海梦花", + "war_archives_20210527_cn": "档案 镜位螺旋" }, "Mode": { "name": "关卡模式", diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 9acf969e4..70af5f137 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -740,7 +740,9 @@ "war_archives_20211014_cn": "archives Crescendo of Polaris", "war_archives_20211028_cn": "檔案 穹頂下的聖詠曲", "war_archives_20220210_cn": "檔案 北境序曲", - "war_archives_20220414_cn": "檔案 永夜幻光" + "war_archives_20220414_cn": "檔案 永夜幻光", + "war_archives_20200917_cn": "檔案 蝶海夢花", + "war_archives_20210527_cn": "檔案 鏡位螺旋" }, "Mode": { "name": "地圖模式", diff --git a/module/war_archives/assets.py b/module/war_archives/assets.py index c0f66a7d2..f86430741 100644 --- a/module/war_archives/assets.py +++ b/module/war_archives/assets.py @@ -10,6 +10,7 @@ TEMPLATE_AURORA_NOCTIS = Template(file={'cn': './assets/cn/war_archives/TEMPLATE TEMPLATE_CRESCENDO_OF_POLARIS = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png', 'en': './assets/en/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png', 'jp': './assets/jp/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png', 'tw': './assets/cn/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png'}) TEMPLATE_CRIMSON_ECHOES = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_CRIMSON_ECHOES.png', 'en': './assets/en/war_archives/TEMPLATE_CRIMSON_ECHOES.png', 'jp': './assets/jp/war_archives/TEMPLATE_CRIMSON_ECHOES.png', 'tw': './assets/cn/war_archives/TEMPLATE_CRIMSON_ECHOES.png'}) TEMPLATE_DIVERGENT_CHESSBOARD = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png', 'en': './assets/en/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png', 'jp': './assets/jp/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png', 'tw': './assets/tw/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png'}) +TEMPLATE_DREAMWAKERS_BUTTERFLY = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png', 'en': './assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png', 'jp': './assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png', 'tw': './assets/cn/war_archives/TEMPLATE_DREAMWAKERS_BUTTERFLY.png'}) TEMPLATE_EMPYREAL_TRAGICOMEDY = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png', 'en': './assets/en/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png', 'jp': './assets/cn/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png', 'tw': './assets/cn/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png'}) TEMPLATE_ENCIRCLING_GRAF_SPEE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_ENCIRCLING_GRAF_SPEE.png', 'en': './assets/en/war_archives/TEMPLATE_ENCIRCLING_GRAF_SPEE.png', 'jp': './assets/jp/war_archives/TEMPLATE_ENCIRCLING_GRAF_SPEE.png', 'tw': './assets/tw/war_archives/TEMPLATE_ENCIRCLING_GRAF_SPEE.png'}) TEMPLATE_FALLEN_WINGS = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_FALLEN_WINGS.png', 'en': './assets/en/war_archives/TEMPLATE_FALLEN_WINGS.png', 'jp': './assets/jp/war_archives/TEMPLATE_FALLEN_WINGS.png', 'tw': './assets/tw/war_archives/TEMPLATE_FALLEN_WINGS.png'}) @@ -18,6 +19,7 @@ TEMPLATE_INK_STAINED_STEEL_SAKURA = Template(file={'cn': './assets/cn/war_archiv TEMPLATE_INVERTED_ORTHANT = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_INVERTED_ORTHANT.png', 'en': './assets/cn/war_archives/TEMPLATE_INVERTED_ORTHANT.png', 'jp': './assets/cn/war_archives/TEMPLATE_INVERTED_ORTHANT.png', 'tw': './assets/cn/war_archives/TEMPLATE_INVERTED_ORTHANT.png'}) TEMPLATE_IRIS_OF_LIGHT_AND_DARK = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_IRIS_OF_LIGHT_AND_DARK.png', 'en': './assets/en/war_archives/TEMPLATE_IRIS_OF_LIGHT_AND_DARK.png', 'jp': './assets/jp/war_archives/TEMPLATE_IRIS_OF_LIGHT_AND_DARK.png', 'tw': './assets/cn/war_archives/TEMPLATE_IRIS_OF_LIGHT_AND_DARK.png'}) TEMPLATE_MICROLAYER_MEDLEY = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_MICROLAYER_MEDLEY.png', 'en': './assets/en/war_archives/TEMPLATE_MICROLAYER_MEDLEY.png', 'jp': './assets/cn/war_archives/TEMPLATE_MICROLAYER_MEDLEY.png', 'tw': './assets/cn/war_archives/TEMPLATE_MICROLAYER_MEDLEY.png'}) +TEMPLATE_MIRROR_INVOLUTION = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png', 'en': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png', 'jp': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png', 'tw': './assets/cn/war_archives/TEMPLATE_MIRROR_INVOLUTION.png'}) TEMPLATE_NORTHERN_OVERTURE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_NORTHERN_OVERTURE.png', 'en': './assets/en/war_archives/TEMPLATE_NORTHERN_OVERTURE.png', 'jp': './assets/cn/war_archives/TEMPLATE_NORTHERN_OVERTURE.png', 'tw': './assets/cn/war_archives/TEMPLATE_NORTHERN_OVERTURE.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'}) diff --git a/module/war_archives/dictionary.py b/module/war_archives/dictionary.py index e830afeea..54c6ef876 100644 --- a/module/war_archives/dictionary.py +++ b/module/war_archives/dictionary.py @@ -24,4 +24,6 @@ dic_archives_template = { 'war_archives_20220210_cn': TEMPLATE_NORTHERN_OVERTURE, 'war_archives_20220414_cn': TEMPLATE_AURORA_NOCTIS, 'war_archives_20201229_cn': TEMPLATE_INVERTED_ORTHANT, + 'war_archives_20200917_cn': TEMPLATE_DREAMWAKERS_BUTTERFLY, + 'war_archives_20210527_cn': TEMPLATE_MIRROR_INVOLUTION, }