mirror of
https://github.com/LmeSzinc/AzurLaneAutoScript.git
synced 2025-01-09 10:17:38 +08:00
Add: W14 maps extracted
- Opt: _extract_stage_name for color just a little bit higher than 235 - Add: LuaLoader
This commit is contained in:
parent
93e2053b59
commit
825d0651d8
70
campaign/campaign_main/campaign_14_1.py
Normal file
70
campaign/campaign_main/campaign_14_1.py
Normal file
@ -0,0 +1,70 @@
|
||||
from module.campaign.campaign_base import CampaignBase
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import SelectedGrids, RoadGrids
|
||||
from module.logger import logger
|
||||
|
||||
MAP = CampaignMap('14-1')
|
||||
MAP.shape = 'H7'
|
||||
MAP.camera_data = ['D2', 'D5', 'E2', 'E5']
|
||||
MAP.camera_data_spawn_point = ['E5']
|
||||
MAP.map_data = """
|
||||
MB ++ ++ ME Me -- ME ME
|
||||
MB ME ++ ME __ ME -- --
|
||||
-- ME Me -- -- -- ME ++
|
||||
-- __ -- Me ME ME Me ++
|
||||
-- ++ MM -- ME Me -- --
|
||||
-- ME ME -- -- -- Me ME
|
||||
MB 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
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 2, 'mystery': 1},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 2},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5},
|
||||
{'battle': 6, '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:
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['0']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = False
|
||||
MAP_HAS_AMBUSH = True
|
||||
MAP_HAS_MYSTERY = True
|
||||
# ===== End of generated config =====
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_6(self):
|
||||
return self.fleet_boss.clear_boss()
|
74
campaign/campaign_main/campaign_14_2.py
Normal file
74
campaign/campaign_main/campaign_14_2.py
Normal file
@ -0,0 +1,74 @@
|
||||
from module.campaign.campaign_base import CampaignBase
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import SelectedGrids, RoadGrids
|
||||
from module.logger import logger
|
||||
from .14-1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('14-2')
|
||||
MAP.shape = 'I8'
|
||||
MAP.camera_data = ['D2', 'D6', 'F2', 'F6']
|
||||
MAP.camera_data_spawn_point = ['F2']
|
||||
MAP.map_data = """
|
||||
MB MB ++ -- ME -- ME ++ ++
|
||||
-- ME ++ ME -- Me -- SP SP
|
||||
-- -- Me Me Me -- -- ME ME
|
||||
ME __ -- Me -- ME -- -- ME
|
||||
MM ME -- -- Me -- -- ME ++
|
||||
++ ++ ++ -- ++ -- ME ME ME
|
||||
Me MB ME __ -- -- Me MM ME
|
||||
ME -- -- -- ME ME ++ ++ ME
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'mystery': 1},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 2},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5},
|
||||
{'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, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['0']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = False
|
||||
MAP_HAS_AMBUSH = True
|
||||
MAP_HAS_MYSTERY = True
|
||||
# ===== End of generated config =====
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_6(self):
|
||||
return self.fleet_boss.clear_boss()
|
74
campaign/campaign_main/campaign_14_3.py
Normal file
74
campaign/campaign_main/campaign_14_3.py
Normal file
@ -0,0 +1,74 @@
|
||||
from module.campaign.campaign_base import CampaignBase
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import SelectedGrids, RoadGrids
|
||||
from module.logger import logger
|
||||
from .14-1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('14-3')
|
||||
MAP.shape = 'J8'
|
||||
MAP.camera_data = ['D2', 'D6', 'G2', 'G6']
|
||||
MAP.camera_data_spawn_point = ['G2']
|
||||
MAP.map_data = """
|
||||
ME ++ ++ ++ -- ME ++ ++ ME ME
|
||||
-- Me ME -- ME -- ++ ++ ME --
|
||||
MB -- ME ME -- -- SP SP ME Me
|
||||
-- __ -- ++ -- ME Me -- ME --
|
||||
MB -- Me MM -- ME -- Me ++ ++
|
||||
ME -- Me ME -- Me ME -- ME ++
|
||||
++ -- ME __ ME Me ++ Me ME --
|
||||
MB -- MB MB -- ++ ++ -- ME --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'mystery': 1},
|
||||
{'battle': 1, 'enemy': 3},
|
||||
{'battle': 2, 'enemy': 2},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5},
|
||||
{'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 = ['0']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = False
|
||||
MAP_HAS_AMBUSH = True
|
||||
MAP_HAS_MYSTERY = True
|
||||
# ===== End of generated config =====
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_6(self):
|
||||
return self.fleet_boss.clear_boss()
|
78
campaign/campaign_main/campaign_14_4.py
Normal file
78
campaign/campaign_main/campaign_14_4.py
Normal file
@ -0,0 +1,78 @@
|
||||
from module.campaign.campaign_base import CampaignBase
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import SelectedGrids, RoadGrids
|
||||
from module.logger import logger
|
||||
from .14-1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('14-4')
|
||||
MAP.shape = 'K9'
|
||||
MAP.camera_data = ['D2', 'D6', 'D7', 'H2', 'H6', 'H7']
|
||||
MAP.camera_data_spawn_point = ['H2']
|
||||
MAP.map_data = """
|
||||
ME -- ++ ++ -- ME ME ME ++ ++ ++
|
||||
-- ME ME ME ME ME ME -- SP SP --
|
||||
MB -- __ -- -- -- -- -- ME -- --
|
||||
MB ME -- Me Me -- Me ++ ++ -- ME
|
||||
MM -- Me ME -- Me -- MA ++ -- ME
|
||||
++ ME ME -- ++ -- ME -- ME -- --
|
||||
++ -- ME Me Me ME -- -- -- -- ++
|
||||
-- -- -- -- -- __ -- ME ME -- ME
|
||||
-- -- ++ MB MB ++ ++ MM ME ME ME
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'mystery': 2},
|
||||
{'battle': 1},
|
||||
{'battle': 2},
|
||||
{'battle': 3},
|
||||
{'battle': 4},
|
||||
{'battle': 5},
|
||||
{'battle': 6},
|
||||
{'battle': 7, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, 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 = ['0']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = False
|
||||
MAP_HAS_AMBUSH = True
|
||||
MAP_HAS_MYSTERY = True
|
||||
# ===== End of generated config =====
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_7(self):
|
||||
return self.fleet_boss.clear_boss()
|
@ -4,6 +4,8 @@ import re
|
||||
from dev_tools.slpp import slpp
|
||||
from module.base.utils import location2node
|
||||
from module.map.utils import *
|
||||
from dev_tools.utils import LuaLoader
|
||||
from module.logger import logger
|
||||
|
||||
"""
|
||||
This an auto-tool to extract map files used in Alas.
|
||||
@ -523,10 +525,9 @@ class ChapterTemplate:
|
||||
"""
|
||||
This an auto-tool to extract map files used in Alas.
|
||||
|
||||
Git clone https://github.com/Dimbreath/AzurLaneData, to get the decrypted scripts.
|
||||
Git clone https://github.com/AzurLaneTools/AzurLaneLuaScripts, to get the decrypted scripts.
|
||||
Arguments:
|
||||
FILE: Folder contains `chapter_template.lua` and `expedition_data_template.lua`,
|
||||
Such as '<your_folder>/<server>/sharecfg'
|
||||
FILE: Path to your AzurLaneLuaScripts directory
|
||||
FOLDER: Folder to save, './campaign/test'
|
||||
KEYWORD: A keyword in map name, such as '短兵相接' (7-2, zh-CN), 'Counterattack!' (3-4, en-US)
|
||||
Or map id, such as 702 (7-2), 1140017 (Iris of Light and Dark D2)
|
||||
@ -543,11 +544,12 @@ SELECT = False
|
||||
OVERWRITE = True
|
||||
IS_WAR_ARCHIVES = False
|
||||
|
||||
DATA = load_lua_by_function(FILE, 'chapter_template.lua')
|
||||
DATA_LOOP = load_lua(FILE, 'chapter_template_loop.lua', prefix=41)
|
||||
MAP_EVENT_LIST = load_lua(FILE, 'map_event_list.lua', prefix=34)
|
||||
MAP_EVENT_TEMPLATE = load_lua(FILE, 'map_event_template.lua', prefix=38)
|
||||
EXPECTATION_DATA = load_lua_by_function(FILE, 'expedition_data_template.lua')
|
||||
LOADER = LuaLoader(FILE, server='CN')
|
||||
DATA = LOADER.load('./sharecfg/chapter_template.lua')
|
||||
DATA_LOOP = LOADER.load('./sharecfg/chapter_template_loop.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()
|
||||
ct.extract(ct.get_chapter_by_name(KEYWORD, select=SELECT), folder=FOLDER)
|
||||
|
107
dev_tools/utils.py
Normal file
107
dev_tools/utils.py
Normal file
@ -0,0 +1,107 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
from tqdm import tqdm
|
||||
from dev_tools.slpp import slpp
|
||||
|
||||
|
||||
class LuaLoader:
|
||||
"""
|
||||
Load decrypted scripts
|
||||
"""
|
||||
|
||||
def __init__(self, folder, server='zh-CN'):
|
||||
self.folder = folder
|
||||
self.server = server
|
||||
|
||||
def filepath(self, path):
|
||||
return os.path.join(self.folder, self.server, path)
|
||||
|
||||
def _load_file(self, file):
|
||||
"""
|
||||
Args:
|
||||
file (str):
|
||||
|
||||
Returns:
|
||||
dict:
|
||||
"""
|
||||
with open(self.filepath(file), 'r', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
result = {}
|
||||
matched = re.findall('function \(\)(.*?)end[()]', text, re.S)
|
||||
if matched:
|
||||
# Most files are in this format
|
||||
"""
|
||||
pg = pg or {}
|
||||
slot0 = pg
|
||||
slot0.chapter_template = {}
|
||||
|
||||
(function ()
|
||||
...
|
||||
end)()
|
||||
"""
|
||||
for func in matched:
|
||||
add = slpp.decode('{' + func + '}')
|
||||
result.update(add)
|
||||
elif text.startswith('pg'):
|
||||
# Old format
|
||||
"""
|
||||
pg = pg or {}
|
||||
pg.item_data_statistics = {
|
||||
...
|
||||
}
|
||||
"""
|
||||
# or
|
||||
"""
|
||||
pg = pg or {}
|
||||
|
||||
rawset(pg, "item_data_statistics", rawget(pg, "item_data_statistics") or {
|
||||
...
|
||||
}
|
||||
"""
|
||||
text = '{' + text.split('{', 2)[2]
|
||||
result = slpp.decode(text)
|
||||
else:
|
||||
# Another format, just bare data
|
||||
"""
|
||||
_G.pg.expedition_data_template[...] = {
|
||||
...
|
||||
}
|
||||
_G.pg.expedition_data_template[...] = {
|
||||
...
|
||||
}
|
||||
...
|
||||
"""
|
||||
text = '{' + text + '}'
|
||||
result = slpp.decode(text)
|
||||
|
||||
return result
|
||||
|
||||
def load(self, path):
|
||||
"""
|
||||
Load a lua file to python dictionary, handling the differences
|
||||
|
||||
Args:
|
||||
path (str): Relavice path from {folder}/{server}.
|
||||
Can be a file or a directory
|
||||
|
||||
Returns:
|
||||
dict:
|
||||
"""
|
||||
print(f'Loading {path}')
|
||||
if os.path.isdir(self.filepath(path)):
|
||||
result = {}
|
||||
for file in tqdm(os.listdir(self.filepath(path))):
|
||||
result.update(self._load_file(f'./{path}/{file}'))
|
||||
else:
|
||||
result = self._load_file(path)
|
||||
|
||||
print(f'{len(result.keys())} items loaded')
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Use example
|
||||
lua = LuaLoader(r'xxx/AzurLaneData', server='en-US')
|
||||
res = lua.load('./sharecfg/item_data_statistics.lua')
|
@ -142,7 +142,7 @@ class CampaignOcr(ModuleBase):
|
||||
x_skip = 10
|
||||
interval = 5
|
||||
x_color = np.convolve(np.mean(image, axis=0), np.ones(interval), 'valid') / interval
|
||||
x_list = np.where(x_color[x_skip:] > 235)[0]
|
||||
x_list = np.where(x_color[x_skip:] > 240)[0]
|
||||
if x_list is None or len(x_list) == 0:
|
||||
logger.warning('No interval between digit and text.')
|
||||
area = (0, 0, image.shape[1], image.shape[0])
|
||||
|
Loading…
Reference in New Issue
Block a user