diff --git a/assets/cn/map/MAP_MODE_SWITCH_HARD.png b/assets/cn/map/MAP_MODE_SWITCH_HARD.png new file mode 100644 index 0000000000..fcff54fe99 Binary files /dev/null and b/assets/cn/map/MAP_MODE_SWITCH_HARD.png differ diff --git a/assets/cn/map/MAP_MODE_SWITCH_NORMAL.png b/assets/cn/map/MAP_MODE_SWITCH_NORMAL.png new file mode 100644 index 0000000000..b1b75976ef Binary files /dev/null and b/assets/cn/map/MAP_MODE_SWITCH_NORMAL.png differ diff --git a/assets/en/map/MAP_MODE_SWITCH_HARD.png b/assets/en/map/MAP_MODE_SWITCH_HARD.png new file mode 100644 index 0000000000..fcff54fe99 Binary files /dev/null and b/assets/en/map/MAP_MODE_SWITCH_HARD.png differ diff --git a/assets/en/map/MAP_MODE_SWITCH_NORMAL.png b/assets/en/map/MAP_MODE_SWITCH_NORMAL.png new file mode 100644 index 0000000000..b1b75976ef Binary files /dev/null and b/assets/en/map/MAP_MODE_SWITCH_NORMAL.png differ diff --git a/assets/jp/map/MAP_MODE_SWITCH_HARD.png b/assets/jp/map/MAP_MODE_SWITCH_HARD.png new file mode 100644 index 0000000000..fcff54fe99 Binary files /dev/null and b/assets/jp/map/MAP_MODE_SWITCH_HARD.png differ diff --git a/assets/jp/map/MAP_MODE_SWITCH_NORMAL.png b/assets/jp/map/MAP_MODE_SWITCH_NORMAL.png new file mode 100644 index 0000000000..b1b75976ef Binary files /dev/null and b/assets/jp/map/MAP_MODE_SWITCH_NORMAL.png differ diff --git a/assets/tw/map/MAP_MODE_SWITCH_HARD.png b/assets/tw/map/MAP_MODE_SWITCH_HARD.png new file mode 100644 index 0000000000..fcff54fe99 Binary files /dev/null and b/assets/tw/map/MAP_MODE_SWITCH_HARD.png differ diff --git a/assets/tw/map/MAP_MODE_SWITCH_NORMAL.png b/assets/tw/map/MAP_MODE_SWITCH_NORMAL.png new file mode 100644 index 0000000000..b1b75976ef Binary files /dev/null and b/assets/tw/map/MAP_MODE_SWITCH_NORMAL.png differ diff --git a/campaign/event_20240725_cn/campaign_base.py b/campaign/event_20240725_cn/campaign_base.py index 5f90681029..6da69fc052 100644 --- a/campaign/event_20240725_cn/campaign_base.py +++ b/campaign/event_20240725_cn/campaign_base.py @@ -17,6 +17,9 @@ def campaign_ensure_mode(self, mode='normal'): Returns: bool: If mode changed. """ + if mode == 'hard': + self.config.override(Campaign_Mode='hard') + if mode in ['normal', 'hard', 'ex']: MODE_SWITCH_20240725.set('combat', main=self) elif mode in ['story']: diff --git a/module/campaign/campaign_ui.py b/module/campaign/campaign_ui.py index f6fd2cacd1..7c0137f604 100644 --- a/module/campaign/campaign_ui.py +++ b/module/campaign/campaign_ui.py @@ -77,6 +77,9 @@ def campaign_ensure_mode(self, mode='normal'): Returns: bool: If mode changed. """ + if mode == 'hard': + self.config.override(Campaign_Mode='hard') + switch_2 = MODE_SWITCH_2.get(main=self) if switch_2 == 'unknown': @@ -100,6 +103,29 @@ def campaign_ensure_mode(self, mode='normal'): else: logger.warning(f'Unknown campaign mode: {mode}') + def campaign_get_mode_names(self, name): + """ + Get stage names in both 'normal' and 'hard' + t1 -> [t1, ht1] + ht1 -> [t1, ht1] + a1 -> [a1, c1] + + Args: + name (str): + + Returns: + list[str]: + """ + if name.startswith('t'): + return [f't{name[1:]}', f'ht{name[1:]}'] + if name.startswith('ht'): + return [f't{name[2:]}', f'ht{name[2:]}'] + if name.startswith('a') or name.startswith('c'): + return [f'a{name[1:]}', f'c{name[1:]}'] + if name.startswith('b') or name.startswith('d'): + return [f'b{name[1:]}', f'd{name[1:]}'] + return [name] + def campaign_get_entrance(self, name): """ Args: @@ -108,12 +134,18 @@ def campaign_get_entrance(self, name): Returns: Button: """ + entrance_name = name + if self.config.MAP_HAS_MODE_SWITCH: + for mode_name in self.campaign_get_mode_names(name): + if mode_name in self.stage_entrance: + name = mode_name + if name not in self.stage_entrance: logger.warning(f'Stage not found: {name}') raise CampaignNameError entrance = self.stage_entrance[name] - entrance.name = name + entrance.name = entrance_name return entrance def campaign_set_chapter_main(self, chapter, mode='normal'): @@ -132,11 +164,11 @@ def campaign_set_chapter_main(self, chapter, mode='normal'): return False def campaign_set_chapter_event(self, chapter, mode='normal'): - if chapter in ['a', 'b', 'c', 'd', 'ex_sp', 'as', 'bs', 'cs', 'ds', 't', 'ts', 'tss', 'hts']: + if chapter in ['a', 'b', 'c', 'd', 'ex_sp', 'as', 'bs', 'cs', 'ds', 't', 'ts', 'tss', 'ht', 'hts']: self.ui_goto_event() if chapter in ['a', 'b', 'as', 'bs', 't', 'ts', 'tss']: self.campaign_ensure_mode('normal') - elif chapter in ['c', 'd', 'cs', 'ds', 'hts']: + elif chapter in ['c', 'd', 'cs', 'ds', 'ht', 'hts']: self.campaign_ensure_mode('hard') elif chapter == 'ex_sp': self.campaign_ensure_mode('ex') diff --git a/module/config/config_manual.py b/module/config/config_manual.py index cd795c7e86..7165534495 100644 --- a/module/config/config_manual.py +++ b/module/config/config_manual.py @@ -113,6 +113,7 @@ def SERVER(self): """ module.map.fleet """ + MAP_HAS_MODE_SWITCH = False # event_20240725_cn has mode switch in map preparation MAP_HAS_CLEAR_PERCENTAGE = True MAP_HAS_WALK_SPEEDUP = False MAP_HAS_AMBUSH = True diff --git a/module/map/assets.py b/module/map/assets.py index 84842cf990..a0c937034d 100644 --- a/module/map/assets.py +++ b/module/map/assets.py @@ -22,6 +22,8 @@ FLEET_PREPARATION_CHECK = Button(area={'cn': (1146, 107, 1174, 136), 'en': (1129, 111, 1158, 140), 'jp': (1146, 107, 1174, 136), 'tw': (1145, 106, 1175, 136)}, color={'cn': (180, 98, 111), 'en': (189, 105, 109), 'jp': (180, 98, 111), 'tw': (180, 90, 92)}, button={'cn': (1146, 107, 1174, 136), 'en': (1129, 111, 1158, 140), 'jp': (1146, 107, 1174, 136), 'tw': (1145, 106, 1175, 136)}, file={'cn': './assets/cn/map/FLEET_PREPARATION_CHECK.png', 'en': './assets/en/map/FLEET_PREPARATION_CHECK.png', 'jp': './assets/jp/map/FLEET_PREPARATION_CHECK.png', 'tw': './assets/tw/map/FLEET_PREPARATION_CHECK.png'}) MAP_CAT_ATTACK = Button(area={'cn': (1237, 103, 1252, 153), 'en': (1237, 103, 1252, 153), 'jp': (1237, 103, 1252, 153), 'tw': (1237, 103, 1252, 153)}, color={'cn': (43, 45, 52), 'en': (43, 45, 52), 'jp': (43, 45, 52), 'tw': (43, 45, 52)}, button={'cn': (1148, 653, 1262, 705), 'en': (1147, 651, 1263, 701), 'jp': (1149, 653, 1261, 704), 'tw': (1148, 653, 1262, 705)}, file={'cn': './assets/cn/map/MAP_CAT_ATTACK.png', 'en': './assets/en/map/MAP_CAT_ATTACK.png', 'jp': './assets/jp/map/MAP_CAT_ATTACK.png', 'tw': './assets/tw/map/MAP_CAT_ATTACK.png'}) MAP_CAT_ATTACK_MIRROR = Button(area={'cn': (147, 145, 187, 157), 'en': (147, 145, 187, 157), 'jp': (147, 145, 187, 157), 'tw': (147, 145, 187, 157)}, color={'cn': (214, 191, 99), 'en': (214, 191, 99), 'jp': (214, 191, 99), 'tw': (214, 191, 99)}, button={'cn': (147, 145, 187, 157), 'en': (147, 145, 187, 157), 'jp': (147, 145, 187, 157), 'tw': (147, 145, 187, 157)}, file={'cn': './assets/cn/map/MAP_CAT_ATTACK_MIRROR.png', 'en': './assets/en/map/MAP_CAT_ATTACK_MIRROR.png', 'jp': './assets/jp/map/MAP_CAT_ATTACK_MIRROR.png', 'tw': './assets/tw/map/MAP_CAT_ATTACK_MIRROR.png'}) +MAP_MODE_SWITCH_HARD = Button(area={'cn': (341, 580, 374, 617), 'en': (341, 580, 374, 617), 'jp': (341, 580, 374, 617), 'tw': (341, 580, 374, 617)}, color={'cn': (234, 179, 179), 'en': (234, 179, 179), 'jp': (234, 179, 179), 'tw': (234, 179, 179)}, button={'cn': (341, 580, 374, 617), 'en': (341, 580, 374, 617), 'jp': (341, 580, 374, 617), 'tw': (341, 580, 374, 617)}, file={'cn': './assets/cn/map/MAP_MODE_SWITCH_HARD.png', 'en': './assets/en/map/MAP_MODE_SWITCH_HARD.png', 'jp': './assets/jp/map/MAP_MODE_SWITCH_HARD.png', 'tw': './assets/tw/map/MAP_MODE_SWITCH_HARD.png'}) +MAP_MODE_SWITCH_NORMAL = Button(area={'cn': (214, 584, 255, 615), 'en': (214, 584, 255, 615), 'jp': (214, 584, 255, 615), 'tw': (214, 584, 255, 615)}, color={'cn': (185, 201, 236), 'en': (185, 201, 236), 'jp': (185, 201, 236), 'tw': (185, 201, 236)}, button={'cn': (214, 584, 255, 615), 'en': (214, 584, 255, 615), 'jp': (214, 584, 255, 615), 'tw': (214, 584, 255, 615)}, file={'cn': './assets/cn/map/MAP_MODE_SWITCH_NORMAL.png', 'en': './assets/en/map/MAP_MODE_SWITCH_NORMAL.png', 'jp': './assets/jp/map/MAP_MODE_SWITCH_NORMAL.png', 'tw': './assets/tw/map/MAP_MODE_SWITCH_NORMAL.png'}) MAP_OFFENSIVE = Button(area={'cn': (1148, 653, 1262, 705), 'en': (1147, 652, 1263, 701), 'jp': (1147, 652, 1263, 706), 'tw': (1148, 653, 1262, 705)}, color={'cn': (234, 180, 108), 'en': (234, 183, 108), 'jp': (233, 184, 105), 'tw': (243, 199, 104)}, button={'cn': (1148, 653, 1262, 705), 'en': (1147, 652, 1263, 701), 'jp': (1147, 652, 1263, 706), 'tw': (1148, 653, 1262, 705)}, file={'cn': './assets/cn/map/MAP_OFFENSIVE.png', 'en': './assets/en/map/MAP_OFFENSIVE.png', 'jp': './assets/jp/map/MAP_OFFENSIVE.png', 'tw': './assets/tw/map/MAP_OFFENSIVE.png'}) MAP_PREPARATION = Button(area={'cn': (854, 488, 1052, 548), 'en': (852, 489, 1054, 553), 'jp': (850, 485, 1051, 548), 'tw': (854, 488, 1052, 548)}, color={'cn': (236, 186, 115), 'en': (234, 179, 93), 'jp': (232, 181, 101), 'tw': (236, 186, 115)}, button={'cn': (854, 488, 1052, 548), 'en': (852, 489, 1054, 553), 'jp': (850, 485, 1051, 548), 'tw': (854, 488, 1052, 548)}, file={'cn': './assets/cn/map/MAP_PREPARATION.png', 'en': './assets/en/map/MAP_PREPARATION.png', 'jp': './assets/jp/map/MAP_PREPARATION.png', 'tw': './assets/tw/map/MAP_PREPARATION.png'}) MAP_PREPARATION_CANCEL = Button(area={'cn': (234, 12, 278, 47), 'en': (234, 12, 278, 47), 'jp': (234, 12, 278, 47), 'tw': (234, 12, 278, 47)}, color={'cn': (45, 46, 69), 'en': (45, 46, 69), 'jp': (45, 46, 69), 'tw': (45, 46, 69)}, button={'cn': (234, 12, 278, 47), 'en': (234, 12, 278, 47), 'jp': (234, 12, 278, 47), 'tw': (234, 12, 278, 47)}, file={'cn': './assets/cn/map/MAP_PREPARATION_CANCEL.png', 'en': './assets/en/map/MAP_PREPARATION_CANCEL.png', 'jp': './assets/jp/map/MAP_PREPARATION_CANCEL.png', 'tw': './assets/tw/map/MAP_PREPARATION_CANCEL.png'}) diff --git a/module/map/map_operation.py b/module/map/map_operation.py index f42abc9bb3..ef857fc995 100644 --- a/module/map/map_operation.py +++ b/module/map/map_operation.py @@ -103,7 +103,7 @@ def enter_map(self, button, mode='normal', skip_first_screenshot=True): Args: button: Campaign to enter. - mode (str): 'normal' or 'hard' or 'cd' + mode (str): 'normal' or 'hard' skip_first_screenshot (bool): """ logger.hr('Enter map') @@ -115,6 +115,8 @@ def enter_map(self, button, mode='normal', skip_first_screenshot=True): fleet_click = 0 checked_in_map = False self.stage_entrance = button + self.map_clear_percentage_prev = -1 + self.map_clear_percentage_timer.reset() with self.stat.new( genre=self.config.campaign_name, method=self.config.DropRecord_CombatRecord @@ -153,7 +155,7 @@ def enter_map(self, button, mode='normal', skip_first_screenshot=True): continue # Map preparation - if map_timer.reached() and self.handle_map_preparation(): + if map_timer.reached() and self.handle_map_mode_switch(mode) and self.handle_map_preparation(): self.map_get_info() self.handle_map_walk_speedup() self.handle_fast_forward() @@ -254,6 +256,46 @@ def enter_map_cancel(self, skip_first_screenshot=True): return True + def handle_map_mode_switch(self, mode): + """ + Args: + mode (str): 'normal' or 'hard' + + Returns: + bool: If map mode satisfied + Always True if map doesn't have mode switch in map preparation + """ + if not self.config.MAP_HAS_MODE_SWITCH: + return True + + if mode == 'normal': + if self.appear(MAP_MODE_SWITCH_NORMAL, offset=(20, 20)) \ + and MAP_MODE_SWITCH_NORMAL.match_appear_on(self.device.image): + logger.attr('MAP_MODE_SWITCH', 'normal') + return True + elif self.appear(MAP_MODE_SWITCH_HARD, offset=(20, 20), interval=2): + logger.attr('MAP_MODE_SWITCH', 'hard') + MAP_MODE_SWITCH_NORMAL.clear_offset() + self.device.click(MAP_MODE_SWITCH_NORMAL) + return False + else: + return False + elif mode == 'hard': + if self.appear(MAP_MODE_SWITCH_HARD, offset=(20, 20)) \ + and MAP_MODE_SWITCH_HARD.match_appear_on(self.device.image): + logger.attr('MAP_MODE_SWITCH', 'hard') + return True + if self.appear(MAP_MODE_SWITCH_NORMAL, offset=(20, 20), interval=2): + logger.attr('MAP_MODE_SWITCH', 'normal') + MAP_MODE_SWITCH_HARD.clear_offset() + self.device.click(MAP_MODE_SWITCH_HARD) + return False + else: + return False + else: + logger.error(f'handle_map_mode_switch: Unknown mode={mode}') + return False + def handle_map_preparation(self): """ Returns: