diff --git a/campaign/campaign_main/campaign_16_3.py b/campaign/campaign_main/campaign_16_3.py index efa371a1c..88f9f383d 100644 --- a/campaign/campaign_main/campaign_16_3.py +++ b/campaign/campaign_main/campaign_16_3.py @@ -32,6 +32,14 @@ MAP.spawn_data = [ {'battle': 2, 'enemy': 3}, {'battle': 3, 'boss': 1}, ] +MAP.spawn_data_loop = [ + {'battle': 0, 'enemy': 3}, + {'battle': 1, 'enemy': 6}, + {'battle': 2, 'enemy': 3}, + {'battle': 3}, + {'battle': 4}, + {'battle': 5, '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, \ @@ -57,7 +65,7 @@ class Campaign(CampaignBase): return True def battle_1(self): - if self.use_support_fleet: + if self.use_support_fleet and not self.map_is_clear_mode: self.air_strike(E3) self.clear_chosen_enemy(D3) return True @@ -76,7 +84,7 @@ class Campaign(CampaignBase): if boss: if not self.check_accessibility(boss[0], fleet='boss'): return self.clear_roadblocks([road_main]) - if self.use_support_fleet: + if self.use_support_fleet and not self.map_is_clear_mode: # at this stage the most right zone should be accessible self.goto(K5) self.air_strike(J6) diff --git a/campaign/campaign_main/campaign_16_4.py b/campaign/campaign_main/campaign_16_4.py index b7e9bddec..a4c026071 100644 --- a/campaign/campaign_main/campaign_16_4.py +++ b/campaign/campaign_main/campaign_16_4.py @@ -15,24 +15,24 @@ MAP.map_data = """ ME ++ ++ ++ -- -- ME ++ -- -- -- -- -- ME -- -- ++ ++ ME -- -- -- -- -- -- ME ++ -- ME -- ++ ++ -- - -- -- ME -- -- ME ++ -- ME ++ -- + -- -- -- ME -- ME ++ -- ME ++ -- -- __ -- ++ ++ -- ++ ME ME -- -- - SP -- -- ME -- -- ME ++ -- ++ ++ + SP -- -- 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 40 50 50 50 - 50 50 50 40 50 40 40 40 50 50 50 - 50 50 50 40 40 40 50 50 50 50 50 + 50 50 50 50 50 40 40 40 50 50 50 + 50 50 50 50 50 40 50 50 50 50 50 50 50 50 50 50 50 50 50 50 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': 5}, - {'battle': 1, 'enemy': 4}, + {'battle': 1, 'enemy': 3}, {'battle': 2, 'enemy': 5}, {'battle': 3}, {'battle': 4, 'boss': 1}, @@ -47,7 +47,7 @@ A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, K7, \ A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, K8, \ = MAP.flatten() -road_main = RoadGrids([D4, F5, G4, H3]) +road_main = RoadGrids([D5, F5, G4, H3]) class Config(ConfigBase): MAP_HAS_MAP_STORY = False @@ -59,17 +59,27 @@ class Campaign(CampaignBase): MAP = MAP def battle_0(self): - self.clear_chosen_enemy(D4) - return True - - def battle_1(self): - if self.use_support_fleet: - self.goto(D1) - self.air_strike(B1) - self.clear_chosen_enemy(F5) - return True + if self.clear_roadblocks([road_main]): + return True + if self.clear_potential_roadblocks([road_main]): + return True + if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0): + return True + return self.battle_default() def battle_2(self): + if self.use_support_fleet and not self.map_is_clear_mode: + self.goto(B3) + self.air_strike(B1) + if self.clear_roadblocks([road_main]): + return True + if self.clear_potential_roadblocks([road_main]): + return True + if self.clear_filter_enemy(self.ENEMY_FILTER, preserve=0): + return True + return self.battle_default() + + def battle_3(self): if self.clear_roadblocks([road_main]): return True if self.clear_potential_roadblocks([road_main]): @@ -83,7 +93,7 @@ class Campaign(CampaignBase): if boss: if not self.check_accessibility(boss[0], fleet='boss'): return self.clear_roadblocks([road_main]) - if self.use_support_fleet: + if self.use_support_fleet and not self.map_is_clear_mode: # at this stage the most right zone should be accessible self.goto(J6) self.air_strike(I8) diff --git a/dev_tools/map_extractor.py b/dev_tools/map_extractor.py index 35adb1547..c41ffae69 100644 --- a/dev_tools/map_extractor.py +++ b/dev_tools/map_extractor.py @@ -343,9 +343,18 @@ class MapData: self.map_id = data['id'] try: - self.spawn_data = self.parse_spawn_data(data) + self.event_enemy_data = None + self.event_enemy_data_loop = None + if self.map_id in MAP_EVENT_LIST: + self.event_enemy_data = self.extract_event_enemy_data(MAP_EVENT_LIST[self.map_id]['event_list']) + if data_loop is not None: + self.event_enemy_data_loop = self.extract_event_enemy_data(MAP_EVENT_LIST[self.map_id]['event_list_loop']) + else: + self.event_enemy_data_loop = None + + self.spawn_data = self.parse_spawn_data(data, self.event_enemy_data) if data_loop is not None: - self.spawn_data_loop = self.parse_spawn_data(data_loop) + self.spawn_data_loop = self.parse_spawn_data(data_loop, self.event_enemy_data_loop) if len(self.spawn_data) == len(self.spawn_data_loop) \ and all([s1 == s2 for s1, s2 in zip(self.spawn_data, self.spawn_data_loop)]): self.spawn_data_loop = None @@ -354,10 +363,10 @@ class MapData: # map_data # {0: {0: 6, 1: 8, 2: False, 3: 0}, ...} - self.map_data = self.parse_map_data(data['grids']) + self.map_data = self.parse_map_data(data['grids'], self.event_enemy_data) self.shape = tuple(np.max(list(self.map_data.keys()), axis=0)) if self.data_loop is not None: - self.map_data_loop = self.parse_map_data(data_loop['grids']) + self.map_data_loop = self.parse_map_data(data_loop['grids'], self.event_enemy_data_loop) if all([d1 == d2 for d1, d2 in zip(self.map_data.values(), self.map_data_loop.values())]): self.map_data_loop = None else: @@ -422,7 +431,7 @@ class MapData: __repr__ = __str__ - def parse_map_data(self, grids): + def parse_map_data(self, grids, event_enemy_data=None): map_data = {} offset_y = min([grid[0] for grid in grids.values()]) offset_x = min([grid[1] for grid in grids.values()]) @@ -435,11 +444,16 @@ class MapData: if info == '??': print(f'Unknown grid info. grid={location2node(loca)}, info={grid[3]}') map_data[loca] = info + if isinstance(event_enemy_data, list): + for wave in event_enemy_data: + for enemy in wave.values(): + loca = (enemy[1][1] - offset_x, enemy[1][0] - offset_y) + map_data[loca] = 'ME' return map_data @staticmethod - def parse_spawn_data(data): + def parse_spawn_data(data, event_enemy_data=None): try: battle_count = max(data['boss_refresh'], max(data['enemy_refresh'].keys())) except ValueError: @@ -450,6 +464,11 @@ class MapData: if count: spawn = spawn_data[index] spawn['enemy'] = spawn.get('enemy', 0) + count + if isinstance(event_enemy_data, list): + for index, wave in enumerate(event_enemy_data): + if len(wave): + spawn = spawn_data[index] + spawn['enemy'] = spawn.get('enemy', 0) + len(wave) if ''.join([str(item) for item in data['elite_refresh'].values()]) != '100': # Some data is incorrect for index, count in data['elite_refresh'].items(): if count: @@ -470,6 +489,15 @@ class MapData: return spawn_data + def extract_event_enemy_data(self, data): + extracted_data = [] + for event_id in data.values(): + event = MAP_EVENT_TEMPLATE[event_id] + for effect in event['effect'].values(): + if effect[0] == 'enemy': + extracted_data.append(effect[1]) + return extracted_data + def map_file_name(self): name = self.chapter_name.replace('-', '_').lower() if name[0].isdigit(): @@ -756,8 +784,8 @@ ENEMY_FILTER = '1L > 1M > 1E > 1C > 2L > 2M > 2E > 2C > 3L > 3M > 3E > 3C' LOADER = LuaLoader(FILE, server='CN') DATA = LOADER.load('./sharecfgdata/chapter_template.lua') DATA_LOOP = LOADER.load('./sharecfgdata/chapter_template_loop.lua') -# MAP_EVENT_LIST = LOADER.load('./sharecfg/map_event_list.lua') -# MAP_EVENT_TEMPLATE = LOADER.load('./sharecfg/map_event_template.lua') +MAP_EVENT_LIST = LOADER.load('./sharecfg/map_event_list.lua') +MAP_EVENT_TEMPLATE = LOADER.load('./sharecfg/map_event_template.lua') EXPECTATION_DATA = LOADER.load('./sharecfgdata/expedition_data_template.lua') ct = ChapterTemplate()