diff --git a/alas.py b/alas.py index 6268c638a7..ffd0347e2f 100644 --- a/alas.py +++ b/alas.py @@ -407,6 +407,10 @@ def gems_farming(self): GemsFarming(config=self.config, device=self.device).run( name=self.config.Campaign_Name, folder=self.config.Campaign_Event, mode=self.config.Campaign_Mode) + def island_season_task(self): + from module.island.season_task import IslandSeasonTaskHandler + IslandSeasonTaskHandler(config=self.config, device=self.device).run() + def daemon(self): from module.daemon.daemon import AzurLaneDaemon AzurLaneDaemon(config=self.config, device=self.device, task="Daemon").run() diff --git a/assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png b/assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png new file mode 100644 index 0000000000..a9b9ed5b43 Binary files /dev/null and b/assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png differ diff --git a/assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png b/assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png new file mode 100644 index 0000000000..9a0a5a7c5d Binary files /dev/null and b/assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png differ diff --git a/assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png b/assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png new file mode 100644 index 0000000000..9bc97371e7 Binary files /dev/null and b/assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png differ diff --git a/assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png b/assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png new file mode 100644 index 0000000000..342fc33e85 Binary files /dev/null and b/assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png differ diff --git a/assets/cn/ui/DORMMENU_GOTO_ISLAND.png b/assets/cn/ui/DORMMENU_GOTO_ISLAND.png new file mode 100644 index 0000000000..c12990da84 Binary files /dev/null and b/assets/cn/ui/DORMMENU_GOTO_ISLAND.png differ diff --git a/assets/cn/ui/ISLAND_CHECK.png b/assets/cn/ui/ISLAND_CHECK.png new file mode 100644 index 0000000000..5cc9d2e78e Binary files /dev/null and b/assets/cn/ui/ISLAND_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_COMMISSION_CHECK.png b/assets/cn/ui/ISLAND_COMMISSION_CHECK.png new file mode 100644 index 0000000000..4ce32f4259 Binary files /dev/null and b/assets/cn/ui/ISLAND_COMMISSION_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png b/assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png new file mode 100644 index 0000000000..7e59589cf9 Binary files /dev/null and b/assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png differ diff --git a/assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png b/assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png new file mode 100644 index 0000000000..5cc9d2e78e Binary files /dev/null and b/assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png differ diff --git a/assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png b/assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png new file mode 100644 index 0000000000..bf485d50a3 Binary files /dev/null and b/assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png differ diff --git a/assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png b/assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png new file mode 100644 index 0000000000..f5ced938d6 Binary files /dev/null and b/assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png differ diff --git a/assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png b/assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png new file mode 100644 index 0000000000..f521a3ab77 Binary files /dev/null and b/assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png differ diff --git a/assets/cn/ui/ISLAND_MANAGE_CHECK.png b/assets/cn/ui/ISLAND_MANAGE_CHECK.png new file mode 100644 index 0000000000..3b003bd9a1 Binary files /dev/null and b/assets/cn/ui/ISLAND_MANAGE_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_MAP_CHECK.png b/assets/cn/ui/ISLAND_MAP_CHECK.png new file mode 100644 index 0000000000..359a0e82e1 Binary files /dev/null and b/assets/cn/ui/ISLAND_MAP_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_ORDER_CHECK.png b/assets/cn/ui/ISLAND_ORDER_CHECK.png new file mode 100644 index 0000000000..c1c45b4c63 Binary files /dev/null and b/assets/cn/ui/ISLAND_ORDER_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_CHECK.png b/assets/cn/ui/ISLAND_PHONE_CHECK.png new file mode 100644 index 0000000000..4fc9d3f773 Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.BUTTON.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.BUTTON.png new file mode 100644 index 0000000000..4f8cfd430e Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.BUTTON.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png new file mode 100644 index 0000000000..4fc9d3f773 Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.BUTTON.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.BUTTON.png new file mode 100644 index 0000000000..87e077896c Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.BUTTON.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png new file mode 100644 index 0000000000..4fc9d3f773 Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png new file mode 100644 index 0000000000..86eb463fdc Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.BUTTON.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.BUTTON.png new file mode 100644 index 0000000000..cec3089caf Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.BUTTON.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png new file mode 100644 index 0000000000..4fc9d3f773 Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png new file mode 100644 index 0000000000..383ae380e7 Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png differ diff --git a/assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png b/assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png new file mode 100644 index 0000000000..4fc9d3f773 Binary files /dev/null and b/assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png differ diff --git a/assets/cn/ui/ISLAND_SEASON_CHECK.png b/assets/cn/ui/ISLAND_SEASON_CHECK.png new file mode 100644 index 0000000000..eee046c932 Binary files /dev/null and b/assets/cn/ui/ISLAND_SEASON_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_SHOP_CHECK.png b/assets/cn/ui/ISLAND_SHOP_CHECK.png new file mode 100644 index 0000000000..0a196bb384 Binary files /dev/null and b/assets/cn/ui/ISLAND_SHOP_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_STORAGE_CHECK.png b/assets/cn/ui/ISLAND_STORAGE_CHECK.png new file mode 100644 index 0000000000..7b75edab6b Binary files /dev/null and b/assets/cn/ui/ISLAND_STORAGE_CHECK.png differ diff --git a/assets/cn/ui/ISLAND_STORAGE_EXIT.png b/assets/cn/ui/ISLAND_STORAGE_EXIT.png new file mode 100644 index 0000000000..13ef852eb8 Binary files /dev/null and b/assets/cn/ui/ISLAND_STORAGE_EXIT.png differ diff --git a/assets/cn/ui/ISLAND_TECHNOLOGY_CHECK.png b/assets/cn/ui/ISLAND_TECHNOLOGY_CHECK.png new file mode 100644 index 0000000000..0a0efa57ab Binary files /dev/null and b/assets/cn/ui/ISLAND_TECHNOLOGY_CHECK.png differ diff --git a/assets/island/technology/technology_chart_2.png b/assets/island/technology/technology_chart_2.png new file mode 100644 index 0000000000..b5d2632f26 Binary files /dev/null and b/assets/island/technology/technology_chart_2.png differ diff --git a/assets/island/technology/technology_chart_3.png b/assets/island/technology/technology_chart_3.png new file mode 100644 index 0000000000..1d92217970 Binary files /dev/null and b/assets/island/technology/technology_chart_3.png differ diff --git a/assets/island/technology/technology_chart_4.png b/assets/island/technology/technology_chart_4.png new file mode 100644 index 0000000000..e3d52ee5d2 Binary files /dev/null and b/assets/island/technology/technology_chart_4.png differ diff --git a/assets/island/technology/technology_chart_5.png b/assets/island/technology/technology_chart_5.png new file mode 100644 index 0000000000..45dbd4068d Binary files /dev/null and b/assets/island/technology/technology_chart_5.png differ diff --git a/assets/island/technology/technology_chart_6.png b/assets/island/technology/technology_chart_6.png new file mode 100644 index 0000000000..fd96aea061 Binary files /dev/null and b/assets/island/technology/technology_chart_6.png differ diff --git a/assets/jp/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png b/assets/jp/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png new file mode 100644 index 0000000000..342fc33e85 Binary files /dev/null and b/assets/jp/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png differ diff --git a/assets/jp/ui/ISLAND_COMMISSION_CHECK.png b/assets/jp/ui/ISLAND_COMMISSION_CHECK.png new file mode 100644 index 0000000000..4ce32f4259 Binary files /dev/null and b/assets/jp/ui/ISLAND_COMMISSION_CHECK.png differ diff --git a/assets/jp/ui/ISLAND_MANAGE_CHECK.png b/assets/jp/ui/ISLAND_MANAGE_CHECK.png new file mode 100644 index 0000000000..3b003bd9a1 Binary files /dev/null and b/assets/jp/ui/ISLAND_MANAGE_CHECK.png differ diff --git a/assets/jp/ui/ISLAND_MAP_CHECK.png b/assets/jp/ui/ISLAND_MAP_CHECK.png new file mode 100644 index 0000000000..359a0e82e1 Binary files /dev/null and b/assets/jp/ui/ISLAND_MAP_CHECK.png differ diff --git a/assets/jp/ui/ISLAND_ORDER_CHECK.png b/assets/jp/ui/ISLAND_ORDER_CHECK.png new file mode 100644 index 0000000000..c1c45b4c63 Binary files /dev/null and b/assets/jp/ui/ISLAND_ORDER_CHECK.png differ diff --git a/assets/jp/ui/ISLAND_SEASON_CHECK.png b/assets/jp/ui/ISLAND_SEASON_CHECK.png new file mode 100644 index 0000000000..eee046c932 Binary files /dev/null and b/assets/jp/ui/ISLAND_SEASON_CHECK.png differ diff --git a/assets/jp/ui/ISLAND_STORAGE_CHECK.png b/assets/jp/ui/ISLAND_STORAGE_CHECK.png new file mode 100644 index 0000000000..7b75edab6b Binary files /dev/null and b/assets/jp/ui/ISLAND_STORAGE_CHECK.png differ diff --git a/assets/jp/ui/ISLAND_TECHNOLOGY_CHECK.png b/assets/jp/ui/ISLAND_TECHNOLOGY_CHECK.png new file mode 100644 index 0000000000..0a0efa57ab Binary files /dev/null and b/assets/jp/ui/ISLAND_TECHNOLOGY_CHECK.png differ diff --git a/assets/mask/MASK_ISLAND_TECHNOLOGY.png b/assets/mask/MASK_ISLAND_TECHNOLOGY.png new file mode 100644 index 0000000000..d8a72e58fe Binary files /dev/null and b/assets/mask/MASK_ISLAND_TECHNOLOGY.png differ diff --git a/config/template.json b/config/template.json index 801cd23330..29d5426efa 100644 --- a/config/template.json +++ b/config/template.json @@ -1906,6 +1906,30 @@ "Storage": {} } }, + "IslandInfo": { + "IslandSeasonTask": { + "TaskDict": null + }, + "IslandTechnology": { + "TechnologyStatus": null + }, + "Storage": { + "Storage": {} + } + }, + "IslandSeasonTask": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "IslandSeasonTask", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "Storage": { + "Storage": {} + } + }, "Daemon": { "Daemon": { "EnterMap": true diff --git a/dev_tools/island_extractor.py b/dev_tools/island_extractor.py new file mode 100644 index 0000000000..5267d11c11 --- /dev/null +++ b/dev_tools/island_extractor.py @@ -0,0 +1,541 @@ +import re + +from dev_tools.slpp import slpp +from dev_tools.utils import LuaLoader + + +class IslandItem: + def __init__(self, item): + """ + In the file 'sharecfg/island_item_data_template.lua': + id: serial of this item + name: name in server, default to CN + pt_num: pt value of this item + manage_influence: restaurant influence + order_price: price in order system + """ + self.id = item['id'] + # self.name = item['name'] + self.pt_num = item['pt_num'] + self.manage_influence = item['manage_influence'] + self.order_price = item['order_price'] + + def encode(self): + data = { + # 'id': self.id, + 'name': { + 'cn': '', + 'en': '', + 'jp': '', + # 'tw': '', + }, + 'pt_num': self.pt_num, + 'manage_influence': self.manage_influence, + 'order_price': self.order_price, + } + return data + + +class IslandItemExtractor: + def __init__(self): + self.item = {} + + data = LOADER.load('sharecfg/island_item_data_template.lua', keyword='pg.base.island_item_data_template') + for index, item in data.items(): + if not isinstance(index, int) or 0 < index < 1000 or index > 100000: + continue + + self.item[item['id']] = IslandItem(item).encode() + + for index, name in self.extract_item_name('zh-CN').items(): + self.item[index]['name']['cn'] = name + for index, name in self.extract_item_name('en-US').items(): + self.item[index]['name']['en'] = name + for index, name in self.extract_item_name('ja-JP').items(): + self.item[index]['name']['jp'] = name + # for index, name in self.extract_item_name('zh-TW').items(): + # self.item[index]['name']['tw'] = name + + def extract_item_name(self, server): + LOADER.server = server + data = LOADER.load('sharecfg/island_item_data_template.lua', keyword='pg.base.island_item_data_template') + out = {} + for index, item in data.items(): + if not isinstance(index, int) or 0 < index < 1000 or index > 100000: + continue + out[item['id']] = item['name'] + + return out + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_ITEM = {') + lines.append(" 0: {'name': {'cn': '岛屿开发PT', 'en': 'Island Development Points', 'jp': '離島開発Pt'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0},") + for index, item in self.item.items(): + lines.append(f' {index}: {item},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +def unpack_ingredient_dic(dic): + try: + result = {} + for _, entry in dic.items(): + # print(entry) + result[entry[0]] = entry[1] + return result + except TypeError: + print(dic) + raise + + +class IslandRecipe: + def __init__(self, recipe): + """ + In the file 'sharecfg/island_formula.lua': + id: serial of this recipe + name: name in server, default to CN + workload: using time with unit 0.1 second. + commission_cost: a nested dict of ingredients, each being a pair of item id and count + production_limit: consecutive commission upper bound for one commission handle + commission_product: a nested dict of products, each (only one) being a pair of item id and count + second_product_display: a nested dict of products, each being a pair of item id and count. + """ + self.id = recipe['id'] + # self.name = recipe['name'] + self.workload = recipe['workload'] + self.commission_cost = recipe['commission_cost'] + # self.production_limit = recipe['production_limit'] + self.commission_product = recipe['commission_product'] + self.second_product_display = recipe['second_product_display'] + + def encode(self): + data = { + self.id: { + # 'name': self.name, + 'workload': self.workload, + 'commission_cost': unpack_ingredient_dic(self.commission_cost), + # 'production_limit': self.production_limit, + 'commission_product': unpack_ingredient_dic(self.commission_product), + 'second_product_display': unpack_ingredient_dic(self.second_product_display), + } + } + return data + + +class IslandRecipeExtractor: + def __init__(self): + self.recipe = {} + data = LOADER.load('sharecfg/island_formula.lua') + for index, item in data.items(): + if not isinstance(index, int) or not (index // 10000 < 700 or index // 10000 >= 990): + continue + if item['attribute'] in [1, 2, 3, 4, 6]: + self.recipe.update(IslandRecipe(item).encode()) + + # print(item['id'], + # item['name'], + # item['workload'] // 10, + # item['commission_cost'], + # item['production_limit'], + # item['commission_product'], + # item['second_product_display']) + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_RECIPE = {') + for index, recipe in self.recipe.items(): + lines.append(f' {index}: {recipe},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, '', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +def unpack_activity_formula(dic): + try: + result = [] + for _, entry in dic.items(): + result += [item for _, item in entry[1].items()] + return result + except TypeError: + print(dic) + + +class IslandProduction: + def __init__(self, slot): + """ + In the file 'sharecfg/island_production_slot.lua': + type: 1 = agriculture, 2 = mineral, 3 = animal, 4 = restaurant, 6 = industry + place: slot position + exclusion_slot: id of slots that are exclusive to this slot, not necessary for our implementation + formula: applicable recipes + activity_formula: activity id and activity recipes + """ + self.id = slot['id'] + self.attribute = slot['attribute'] + self.place = slot['place'] + self.formula = [item for _, item in slot['formula'].items()] + self.activity_formula = unpack_activity_formula(slot['activity_formula']) + + def encode(self): + data = { + self.id: { + 'attribute': self.attribute, + 'place': self.place, + 'formula': self.formula, + 'activity_formula': self.activity_formula, + } + } + return data + + +class IslandProductionExtractor: + def __init__(self): + self.slot = {} + data = LOADER.load('sharecfg/island_production_slot.lua') + for index, item in data.items(): + if not isinstance(index, int) or index < 9000 or index > 10000: + continue + # print(item['attribute'], item['place'], item['formula'], item['activity_formula']) + self.slot.update(IslandProduction(item).encode()) + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_SLOT = {') + for index, slot in self.slot.items(): + lines.append(f' {index}: {slot},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +class IslandShopItemExtractor: + def __init__(self): + self.item = {} + data = LOADER.load('sharecfg/island_shop_goods.lua', keyword='pg.base.island_shop_goods') + for index, item in data.items(): + if not isinstance(index, int) or index < 100000 or index >= 412000: + continue + try: + self.item[index] = { + 'resource_consume': {item['resource_consume'][1]: item['resource_consume'][2]}, + 'items': { + itm[1]: itm[2] for _, itm in item['items'].items() + }, + } + # print(self.item[index]) + except Exception: + print(index, item) + raise + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_SHOP_ITEM = {') + for index, item in self.item.items(): + lines.append(f' {index}: {item},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +def island_time_to_sql_time(island_time): + """ + island_time is like {0: {0: 2026, 1: 2, 2: 5}, 1: {0: 12, 1: 0, 2: 0}} + """ + year = island_time[0][0] + month = island_time[0][1] + day = island_time[0][2] + hour = island_time[1][0] + minute = island_time[1][1] + second = island_time[1][2] + return f'{year:04}-{month:02}-{day:02} {hour:02}:{minute:02}:{second:02}' + + +class IslandSeason: + def __init__(self, season): + """ + In the file 'sharecfg/island_season.lua': + id: serial of this season + time: time range of this season + task_list: list of tasks in this season + """ + # self.id = season['id'] + self.end_time = island_time_to_sql_time(season['time'][1]) + self.task_list = [task + 10000 - 100 if task in range(80001100, 80001131) else task for _, task in season['task_list'].items()] + + def encode(self): + data = { + 'end_time': self.end_time, + 'task_list': self.task_list, + } + return data + +class IslandSeasonExtractor: + def __init__(self): + self.season = {} + data = LOADER.load('sharecfg/island_season.lua') + for index, item in data.items(): + if not isinstance(index, int): + continue + # print(item['task_list'].values()) + self.season[item['id']] = IslandSeason(item).encode() + # print(self.season) + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_SEASON = {') + for index, season in self.season.items(): + lines.append(f' {index}: {season},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +class IslandSeasonalTaskExtractor(IslandSeasonExtractor): + def __init__(self): + super().__init__() + self.task_list = [] + for season_id, season in self.season.items(): + self.task_list += season['task_list'] + print(self.task_list) + self.task = {} + data = LOADER.load('sharecfg/island_task_target.lua', keyword='pg.base.island_task_target') + for index, item in data.items(): + if not isinstance(index, int): + continue + if item['id'] not in self.task_list: + continue + self.task[item['id']] = { + 'name': { + 'cn': '', + 'en': '', + 'jp': '', + # 'tw': '', + }, + 'type': item['type'], + } + if isinstance(item['target_param'], dict): + self.task[item['id']]['target'] = {item['target_param'][0]: item['target_num']} + else: + self.task[item['id']]['target'] = {} + + for index, name in self.extract_item_name('zh-CN').items(): + self.task[index]['name']['cn'] = name + for index, name in self.extract_item_name('en-US').items(): + self.task[index]['name']['en'] = name + for index, name in self.extract_item_name('ja-JP').items(): + self.task[index]['name']['jp'] = name + # for index, name in self.extract_item_name('zh-TW').items(): + # self.item[index]['name']['tw'] = name + + def extract_item_name(self, server): + LOADER.server = server + data = LOADER.load('sharecfg/island_task.lua', keyword='pg.base.island_task') + out = {} + index_shift = 10000 + for index, item in data.items(): + if not isinstance(index, int) or not item['target_id'][0] in self.task.keys(): + continue + out[item['target_id'][0]] = item['name'] + + return out + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_SEASONAL_TASK = {') + for index, task in self.task.items(): + lines.append(f' {index}: {task},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + +class IslandRestaurantExtractor: + def __init__(self): + self.restaurant = {} + data = LOADER.load('sharecfg/island_manage_restaurant.lua') + for index, item in data.items(): + if not isinstance(index, int): + continue + self.restaurant.update({ + item['id']: { + recipe[0]: recipe[1] for _, recipe in item['item_id'].items() + } + }) + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_RESTAURANT_RECIPE = {') + for index, restaurant in self.restaurant.items(): + lines.append(f' {index}: {restaurant},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +class IslandTechnology: + def __init__(self, item): + self.id = item['id'] + self.tech_belong = item['tech_belong'] + self.axis_x = item['axis'][0] + self.axis_y = item['axis'][1] + self.island_level = item['island_level'] + + def encode(self): + data = { + 'name': { + 'cn': '', + 'en': '', + 'jp': '', + # 'tw': '', + }, + 'tech_belong': self.tech_belong, + 'axis': (self.axis_x, self.axis_y), + 'island_level': self.island_level, + } + return data + +class IslandTechnologyExtractor: + def __init__(self): + self.item = {} + + data = LOADER.load('sharecfg/island_technology_template.lua', keyword='pg.base.island_technology_template') + for index, item in data.items(): + if not isinstance(index, int) or item['tech_belong'] == 1: + continue + + self.item[item['id']] = IslandTechnology(item).encode() + + for index, name in self.extract_item_name('zh-CN').items(): + self.item[index]['name']['cn'] = name + for index, name in self.extract_item_name('en-US').items(): + self.item[index]['name']['en'] = name + for index, name in self.extract_item_name('ja-JP').items(): + self.item[index]['name']['jp'] = name + # for index, name in self.extract_item_name('zh-TW').items(): + # self.item[index]['name']['tw'] = name + + def extract_item_name(self, server): + LOADER.server = server + data = LOADER.load('sharecfg/island_technology_template.lua', keyword='pg.base.island_technology_template') + out = {} + for index, item in data.items(): + if not isinstance(index, int) or item['tech_belong'] == 1: + continue + out[item['id']] = item['tech_name'] + + return out + + def encode(self): + lines = [] + lines.append('DIC_ISLAND_TECHNOLOGY = {') + for index, item in self.item.items(): + lines.append(f' {index}: {item},') + lines.append('}') + return lines + + def write(self, file): + print(f'writing {file}') + with open(file, 'w', encoding='utf-8') as f: + for text in self.encode(): + f.write(text + '\n') + + +if __name__ == '__main__': + FILE = '../AzurLaneLuaScripts' + LOADER = LuaLoader(FILE, server='CN') + save = './module/island/data.py' + + lines = [] + lines.append('# This file was automatically generated by dev_tools/island_extractor.py') + lines.append("# Don't modify it manually.") + lines.append('') + lines.append('DIC_ISLAND_PASSIVE_RECIPE = {') + lines.append(' 1: {"refresh_times": ["03:00"], "product": {2606: 1}},') + lines.append(' 2: {"refresh_times": ["03:00"], "product": {2606: 1}},') + lines.append(' 3: {"refresh_times": ["03:00"], "product": {2606: 1}},') + lines.append(' 4: {"refresh_times": ["03:00"], "product": {2606: 1}},') + lines.append(' 5: {"refresh_times": ["03:00"], "product": {2606: 1}},') + lines.append(' 6: {"refresh_times": ["03:00"], "product": {2606: 1}},') + lines.append(' 1001: {"refresh_times": ["03:00"], "product": {4001: 4}},') + lines.append(' 1002: {"refresh_times": ["03:00"], "product": {4001: 4}},') + lines.append(' 1003: {"refresh_times": ["03:00"], "product": {4002: 8}},') + lines.append(' 1004: {"refresh_times": ["03:00"], "product": {4002: 8}},') + lines.append(' 1005: {"refresh_times": ["03:00"], "product": {4003: 12}},') + lines.append(' 1006: {"refresh_times": ["03:00"], "product": {4003: 12}},') + lines.append(' 1007: {"refresh_times": ["03:00"], "product": {4004: 3}},') + lines.append(' 1008: {"refresh_times": ["03:00"], "product": {4004: 3}},') + lines.append(' 40101: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40102: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40103: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40104: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40105: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40106: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40107: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40108: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40109: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}},') + lines.append(' 40201: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40202: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40203: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40204: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40205: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40206: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40207: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40208: {"refresh_times": ["04:00", "18:00"], "product": {2800: 8}},') + lines.append(' 40209: {"refresh_times": ["04:00", "18:00"], "product": {2800: 8}},') + lines.append('}') + lines.append('') + + lines += IslandItemExtractor().encode() + lines.append('') + lines += IslandRecipeExtractor().encode() + lines.append('') + lines += IslandProductionExtractor().encode() + lines.append('') + lines += IslandShopItemExtractor().encode() + lines.append('') + lines += IslandSeasonExtractor().encode() + lines.append('') + lines += IslandSeasonalTaskExtractor().encode() + lines.append('') + lines += IslandRestaurantExtractor().encode() + lines.append('') + lines += IslandTechnologyExtractor().encode() + with open(save, 'w', encoding='utf-8') as f: + for text in lines: + f.write(text + '\n') diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 6f51599d8e..4349ca838e 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -9184,6 +9184,73 @@ } } }, + "IslandInfo": { + "IslandSeasonTask": { + "TaskDict": { + "type": "textarea", + "value": "" + } + }, + "IslandTechnology": { + "TechnologyStatus": { + "type": "textarea", + "value": "" + } + }, + "Storage": { + "Storage": { + "type": "storage", + "value": {}, + "valuetype": "ignore", + "display": "disabled" + } + } + }, + "IslandSeasonTask": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false, + "option": [ + true, + false + ] + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "IslandSeasonTask", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 0, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "00:00", + "display": "hide" + } + }, + "Storage": { + "Storage": { + "type": "storage", + "value": {}, + "valuetype": "ignore", + "display": "disabled" + } + } + }, "Daemon": { "Daemon": { "EnterMap": { diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 7e17ccd299..77ae27c77f 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -732,6 +732,16 @@ OpsiHazard1Leveling: value: 0 option: [ 0, 44, 22 ] +# =================== Island ==================== +IslandSeasonTask: + TaskDict: + type: textarea + value: |- +IslandTechnology: + TechnologyStatus: + type: textarea + value: |- + # ==================== Tools ==================== Daemon: diff --git a/module/config/argument/menu.json b/module/config/argument/menu.json index abdfe9c9b7..6140f08fa8 100644 --- a/module/config/argument/menu.json +++ b/module/config/argument/menu.json @@ -96,6 +96,14 @@ "OpsiCrossMonth" ] }, + "Island": { + "menu": "collapse", + "page": "setting", + "tasks": [ + "IslandInfo", + "IslandSeasonTask" + ] + }, "Tool": { "menu": "collapse", "page": "tool", diff --git a/module/config/argument/task.yaml b/module/config/argument/task.yaml index c6f20bb00d..1dea471381 100644 --- a/module/config/argument/task.yaml +++ b/module/config/argument/task.yaml @@ -325,6 +325,18 @@ Opsi: OpsiCrossMonth: - Scheduler +# =================== Island =================== +Island: + menu: 'collapse' + page: 'setting' + tasks: + IslandInfo: + - IslandSeasonTask + - IslandTechnology + IslandSeasonTask: + - Scheduler + + # ==================== Tool ==================== Tool: diff --git a/module/config/config_generated.py b/module/config/config_generated.py index fecd84a36e..a2e586cf43 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -435,6 +435,12 @@ class GeneratedConfig: # Group `OpsiHazard1Leveling` OpsiHazard1Leveling_TargetZone = 0 # 0, 44, 22 + # Group `IslandSeasonTask` + IslandSeasonTask_TaskDict = None + + # Group `IslandTechnology` + IslandTechnology_TechnologyStatus = None + # Group `Daemon` Daemon_EnterMap = True diff --git a/module/config/config_manual.py b/module/config/config_manual.py index f928f67f2d..1a77e1b4b6 100644 --- a/module/config/config_manual.py +++ b/module/config/config_manual.py @@ -22,6 +22,7 @@ def SERVER(self): > OpsiAshBeacon > OpsiDaily > OpsiShop > OpsiVoucher > OpsiAbyssal > OpsiStronghold > OpsiObscure > OpsiArchive + > IslandSeasonTask > Daily > Hard > OpsiAshBeacon > OpsiAshAssist > OpsiMonthBoss > Sos > EventSp > EventA > EventB > EventC > EventD > RaidDaily > CoalitionSp > WarArchives > MaritimeEscort diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 847c50e064..aaae74fbae 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -28,6 +28,10 @@ "name": "OpSi", "help": "" }, + "Island": { + "name": "Menu.Island.name", + "help": "Menu.Island.help" + }, "Tool": { "name": "Tools", "help": "" @@ -254,6 +258,14 @@ "name": "Cross Month Daily", "help": " ALAS will enter OpSi 10min before OpSi reset, wait until OpSi reset but not exit OpSi. Then do the daily, obscure, abyssal and meowfficer farming to get extra gold plates. When running dailies, settings in task \"OpSiDaily\" are used, the rest function are the same.\n IMPORTANT: Please do not touch the game while ALAS is waiting for OpSi reset." }, + "IslandInfo": { + "name": "Task.IslandInfo.name", + "help": "Task.IslandInfo.help" + }, + "IslandSeasonTask": { + "name": "Task.IslandSeasonTask.name", + "help": "Task.IslandSeasonTask.help" + }, "Daemon": { "name": "Normal Semi-auto", "help": "" @@ -2540,6 +2552,26 @@ "22": "22 | NA Ocean SW Sector B" } }, + "IslandSeasonTask": { + "_info": { + "name": "IslandSeasonTask._info.name", + "help": "IslandSeasonTask._info.help" + }, + "TaskDict": { + "name": "IslandSeasonTask.TaskDict.name", + "help": "IslandSeasonTask.TaskDict.help" + } + }, + "IslandTechnology": { + "_info": { + "name": "IslandTechnology._info.name", + "help": "IslandTechnology._info.help" + }, + "TechnologyStatus": { + "name": "IslandTechnology.TechnologyStatus.name", + "help": "IslandTechnology.TechnologyStatus.help" + } + }, "Daemon": { "_info": { "name": "Semi-auto Clicking", diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 604b90644a..b20b0b1407 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -28,6 +28,10 @@ "name": "セイレーン作戦", "help": "" }, + "Island": { + "name": "Menu.Island.name", + "help": "Menu.Island.help" + }, "Tool": { "name": "ツール", "help": "" @@ -254,6 +258,14 @@ "name": "Cross Month Daily", "help": " ALAS will enter OpSi 10min before OpSi reset, wait until OpSi reset but not exit OpSi. Then do the daily, obscure, abyssal and meowfficer farming to get extra gold plates. When running dailies, settings in task \"OpSiDaily\" are used, the rest function are the same.\n IMPORTANT: Please do not touch the game while ALAS is waiting for OpSi reset." }, + "IslandInfo": { + "name": "Task.IslandInfo.name", + "help": "Task.IslandInfo.help" + }, + "IslandSeasonTask": { + "name": "Task.IslandSeasonTask.name", + "help": "Task.IslandSeasonTask.help" + }, "Daemon": { "name": "半自動クリック", "help": "" @@ -2540,6 +2552,26 @@ "22": "22" } }, + "IslandSeasonTask": { + "_info": { + "name": "IslandSeasonTask._info.name", + "help": "IslandSeasonTask._info.help" + }, + "TaskDict": { + "name": "IslandSeasonTask.TaskDict.name", + "help": "IslandSeasonTask.TaskDict.help" + } + }, + "IslandTechnology": { + "_info": { + "name": "IslandTechnology._info.name", + "help": "IslandTechnology._info.help" + }, + "TechnologyStatus": { + "name": "IslandTechnology.TechnologyStatus.name", + "help": "IslandTechnology.TechnologyStatus.help" + } + }, "Daemon": { "_info": { "name": "Daemon._info.name", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index 399021004d..5d55eac89c 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -28,6 +28,10 @@ "name": "大世界", "help": "" }, + "Island": { + "name": "岛屿计划", + "help": "" + }, "Tool": { "name": "工具", "help": "" @@ -254,6 +258,14 @@ "name": "跨月每日", "help": " Alas将在大世界跨月重置之前10分钟进入大世界,等待大世界重置但不退出大世界,然后完成新一天的大世界每日、隐秘海域、深渊海域和短猫相接,以获得额外的金菜。运行大世界每日时,按\"大世界每日\"任务设置运行,其余同理。\n 重要:Alas等待跨月期间,请不要操作游戏。" }, + "IslandInfo": { + "name": "岛屿信息", + "help": "岛屿仪表盘" + }, + "IslandSeasonTask": { + "name": "赛季任务", + "help": "" + }, "Daemon": { "name": "半自动点击", "help": "" @@ -2540,6 +2552,26 @@ "22": "22 | NA海域西南B" } }, + "IslandSeasonTask": { + "_info": { + "name": "赛季任务", + "help": "" + }, + "TaskDict": { + "name": "任务列表", + "help": "Alas会自动导出列表" + } + }, + "IslandTechnology": { + "_info": { + "name": "岛屿科技", + "help": "" + }, + "TechnologyStatus": { + "name": "科技列表", + "help": "Alas会自动导出列表" + } + }, "Daemon": { "_info": { "name": "半自动点击", diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index ea98dfc75a..4389edd6ff 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -28,6 +28,10 @@ "name": "大世界", "help": "" }, + "Island": { + "name": "Menu.Island.name", + "help": "Menu.Island.help" + }, "Tool": { "name": "工具", "help": "" @@ -254,6 +258,14 @@ "name": "跨月每日", "help": " Alas將在大世界跨月重置之前10分鐘進入大世界,等待大世界重置但不退出大世界,然後完成新一天的大世界每日、隱秘海域、深淵海域和短貓相接,以獲得額外的金菜。運行大世界每日時,按\"大世界每日\"任務設定運行,其餘同理。\n 重要:Alas等待跨月期間,請不要操作遊戲。" }, + "IslandInfo": { + "name": "Task.IslandInfo.name", + "help": "Task.IslandInfo.help" + }, + "IslandSeasonTask": { + "name": "Task.IslandSeasonTask.name", + "help": "Task.IslandSeasonTask.help" + }, "Daemon": { "name": "半自動點擊", "help": "" @@ -2540,6 +2552,26 @@ "22": "22 | NA海域西南B" } }, + "IslandSeasonTask": { + "_info": { + "name": "IslandSeasonTask._info.name", + "help": "IslandSeasonTask._info.help" + }, + "TaskDict": { + "name": "IslandSeasonTask.TaskDict.name", + "help": "IslandSeasonTask.TaskDict.help" + } + }, + "IslandTechnology": { + "_info": { + "name": "IslandTechnology._info.name", + "help": "IslandTechnology._info.help" + }, + "TechnologyStatus": { + "name": "IslandTechnology.TechnologyStatus.name", + "help": "IslandTechnology.TechnologyStatus.help" + } + }, "Daemon": { "_info": { "name": "半自動點擊", diff --git a/module/island/assets.py b/module/island/assets.py new file mode 100644 index 0000000000..7b75255605 --- /dev/null +++ b/module/island/assets.py @@ -0,0 +1,10 @@ +from module.base.button import Button +from module.base.template import Template + +# This file was automatically generated by dev_tools/button_extract.py. +# Don't modify it manually. + +ISLAND_SEASON_TASK_SCROLL_AREA = Button(area={'cn': (1236, 171, 1237, 604), 'en': (1236, 171, 1237, 604), 'jp': (1236, 171, 1237, 604), 'tw': (1236, 171, 1237, 604)}, color={'cn': (186, 192, 191), 'en': (186, 192, 191), 'jp': (186, 192, 191), 'tw': (186, 192, 191)}, button={'cn': (1236, 171, 1237, 604), 'en': (1236, 171, 1237, 604), 'jp': (1236, 171, 1237, 604), 'tw': (1236, 171, 1237, 604)}, file={'cn': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png', 'en': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png', 'jp': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png', 'tw': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png'}) +ISLAND_TECHNOLOGY_TAB1 = Button(area={'cn': (20, 575, 109, 644), 'en': (20, 575, 109, 644), 'jp': (20, 575, 109, 644), 'tw': (20, 575, 109, 644)}, color={'cn': (76, 109, 130), 'en': (76, 109, 130), 'jp': (76, 109, 130), 'tw': (76, 109, 130)}, button={'cn': (20, 575, 109, 644), 'en': (20, 575, 109, 644), 'jp': (20, 575, 109, 644), 'tw': (20, 575, 109, 644)}, file={'cn': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png', 'en': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png', 'jp': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png', 'tw': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png'}) +TEMPLATE_ISLAND_SEASON_TASK_ICON = Template(file={'cn': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png', 'en': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png', 'jp': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png', 'tw': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_ICON.png'}) +TEMPLATE_ISLAND_SEASON_TASK_OBTAINED = Template(file={'cn': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png', 'en': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png', 'jp': './assets/jp/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png', 'tw': './assets/cn/island/TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.png'}) diff --git a/module/island/data.py b/module/island/data.py new file mode 100644 index 0000000000..c5d7b99e0f --- /dev/null +++ b/module/island/data.py @@ -0,0 +1,569 @@ +# This file was automatically generated by dev_tools/island_extractor.py +# Don't modify it manually. + +DIC_ISLAND_PASSIVE_RECIPE = { + 1: {"refresh_times": ["03:00"], "product": {2606: 1}}, + 2: {"refresh_times": ["03:00"], "product": {2606: 1}}, + 3: {"refresh_times": ["03:00"], "product": {2606: 1}}, + 4: {"refresh_times": ["03:00"], "product": {2606: 1}}, + 5: {"refresh_times": ["03:00"], "product": {2606: 1}}, + 6: {"refresh_times": ["03:00"], "product": {2606: 1}}, + 1001: {"refresh_times": ["03:00"], "product": {4001: 4}}, + 1002: {"refresh_times": ["03:00"], "product": {4001: 4}}, + 1003: {"refresh_times": ["03:00"], "product": {4002: 8}}, + 1004: {"refresh_times": ["03:00"], "product": {4002: 8}}, + 1005: {"refresh_times": ["03:00"], "product": {4003: 12}}, + 1006: {"refresh_times": ["03:00"], "product": {4003: 12}}, + 1007: {"refresh_times": ["03:00"], "product": {4004: 3}}, + 1008: {"refresh_times": ["03:00"], "product": {4004: 3}}, + 40101: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40102: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40103: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40104: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40105: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40106: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40107: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40108: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40109: {"refresh_times": ["03:00", "18:00"], "product": {2700: 8}}, + 40201: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40202: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40203: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40204: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40205: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40206: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40207: {"refresh_times": ["03:00", "18:00"], "product": {2800: 8}}, + 40208: {"refresh_times": ["04:00", "18:00"], "product": {2800: 8}}, + 40209: {"refresh_times": ["04:00", "18:00"], "product": {2800: 8}}, +} + +DIC_ISLAND_ITEM = { + 0: {'name': {'cn': '岛屿开发PT', 'en': 'Island Development Points', 'jp': '離島開発Pt'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1: {'name': {'cn': '开发资金', 'en': 'Development Funds', 'jp': '開発資金'}, 'pt_num': 0, 'manage_influence': 0, 'order_price': 1}, + 1000: {'name': {'cn': '小麦种子', 'en': 'Wheat Seeds', 'jp': '小麦の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1001: {'name': {'cn': '玉米种子', 'en': 'Corn Seeds', 'jp': 'とうもろこしの種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1002: {'name': {'cn': '旱稻种子', 'en': 'Upland Rice Seeds', 'jp': '陸稲の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1003: {'name': {'cn': '白菜种子', 'en': 'Napa Cabbage Seeds', 'jp': '白菜の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1004: {'name': {'cn': '胡萝卜种子', 'en': 'Carrot Seeds', 'jp': 'ニンジンの種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1005: {'name': {'cn': '土豆种子', 'en': 'Potato Seeds', 'jp': 'じゃがいもの種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1006: {'name': {'cn': '大豆种子', 'en': 'Soy Bean Seeds', 'jp': '大豆の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1007: {'name': {'cn': '洋葱种子', 'en': 'Onion Seeds', 'jp': '玉ねぎの種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1008: {'name': {'cn': '牧草种子', 'en': 'Grass Seeds', 'jp': '牧草の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1009: {'name': {'cn': '咖啡树种', 'en': 'Coffee Tree Seeds', 'jp': 'コーヒーの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1010: {'name': {'cn': '亚麻种子', 'en': 'Flax Seeds', 'jp': '亜麻の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1011: {'name': {'cn': '草莓种子', 'en': 'Strawberry Seeds', 'jp': 'いちごの種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1012: {'name': {'cn': '棉花种子', 'en': 'Cotton Seeds', 'jp': '綿の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1014: {'name': {'cn': '茶树种子', 'en': 'Tea Tree Seeds', 'jp': '茶の木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1015: {'name': {'cn': '薰衣草种子', 'en': 'Lavender Seeds', 'jp': 'ラベンダーの種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1016: {'name': {'cn': '苹果树种', 'en': 'Apple Tree Seeds', 'jp': 'りんごの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1017: {'name': {'cn': '柑橘树种', 'en': 'Citrus Fruit Tree Seeds', 'jp': '柑橘類の木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1018: {'name': {'cn': '香蕉树种', 'en': 'Banana Tree Seed', 'jp': 'バナナの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1019: {'name': {'cn': '芒果树种', 'en': 'Mango Tree Seeds', 'jp': 'マンゴーの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1020: {'name': {'cn': '柠檬树种', 'en': 'Lemon Tree Seed', 'jp': 'レモンの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1021: {'name': {'cn': '牛油果树种', 'en': 'Avocado Tree Seeds', 'jp': 'アボカドの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 1022: {'name': {'cn': '橡胶树种', 'en': 'Rubber Tree Seeds', 'jp': 'ゴムの木の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 2000: {'name': {'cn': '小麦', 'en': 'Wheat', 'jp': '小麦'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 8}, + 2001: {'name': {'cn': '玉米', 'en': 'Corn', 'jp': 'とうもろこし'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 8}, + 2002: {'name': {'cn': '大米', 'en': 'Rice', 'jp': '米'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 17}, + 2003: {'name': {'cn': '白菜', 'en': 'Napa Cabbage', 'jp': '白菜'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 14}, + 2004: {'name': {'cn': '胡萝卜', 'en': 'Carrot', 'jp': 'ニンジン'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 34}, + 2005: {'name': {'cn': '土豆', 'en': 'Potato', 'jp': 'じゃがいも'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 33}, + 2006: {'name': {'cn': '大豆', 'en': 'Soy Beans', 'jp': '大豆'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 14}, + 2007: {'name': {'cn': '洋葱', 'en': 'Onion', 'jp': '玉ねぎ'}, 'pt_num': 24, 'manage_influence': 0, 'order_price': 244}, + 2008: {'name': {'cn': '牧草', 'en': 'Grass', 'jp': '牧草'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 11}, + 2009: {'name': {'cn': '咖啡豆', 'en': 'Coffee Beans', 'jp': 'コーヒー豆'}, 'pt_num': 6, 'manage_influence': 0, 'order_price': 68}, + 2010: {'name': {'cn': '亚麻', 'en': 'Flax', 'jp': '亜麻'}, 'pt_num': 6, 'manage_influence': 0, 'order_price': 72}, + 2011: {'name': {'cn': '草莓', 'en': 'Strawberries', 'jp': 'いちご'}, 'pt_num': 5, 'manage_influence': 0, 'order_price': 54}, + 2012: {'name': {'cn': '棉花', 'en': 'Cotton', 'jp': '綿'}, 'pt_num': 6, 'manage_influence': 0, 'order_price': 92}, + 2014: {'name': {'cn': '茶叶', 'en': 'Tea Leaves', 'jp': '茶葉'}, 'pt_num': 14, 'manage_influence': 0, 'order_price': 118}, + 2015: {'name': {'cn': '薰衣草', 'en': 'Lavender', 'jp': 'ラベンダー'}, 'pt_num': 35, 'manage_influence': 0, 'order_price': 294}, + 2016: {'name': {'cn': '苹果', 'en': 'Apple', 'jp': 'りんご'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 50}, + 2017: {'name': {'cn': '柑橘', 'en': 'Citrus Fruit', 'jp': '柑橘フルーツ'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 65}, + 2018: {'name': {'cn': '香蕉', 'en': 'Banana', 'jp': 'バナナ'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 80}, + 2019: {'name': {'cn': '芒果', 'en': 'Mango', 'jp': 'マンゴー'}, 'pt_num': 18, 'manage_influence': 0, 'order_price': 180}, + 2020: {'name': {'cn': '柠檬', 'en': 'Lemon', 'jp': 'レモン'}, 'pt_num': 3, 'manage_influence': 0, 'order_price': 32}, + 2021: {'name': {'cn': '牛油果', 'en': 'Avocado', 'jp': 'アボカド'}, 'pt_num': 45, 'manage_influence': 0, 'order_price': 375}, + 2022: {'name': {'cn': '橡胶', 'en': 'Rubber', 'jp': 'ゴム'}, 'pt_num': 30, 'manage_influence': 0, 'order_price': 250}, + 2600: {'name': {'cn': '鲜肉', 'en': 'Fresh Meat', 'jp': '新鮮な肉'}, 'pt_num': 2, 'manage_influence': 0, 'order_price': 200}, + 2601: {'name': {'cn': '鸡蛋', 'en': 'Eggs', 'jp': '卵'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 55}, + 2602: {'name': {'cn': '禽肉', 'en': 'Poultry', 'jp': '鶏肉'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 20}, + 2603: {'name': {'cn': '牛奶', 'en': 'Milk', 'jp': '牛乳'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 136}, + 2604: {'name': {'cn': '皮料', 'en': 'Pelt', 'jp': '皮素材'}, 'pt_num': 10, 'manage_influence': 0, 'order_price': 95}, + 2605: {'name': {'cn': '羊毛', 'en': 'Wool', 'jp': '羊毛'}, 'pt_num': 72, 'manage_influence': 0, 'order_price': 600}, + 2606: {'name': {'cn': '新鲜蜂蜜', 'en': 'Fresh Honey', 'jp': '新鮮なはちみつ'}, 'pt_num': 2, 'manage_influence': 0, 'order_price': 200}, + 2700: {'name': {'cn': '煤炭', 'en': 'Coal', 'jp': '石炭'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 12}, + 2701: {'name': {'cn': '铜矿', 'en': 'Copper Ore', 'jp': '銅鉱石'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 100}, + 2702: {'name': {'cn': '铝矿', 'en': 'Bauxite Ore', 'jp': 'アルミ鉱石'}, 'pt_num': 30, 'manage_influence': 0, 'order_price': 300}, + 2703: {'name': {'cn': '铁矿', 'en': 'Iron Ore', 'jp': '鉄鉱石'}, 'pt_num': 18, 'manage_influence': 0, 'order_price': 180}, + 2704: {'name': {'cn': '硫矿', 'en': 'Sulfur', 'jp': '硫黄鉱石'}, 'pt_num': 80, 'manage_influence': 0, 'order_price': 700}, + 2705: {'name': {'cn': '银矿', 'en': 'Silver Ore', 'jp': '銀鉱石'}, 'pt_num': 240, 'manage_influence': 0, 'order_price': 1600}, + 2800: {'name': {'cn': '自然之木', 'en': 'Raw Timber', 'jp': '大自然の原木'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 12}, + 2801: {'name': {'cn': '实用之木', 'en': 'Workable Wood', 'jp': '実用の木材'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 125}, + 2802: {'name': {'cn': '精选之木', 'en': 'Premium Wood', 'jp': 'プレミアム木材'}, 'pt_num': 36, 'manage_influence': 0, 'order_price': 360}, + 2803: {'name': {'cn': '典雅之木', 'en': 'Elegant Wood', 'jp': 'エレガント木材'}, 'pt_num': 180, 'manage_influence': 0, 'order_price': 1200}, + 3000: {'name': {'cn': '咯咯鸡饲料', 'en': 'Clucky Clucky Bird Feed', 'jp': 'コッコートリの餌'}, 'pt_num': 3, 'manage_influence': 0, 'order_price': 25}, + 3001: {'name': {'cn': '哼哼猪饲料', 'en': 'Oinky Oinky Pig Feed', 'jp': 'ブーブーブタの餌'}, 'pt_num': 3, 'manage_influence': 0, 'order_price': 25}, + 3002: {'name': {'cn': '哞哞牛饲料', 'en': 'Moo Moo Cow Feed', 'jp': 'モーモーウシの餌'}, 'pt_num': 4, 'manage_influence': 0, 'order_price': 40}, + 3003: {'name': {'cn': '咩咩羊饲料', 'en': 'Baa Baa Sheep Feed', 'jp': 'メェメーヒツジの餌'}, 'pt_num': 4, 'manage_influence': 0, 'order_price': 40}, + 3004: {'name': {'cn': '面粉', 'en': 'Flour', 'jp': '小麦粉'}, 'pt_num': 6, 'manage_influence': 0, 'order_price': 50}, + 3005: {'name': {'cn': '冰咖啡', 'en': 'Iced Coffee', 'jp': 'アイスコーヒー'}, 'pt_num': 15, 'manage_influence': 190, 'order_price': 95}, + 3006: {'name': {'cn': '芝士', 'en': 'Cheese', 'jp': 'チーズ'}, 'pt_num': 55, 'manage_influence': 150, 'order_price': 550}, + 3007: {'name': {'cn': '拿铁', 'en': 'Latte', 'jp': 'ラテ'}, 'pt_num': 25, 'manage_influence': 180, 'order_price': 250}, + 3008: {'name': {'cn': '柑橘咖啡', 'en': 'Citrus Coffee', 'jp': 'シトラスコーヒー'}, 'pt_num': 25, 'manage_influence': 180, 'order_price': 190}, + 3009: {'name': {'cn': '苹果派', 'en': 'Apple Pie', 'jp': 'アップルパイ'}, 'pt_num': 35, 'manage_influence': 190, 'order_price': 385}, + 3010: {'name': {'cn': '草莓奶绿', 'en': 'Strawberry Milkshake', 'jp': 'いちごミルクシェイク'}, 'pt_num': 60, 'manage_influence': 240, 'order_price': 260}, + 3011: {'name': {'cn': '豆腐', 'en': 'Tofu', 'jp': '豆腐'}, 'pt_num': 35, 'manage_influence': 170, 'order_price': 340}, + 3012: {'name': {'cn': '肉末烧豆腐', 'en': 'Tofu with Minced Meat', 'jp': '肉そぼろ豆腐'}, 'pt_num': 155, 'manage_influence': 180, 'order_price': 1300}, + 3013: {'name': {'cn': '蛋包饭', 'en': 'Omurice', 'jp': 'オムライス'}, 'pt_num': 35, 'manage_influence': 240, 'order_price': 355}, + 3014: {'name': {'cn': '白菜豆腐汤', 'en': 'Cabbage and Tofu Soup', 'jp': '白菜と豆腐のスープ'}, 'pt_num': 65, 'manage_influence': 180, 'order_price': 425}, + 3015: {'name': {'cn': '蔬菜沙拉', 'en': 'Vegetable Salad', 'jp': '野菜サラダ'}, 'pt_num': 10, 'manage_influence': 160, 'order_price': 105}, + 3017: {'name': {'cn': '苹果汁', 'en': 'Apple Juice', 'jp': 'りんごジュース'}, 'pt_num': 10, 'manage_influence': 200, 'order_price': 105}, + 3018: {'name': {'cn': '香蕉芒果汁', 'en': 'Banana and Mango Juice', 'jp': 'バナナマンゴージュース'}, 'pt_num': 25, 'manage_influence': 190, 'order_price': 215}, + 3019: {'name': {'cn': '蜂蜜柠檬水', 'en': 'Honey and Lemon Water', 'jp': 'はちみつレモン水'}, 'pt_num': 15, 'manage_influence': 240, 'order_price': 140}, + 3020: {'name': {'cn': '草莓蜜沁', 'en': 'Strawberry Lemon Drink', 'jp': 'いちごレモンドリンク'}, 'pt_num': 50, 'manage_influence': 180, 'order_price': 270}, + 3021: {'name': {'cn': '薰衣草茶', 'en': 'Lavender Tea', 'jp': 'ラベンダーティー'}, 'pt_num': 240, 'manage_influence': 160, 'order_price': 1590}, + 3022: {'name': {'cn': '草莓蜂蜜冰沙', 'en': 'Strawberry Honey Frappé', 'jp': 'いちごのハニーフラッペ'}, 'pt_num': 95, 'manage_influence': 220, 'order_price': 790}, + 3023: {'name': {'cn': '玉米杯', 'en': 'Corn Cup', 'jp': 'コーンカップ'}, 'pt_num': 7, 'manage_influence': 180, 'order_price': 45}, + 3024: {'name': {'cn': '香橙派', 'en': 'Orange Pie', 'jp': 'オレンジパイ'}, 'pt_num': 35, 'manage_influence': 185, 'order_price': 375}, + 3025: {'name': {'cn': '芒果糯米饭', 'en': 'Sticky Rice with Mango', 'jp': 'マンゴーともち米の蒸し飯'}, 'pt_num': 60, 'manage_influence': 160, 'order_price': 510}, + 3026: {'name': {'cn': '香蕉可丽饼', 'en': 'Banana Crêpe', 'jp': 'バナナクレープ'}, 'pt_num': 30, 'manage_influence': 170, 'order_price': 230}, + 3028: {'name': {'cn': '草莓夏洛特', 'en': 'Strawberry Charlotte', 'jp': 'いちごシャルロット'}, 'pt_num': 200, 'manage_influence': 190, 'order_price': 1350}, + 3029: {'name': {'cn': '炭烤肉串', 'en': 'Coal-Roasted Skewer', 'jp': '炭火串焼き'}, 'pt_num': 40, 'manage_influence': 210, 'order_price': 390}, + 3030: {'name': {'cn': '禽肉土豆拼盘', 'en': "Chicken and Potato Hors d'Oeuvre", 'jp': '鶏肉とポテトの盛り合わせ'}, 'pt_num': 36, 'manage_influence': 230, 'order_price': 370}, + 3032: {'name': {'cn': '爆炒禽肉', 'en': 'Stir-Fried Chicken', 'jp': '鶏肉炒め'}, 'pt_num': 70, 'manage_influence': 220, 'order_price': 580}, + 3033: {'name': {'cn': '胡萝卜厚蛋烧', 'en': 'Rolled Carrot Omelette', 'jp': 'ニンジン厚焼き玉子'}, 'pt_num': 16, 'manage_influence': 180, 'order_price': 170}, + 3034: {'name': {'cn': '汉堡肉饭', 'en': 'Steak Bowl', 'jp': 'ハンバーグ丼'}, 'pt_num': 100, 'manage_influence': 150, 'order_price': 845}, + 3035: {'name': {'cn': '布料', 'en': 'Cloth', 'jp': '布生地'}, 'pt_num': 34, 'manage_influence': 0, 'order_price': 340}, + 3036: {'name': {'cn': '皮革', 'en': 'Leather', 'jp': '革'}, 'pt_num': 60, 'manage_influence': 0, 'order_price': 600}, + 3037: {'name': {'cn': '绳索', 'en': 'Rope', 'jp': 'ロープ'}, 'pt_num': 72, 'manage_influence': 0, 'order_price': 600}, + 3038: {'name': {'cn': '手套', 'en': 'Gloves', 'jp': '手袋'}, 'pt_num': 105, 'manage_influence': 0, 'order_price': 890}, + 3039: {'name': {'cn': '香囊', 'en': 'Aroma Sachet', 'jp': '香り袋'}, 'pt_num': 130, 'manage_influence': 0, 'order_price': 1100}, + 3040: {'name': {'cn': '鞋靴', 'en': 'Shoes', 'jp': '靴'}, 'pt_num': 350, 'manage_influence': 0, 'order_price': 2380}, + 3041: {'name': {'cn': '绷带', 'en': 'Wound Dressings', 'jp': '包帯'}, 'pt_num': 350, 'manage_influence': 0, 'order_price': 2380}, + 3042: {'name': {'cn': '炭笔', 'en': 'Charcoal Brush', 'jp': '木炭筆'}, 'pt_num': 30, 'manage_influence': 0, 'order_price': 300}, + 3043: {'name': {'cn': '电缆', 'en': 'Cable', 'jp': 'ケーブル'}, 'pt_num': 92, 'manage_influence': 0, 'order_price': 770}, + 3044: {'name': {'cn': '铁钉', 'en': 'Nails', 'jp': '鉄釘'}, 'pt_num': 66, 'manage_influence': 0, 'order_price': 660}, + 3045: {'name': {'cn': '硫酸', 'en': 'Chemicals', 'jp': '化学品'}, 'pt_num': 84, 'manage_influence': 0, 'order_price': 840}, + 3046: {'name': {'cn': '火药', 'en': 'Gunpowder', 'jp': '火薬'}, 'pt_num': 150, 'manage_influence': 0, 'order_price': 1200}, + 3047: {'name': {'cn': '刀叉餐具', 'en': 'Utensils', 'jp': '食器'}, 'pt_num': 380, 'manage_influence': 0, 'order_price': 2560}, + 3048: {'name': {'cn': '纸张', 'en': 'Paper', 'jp': '紙'}, 'pt_num': 6, 'manage_influence': 0, 'order_price': 175}, + 3049: {'name': {'cn': '记事本', 'en': 'Notebook', 'jp': 'メモ帳'}, 'pt_num': 120, 'manage_influence': 0, 'order_price': 1230}, + 3050: {'name': {'cn': '桌椅', 'en': 'Chair and Desk', 'jp': '机と椅子'}, 'pt_num': 80, 'manage_influence': 0, 'order_price': 810}, + 3051: {'name': {'cn': '精选木桶', 'en': 'Choice Wooden Barrel', 'jp': 'セレクション樽'}, 'pt_num': 190, 'manage_influence': 0, 'order_price': 1610}, + 3052: {'name': {'cn': '文件柜', 'en': 'Filing Cabinet', 'jp': 'ファイルキャビネット'}, 'pt_num': 430, 'manage_influence': 0, 'order_price': 2880}, + 3053: {'name': {'cn': '墨盒', 'en': 'Ink Cartridge', 'jp': 'インクカートリッジ'}, 'pt_num': 55, 'manage_influence': 0, 'order_price': 570}, + 3054: {'name': {'cn': '钟表', 'en': 'Clock', 'jp': '時計'}, 'pt_num': 310, 'manage_influence': 0, 'order_price': 2590}, + 3055: {'name': {'cn': '蓄电池', 'en': 'Battery', 'jp': '蓄電池'}, 'pt_num': 210, 'manage_influence': 0, 'order_price': 1750}, + 3056: {'name': {'cn': '净水滤芯', 'en': 'Water Filter', 'jp': '浄水フィルター'}, 'pt_num': 360, 'manage_influence': 0, 'order_price': 2400}, + 3059: {'name': {'cn': '欧姆蛋', 'en': 'Omelette', 'jp': 'オムレツ'}, 'pt_num': 2, 'manage_influence': 210, 'order_price': 50}, + 3101: {'name': {'cn': '经典豆腐套餐', 'en': 'Classic Tofu Combo', 'jp': '定番豆腐セット'}, 'pt_num': 230, 'manage_influence': 210, 'order_price': 1735}, + 3102: {'name': {'cn': '绵玉定食', 'en': 'Hearty Meal', 'jp': 'ふんわり定食'}, 'pt_num': 100, 'manage_influence': 220, 'order_price': 695}, + 3103: {'name': {'cn': '花香果韵', 'en': 'Floral and Fruity', 'jp': '香りも楽しめるフルーツセット'}, 'pt_num': 250, 'manage_influence': 210, 'order_price': 1700}, + 3104: {'name': {'cn': '缤纷果乐园', 'en': 'Colorful Fruit Paradise', 'jp': 'カラフル果物パラダイス'}, 'pt_num': 120, 'manage_influence': 215, 'order_price': 1000}, + 3105: {'name': {'cn': '阳光蜜水', 'en': 'Sunny Honey', 'jp': '太陽のハニー'}, 'pt_num': 70, 'manage_influence': 260, 'order_price': 410}, + 3106: {'name': {'cn': '香甜组合', 'en': 'Succulently Sweet', 'jp': 'スイートテイスト'}, 'pt_num': 70, 'manage_influence': 250, 'order_price': 560}, + 3107: {'name': {'cn': '果园二重奏', 'en': 'Orchard Duo', 'jp': '果樹園二重奏'}, 'pt_num': 70, 'manage_influence': 240, 'order_price': 615}, + 3108: {'name': {'cn': '莓果香橙甜点组', 'en': 'Berry and Orange Dessert', 'jp': 'ベリーオレンジスイーツ'}, 'pt_num': 260, 'manage_influence': 210, 'order_price': 1730}, + 3109: {'name': {'cn': '烤肉狂欢', 'en': 'The Carne-val', 'jp': '肉カーニバル'}, 'pt_num': 90, 'manage_influence': 230, 'order_price': 760}, + 3110: {'name': {'cn': '能量双拼套餐', 'en': 'Double Energy Combo', 'jp': 'エナジーダブルコンボ'}, 'pt_num': 210, 'manage_influence': 210, 'order_price': 1430}, + 3111: {'name': {'cn': '晨光活力组合', 'en': 'Morning Light Energy Combo', 'jp': '朝光活力コンビ'}, 'pt_num': 36, 'manage_influence': 250, 'order_price': 300}, + 3112: {'name': {'cn': '醒神套餐', 'en': 'The Wake-Up Call', 'jp': 'お目覚めブレックファスト'}, 'pt_num': 80, 'manage_influence': 240, 'order_price': 650}, + 3113: {'name': {'cn': '果香双杯乐', 'en': 'Fruity & Fruitier', 'jp': 'フルーツツインズ'}, 'pt_num': 90, 'manage_influence': 260, 'order_price': 450}, + 4001: {'name': {'cn': '秋菊', 'en': 'Autumn Chrysanthemum', 'jp': 'アキギク'}, 'pt_num': 40, 'manage_influence': 0, 'order_price': 400}, + 4002: {'name': {'cn': '芦苇花', 'en': 'Reed Flowers', 'jp': '葦の花'}, 'pt_num': 2, 'manage_influence': 0, 'order_price': 200}, + 4003: {'name': {'cn': '花生', 'en': 'Peanuts', 'jp': '落花生'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 150}, + 4004: {'name': {'cn': '松茸', 'en': 'Matsutake', 'jp': '松茸'}, 'pt_num': 95, 'manage_influence': 0, 'order_price': 800}, + 4005: {'name': {'cn': '秋月梨', 'en': 'Yoizuki Pear', 'jp': '宵月梨'}, 'pt_num': 5, 'manage_influence': 0, 'order_price': 70}, + 4006: {'name': {'cn': '秋月梨树种', 'en': 'Yoizuki Pear Seeds', 'jp': '宵月梨の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 4007: {'name': {'cn': '柿子', 'en': 'Kaki Persimmon', 'jp': '柿'}, 'pt_num': 24, 'manage_influence': 0, 'order_price': 200}, + 4008: {'name': {'cn': '柿子树种', 'en': 'Kaki Persimmon Seeds', 'jp': '柿の種'}, 'pt_num': 1, 'manage_influence': 0, 'order_price': 0}, + 4009: {'name': {'cn': '柿子饼', 'en': 'Dried Persimmon', 'jp': '干し柿'}, 'pt_num': 25, 'manage_influence': 280, 'order_price': 210}, + 4010: {'name': {'cn': '松茸鸡汤', 'en': 'Matsutake and Chicken Soup', 'jp': '松茸と鶏のスープ'}, 'pt_num': 135, 'manage_influence': 280, 'order_price': 900}, + 4011: {'name': {'cn': '秋季花束', 'en': 'Autumn Bouquet', 'jp': '秋のブーケ'}, 'pt_num': 70, 'manage_influence': 280, 'order_price': 705}, + 4012: {'name': {'cn': '花生油', 'en': 'Peanut Oil', 'jp': '落花生油'}, 'pt_num': 100, 'manage_influence': 280, 'order_price': 1005}, + 4013: {'name': {'cn': '胡萝卜秋梨汁', 'en': 'Carrot and Pear Juice', 'jp': 'ニンジンと梨のジュース'}, 'pt_num': 20, 'manage_influence': 280, 'order_price': 200}, + 4014: {'name': {'cn': '菊花茶', 'en': 'Chrysanthemum Tea', 'jp': '菊花の茶'}, 'pt_num': 100, 'manage_influence': 280, 'order_price': 840}, +} + +DIC_ISLAND_RECIPE = { + 101001: {'workload': 24000, 'commission_cost': {1000: 9}, 'commission_product': {2000: 162}, 'second_product_display': {}}, + 101002: {'workload': 24000, 'commission_cost': {1001: 9}, 'commission_product': {2001: 162}, 'second_product_display': {}}, + 101003: {'workload': 24000, 'commission_cost': {1008: 9}, 'commission_product': {2008: 108}, 'second_product_display': {}}, + 101004: {'workload': 84000, 'commission_cost': {1009: 9}, 'commission_product': {2009: 81}, 'second_product_display': {}}, + 101005: {'workload': 48000, 'commission_cost': {1002: 9}, 'commission_product': {2002: 162}, 'second_product_display': {}}, + 101006: {'workload': 24000, 'commission_cost': {1003: 9}, 'commission_product': {2003: 81}, 'second_product_display': {}}, + 101007: {'workload': 108000, 'commission_cost': {1005: 9}, 'commission_product': {2005: 243}, 'second_product_display': {}}, + 101008: {'workload': 42000, 'commission_cost': {1006: 9}, 'commission_product': {2006: 243}, 'second_product_display': {}}, + 101013: {'workload': 36000, 'commission_cost': {3000: 2}, 'commission_product': {2601: 5}, 'second_product_display': {2602: 4}}, + 101015: {'workload': 72000, 'commission_cost': {3001: 2}, 'commission_product': {2600: 4}, 'second_product_display': {}}, + 101016: {'workload': 54000, 'commission_cost': {3002: 2}, 'commission_product': {2603: 4}, 'second_product_display': {2604: 4}}, + 101018: {'workload': 180000, 'commission_cost': {3003: 2}, 'commission_product': {2605: 4}, 'second_product_display': {}}, + 401001: {'workload': 12000, 'commission_cost': {}, 'commission_product': {2700: 8}, 'second_product_display': {}}, + 401002: {'workload': 24000, 'commission_cost': {}, 'commission_product': {2701: 4}, 'second_product_display': {}}, + 401004: {'workload': 60000, 'commission_cost': {}, 'commission_product': {2702: 4}, 'second_product_display': {}}, + 401005: {'workload': 36000, 'commission_cost': {}, 'commission_product': {2703: 4}, 'second_product_display': {}}, + 401006: {'workload': 120000, 'commission_cost': {}, 'commission_product': {2704: 4}, 'second_product_display': {}}, + 401007: {'workload': 240000, 'commission_cost': {}, 'commission_product': {2705: 4}, 'second_product_display': {}}, + 402001: {'workload': 12000, 'commission_cost': {}, 'commission_product': {2800: 8}, 'second_product_display': {}}, + 402002: {'workload': 30000, 'commission_cost': {}, 'commission_product': {2801: 4}, 'second_product_display': {}}, + 402003: {'workload': 72000, 'commission_cost': {}, 'commission_product': {2802: 4}, 'second_product_display': {}}, + 402004: {'workload': 180000, 'commission_cost': {}, 'commission_product': {2803: 4}, 'second_product_display': {}}, + 501001: {'workload': 45000, 'commission_cost': {1016: 4}, 'commission_product': {2016: 32}, 'second_product_display': {}}, + 501002: {'workload': 45000, 'commission_cost': {1017: 4}, 'commission_product': {2017: 32}, 'second_product_display': {}}, + 501003: {'workload': 60000, 'commission_cost': {1018: 4}, 'commission_product': {2018: 32}, 'second_product_display': {}}, + 501004: {'workload': 90000, 'commission_cost': {1019: 4}, 'commission_product': {2019: 32}, 'second_product_display': {}}, + 501005: {'workload': 36000, 'commission_cost': {1020: 4}, 'commission_product': {2020: 48}, 'second_product_display': {}}, + 501006: {'workload': 120000, 'commission_cost': {1021: 4}, 'commission_product': {2021: 16}, 'second_product_display': {}}, + 501007: {'workload': 96000, 'commission_cost': {1022: 4}, 'commission_product': {2022: 32}, 'second_product_display': {}}, + 502001: {'workload': 24000, 'commission_cost': {1010: 3}, 'commission_product': {2010: 18}, 'second_product_display': {}}, + 502002: {'workload': 54000, 'commission_cost': {1011: 3}, 'commission_product': {2011: 54}, 'second_product_display': {}}, + 502003: {'workload': 36000, 'commission_cost': {1012: 3}, 'commission_product': {2012: 18}, 'second_product_display': {}}, + 502004: {'workload': 54000, 'commission_cost': {1014: 3}, 'commission_product': {2014: 36}, 'second_product_display': {}}, + 502005: {'workload': 108000, 'commission_cost': {1015: 3}, 'commission_product': {2015: 24}, 'second_product_display': {}}, + 502006: {'workload': 24000, 'commission_cost': {1004: 3}, 'commission_product': {2004: 36}, 'second_product_display': {}}, + 502007: {'workload': 54000, 'commission_cost': {1007: 3}, 'commission_product': {2007: 12}, 'second_product_display': {}}, + 601001: {'workload': 72000, 'commission_cost': {2006: 15}, 'commission_product': {3011: 1}, 'second_product_display': {}}, + 601002: {'workload': 48000, 'commission_cost': {3011: 2, 2600: 1}, 'commission_product': {3012: 1}, 'second_product_display': {}}, + 601003: {'workload': 24000, 'commission_cost': {2601: 4, 2002: 9}, 'commission_product': {3013: 1}, 'second_product_display': {}}, + 601004: {'workload': 36000, 'commission_cost': {2003: 6, 3011: 1}, 'commission_product': {3014: 1}, 'second_product_display': {}}, + 601005: {'workload': 12000, 'commission_cost': {2004: 2, 2003: 3, 2001: 1}, 'commission_product': {3015: 1}, 'second_product_display': {}}, + 601101: {'workload': 6000, 'commission_cost': {3012: 1, 3014: 1}, 'commission_product': {3101: 1}, 'second_product_display': {}}, + 601102: {'workload': 6000, 'commission_cost': {3013: 1, 3011: 1}, 'commission_product': {3102: 1}, 'second_product_display': {}}, + 602001: {'workload': 12000, 'commission_cost': {2016: 2}, 'commission_product': {3017: 1}, 'second_product_display': {}}, + 602002: {'workload': 18000, 'commission_cost': {2018: 1, 2019: 1}, 'commission_product': {3018: 1}, 'second_product_display': {}}, + 602003: {'workload': 12000, 'commission_cost': {2020: 3, 2606: 1}, 'commission_product': {3019: 1}, 'second_product_display': {}}, + 602004: {'workload': 24000, 'commission_cost': {2011: 5, 2020: 2}, 'commission_product': {3020: 1}, 'second_product_display': {}}, + 602005: {'workload': 48000, 'commission_cost': {2014: 6, 2015: 4}, 'commission_product': {3021: 1}, 'second_product_display': {}}, + 602006: {'workload': 36000, 'commission_cost': {2011: 10, 2606: 4}, 'commission_product': {3022: 1}, 'second_product_display': {}}, + 602101: {'workload': 6000, 'commission_cost': {3021: 1, 3017: 1}, 'commission_product': {3103: 1}, 'second_product_display': {}}, + 602102: {'workload': 6000, 'commission_cost': {3018: 1, 3022: 1}, 'commission_product': {3104: 1}, 'second_product_display': {}}, + 602103: {'workload': 6000, 'commission_cost': {3020: 1, 3019: 1}, 'commission_product': {3105: 1}, 'second_product_display': {}}, + 603001: {'workload': 6000, 'commission_cost': {2001: 3, 2603: 1}, 'commission_product': {3023: 1}, 'second_product_display': {}}, + 603002: {'workload': 36000, 'commission_cost': {3004: 5, 2016: 3}, 'commission_product': {3009: 1}, 'second_product_display': {}}, + 603003: {'workload': 36000, 'commission_cost': {2017: 3, 3004: 6}, 'commission_product': {3024: 1}, 'second_product_display': {}}, + 603004: {'workload': 24000, 'commission_cost': {2019: 3, 2002: 2}, 'commission_product': {3025: 1}, 'second_product_display': {}}, + 603005: {'workload': 18000, 'commission_cost': {2018: 2, 3004: 2}, 'commission_product': {3026: 1}, 'second_product_display': {}}, + 603006: {'workload': 42000, 'commission_cost': {2011: 1, 3006: 2, 3004: 2}, 'commission_product': {3028: 1}, 'second_product_display': {}}, + 603101: {'workload': 6000, 'commission_cost': {3025: 1, 3023: 1}, 'commission_product': {3106: 1}, 'second_product_display': {}}, + 603102: {'workload': 6000, 'commission_cost': {3026: 1, 3009: 1}, 'commission_product': {3107: 1}, 'second_product_display': {}}, + 603103: {'workload': 6000, 'commission_cost': {3028: 1, 3024: 1}, 'commission_product': {3108: 1}, 'second_product_display': {}}, + 604001: {'workload': 24000, 'commission_cost': {2600: 4}, 'commission_product': {3029: 1}, 'second_product_display': {}}, + 604002: {'workload': 36000, 'commission_cost': {2005: 6, 2602: 5}, 'commission_product': {3030: 1}, 'second_product_display': {}}, + 604004: {'workload': 30000, 'commission_cost': {2602: 3, 2007: 1}, 'commission_product': {3032: 1}, 'second_product_display': {}}, + 604005: {'workload': 12000, 'commission_cost': {2601: 5, 2004: 2}, 'commission_product': {3033: 1}, 'second_product_display': {}}, + 604006: {'workload': 30000, 'commission_cost': {2002: 12, 2600: 6, 2003: 2}, 'commission_product': {3034: 1}, 'second_product_display': {}}, + 604101: {'workload': 6000, 'commission_cost': {3029: 1, 3030: 1}, 'commission_product': {3109: 1}, 'second_product_display': {}}, + 604102: {'workload': 6000, 'commission_cost': {3034: 1, 3032: 1}, 'commission_product': {3110: 1}, 'second_product_display': {}}, + 701001: {'workload': 18000, 'commission_cost': {2010: 4}, 'commission_product': {3035: 1}, 'second_product_display': {}}, + 701002: {'workload': 60000, 'commission_cost': {2604: 1}, 'commission_product': {3036: 1}, 'second_product_display': {}}, + 701003: {'workload': 108000, 'commission_cost': {2012: 1, 2010: 1}, 'commission_product': {3037: 1}, 'second_product_display': {}}, + 701004: {'workload': 72000, 'commission_cost': {2022: 1, 3035: 1}, 'commission_product': {3038: 1}, 'second_product_display': {}}, + 701005: {'workload': 108000, 'commission_cost': {3035: 1, 2015: 1}, 'commission_product': {3039: 1}, 'second_product_display': {}}, + 701006: {'workload': 144000, 'commission_cost': {3036: 1, 2022: 1, 2605: 1}, 'commission_product': {3040: 1}, 'second_product_display': {}}, + 701007: {'workload': 48000, 'commission_cost': {2705: 1, 3035: 1, 2012: 1}, 'commission_product': {3041: 1}, 'second_product_display': {}}, + 701008: {'workload': 36000, 'commission_cost': {2700: 1, 2801: 1}, 'commission_product': {3042: 1}, 'second_product_display': {}}, + 701009: {'workload': 108000, 'commission_cost': {2701: 1, 2022: 1}, 'commission_product': {3043: 1}, 'second_product_display': {}}, + 701010: {'workload': 144000, 'commission_cost': {2703: 1}, 'commission_product': {3044: 1}, 'second_product_display': {}}, + 701011: {'workload': 72000, 'commission_cost': {2704: 1}, 'commission_product': {3045: 1}, 'second_product_display': {}}, + 701012: {'workload': 72000, 'commission_cost': {3045: 1, 2700: 1}, 'commission_product': {3046: 1}, 'second_product_display': {}}, + 701013: {'workload': 216000, 'commission_cost': {2705: 1}, 'commission_product': {3047: 1}, 'second_product_display': {}}, + 701014: {'workload': 36000, 'commission_cost': {2800: 10}, 'commission_product': {3048: 1}, 'second_product_display': {}}, + 701015: {'workload': 72000, 'commission_cost': {3048: 4, 2801: 1}, 'commission_product': {3049: 1}, 'second_product_display': {}}, + 701016: {'workload': 108000, 'commission_cost': {2801: 1, 2702: 1}, 'commission_product': {3050: 1}, 'second_product_display': {}}, + 701017: {'workload': 108000, 'commission_cost': {2802: 1, 3044: 1}, 'commission_product': {3051: 1}, 'second_product_display': {}}, + 701018: {'workload': 180000, 'commission_cost': {2803: 1, 3044: 1}, 'commission_product': {3052: 1}, 'second_product_display': {}}, + 701019: {'workload': 72000, 'commission_cost': {2700: 1, 2702: 1}, 'commission_product': {3053: 1}, 'second_product_display': {}}, + 701020: {'workload': 216000, 'commission_cost': {2705: 1, 2703: 1, 2701: 1}, 'commission_product': {3054: 1}, 'second_product_display': {}}, + 701021: {'workload': 108000, 'commission_cost': {3045: 1, 2701: 1, 2703: 1}, 'commission_product': {3055: 1}, 'second_product_display': {}}, + 701022: {'workload': 144000, 'commission_cost': {2700: 1, 2705: 1, 2012: 1}, 'commission_product': {3056: 1}, 'second_product_display': {}}, + 901001: {'workload': 6000, 'commission_cost': {2601: 1}, 'commission_product': {3059: 1}, 'second_product_display': {}}, + 901002: {'workload': 18000, 'commission_cost': {2009: 2}, 'commission_product': {3005: 1}, 'second_product_display': {}}, + 901003: {'workload': 54000, 'commission_cost': {2603: 8}, 'commission_product': {3006: 1}, 'second_product_display': {}}, + 901004: {'workload': 24000, 'commission_cost': {2009: 3, 2603: 2}, 'commission_product': {3007: 1}, 'second_product_display': {}}, + 901005: {'workload': 18000, 'commission_cost': {2017: 1, 2009: 3}, 'commission_product': {3008: 1}, 'second_product_display': {}}, + 901006: {'workload': 24000, 'commission_cost': {2014: 1, 2011: 1, 2603: 1}, 'commission_product': {3010: 1}, 'second_product_display': {}}, + 901101: {'workload': 6000, 'commission_cost': {3059: 1, 3007: 1}, 'commission_product': {3111: 1}, 'second_product_display': {}}, + 901102: {'workload': 6000, 'commission_cost': {3005: 1, 3006: 1}, 'commission_product': {3112: 1}, 'second_product_display': {}}, + 901103: {'workload': 6000, 'commission_cost': {3008: 1, 3010: 1}, 'commission_product': {3113: 1}, 'second_product_display': {}}, + 9900001: {'workload': 18000, 'commission_cost': {4006: 1}, 'commission_product': {4005: 8}, 'second_product_display': {}}, + 9900002: {'workload': 18000, 'commission_cost': {4008: 1}, 'commission_product': {4007: 4}, 'second_product_display': {}}, + 9900003: {'workload': 18000, 'commission_cost': {4007: 1}, 'commission_product': {4009: 1}, 'second_product_display': {}}, + 9900004: {'workload': 18000, 'commission_cost': {2602: 2, 4004: 1}, 'commission_product': {4010: 1}, 'second_product_display': {}}, + 9900005: {'workload': 18000, 'commission_cost': {4002: 2, 4001: 1}, 'commission_product': {4011: 1}, 'second_product_display': {}}, + 9900006: {'workload': 18000, 'commission_cost': {4003: 8}, 'commission_product': {4012: 1}, 'second_product_display': {}}, + 9900007: {'workload': 18000, 'commission_cost': {4005: 3, 2004: 2}, 'commission_product': {4013: 1}, 'second_product_display': {}}, + 9900008: {'workload': 18000, 'commission_cost': {4001: 2}, 'commission_product': {4014: 1}, 'second_product_display': {}}, +} + +DIC_ISLAND_SLOT = { + 9001: {'attribute': 1, 'place': 101, 'formula': [101001, 101002, 101003, 101004, 101005, 101006, 101007, 101008], 'activity_formula': []}, + 9002: {'attribute': 1, 'place': 101, 'formula': [101001, 101002, 101003, 101004, 101005, 101006, 101007, 101008], 'activity_formula': []}, + 9003: {'attribute': 1, 'place': 101, 'formula': [101001, 101002, 101003, 101004, 101005, 101006, 101007, 101008], 'activity_formula': []}, + 9004: {'attribute': 1, 'place': 101, 'formula': [101001, 101002, 101003, 101004, 101005, 101006, 101007, 101008], 'activity_formula': []}, + 9011: {'attribute': 2, 'place': 401, 'formula': [401001, 401002, 401004, 401005, 401006, 401007], 'activity_formula': []}, + 9012: {'attribute': 2, 'place': 401, 'formula': [401001, 401002, 401004, 401005, 401006, 401007], 'activity_formula': []}, + 9013: {'attribute': 2, 'place': 401, 'formula': [401001, 401002, 401004, 401005, 401006, 401007], 'activity_formula': []}, + 9014: {'attribute': 2, 'place': 401, 'formula': [401001, 401002, 401004, 401005, 401006, 401007], 'activity_formula': []}, + 9021: {'attribute': 2, 'place': 402, 'formula': [402001, 402002, 402003, 402004], 'activity_formula': []}, + 9022: {'attribute': 2, 'place': 402, 'formula': [402001, 402002, 402003, 402004], 'activity_formula': []}, + 9023: {'attribute': 2, 'place': 402, 'formula': [402001, 402002, 402003, 402004], 'activity_formula': []}, + 9024: {'attribute': 2, 'place': 402, 'formula': [402001, 402002, 402003, 402004], 'activity_formula': []}, + 9031: {'attribute': 3, 'place': 102, 'formula': [101013], 'activity_formula': []}, + 9032: {'attribute': 3, 'place': 102, 'formula': [101015], 'activity_formula': []}, + 9033: {'attribute': 3, 'place': 102, 'formula': [101016], 'activity_formula': []}, + 9034: {'attribute': 3, 'place': 102, 'formula': [101018], 'activity_formula': []}, + 9041: {'attribute': 4, 'place': 901, 'formula': [901001, 901002, 901003, 901004, 901005, 901006, 901101, 901102, 901103], 'activity_formula': []}, + 9042: {'attribute': 4, 'place': 901, 'formula': [901001, 901002, 901003, 901004, 901005, 901006, 901101, 901102, 901103], 'activity_formula': []}, + 9061: {'attribute': 4, 'place': 601, 'formula': [601001, 601002, 601003, 601004, 601005, 601101, 601102], 'activity_formula': [9900003, 9900004]}, + 9062: {'attribute': 4, 'place': 601, 'formula': [601001, 601002, 601003, 601004, 601005, 601101, 601102], 'activity_formula': [9900003, 9900004]}, + 9071: {'attribute': 4, 'place': 602, 'formula': [602001, 602002, 602003, 602004, 602005, 602006, 602101, 602102, 602103], 'activity_formula': [9900007, 9900008]}, + 9072: {'attribute': 4, 'place': 602, 'formula': [602001, 602002, 602003, 602004, 602005, 602006, 602101, 602102, 602103], 'activity_formula': [9900007, 9900008]}, + 9081: {'attribute': 4, 'place': 603, 'formula': [603001, 603002, 603003, 603004, 603005, 603006, 603101, 603102, 603103], 'activity_formula': []}, + 9082: {'attribute': 4, 'place': 603, 'formula': [603001, 603002, 603003, 603004, 603005, 603006, 603101, 603102, 603103], 'activity_formula': []}, + 9091: {'attribute': 4, 'place': 604, 'formula': [604001, 604002, 604004, 604005, 604006, 604101, 604102], 'activity_formula': []}, + 9092: {'attribute': 4, 'place': 604, 'formula': [604001, 604002, 604004, 604005, 604006, 604101, 604102], 'activity_formula': []}, + 9101: {'attribute': 1, 'place': 501, 'formula': [501001, 501002, 501003, 501004, 501005, 501006, 501007], 'activity_formula': [9900001, 9900002]}, + 9102: {'attribute': 1, 'place': 501, 'formula': [501001, 501002, 501003, 501004, 501005, 501006, 501007], 'activity_formula': [9900001, 9900002]}, + 9103: {'attribute': 1, 'place': 501, 'formula': [501001, 501002, 501003, 501004, 501005, 501006, 501007], 'activity_formula': [9900001, 9900002]}, + 9104: {'attribute': 1, 'place': 501, 'formula': [501001, 501002, 501003, 501004, 501005, 501006, 501007], 'activity_formula': [9900001, 9900002]}, + 9111: {'attribute': 1, 'place': 502, 'formula': [502001, 502002, 502003, 502004, 502005, 502006, 502007], 'activity_formula': []}, + 9112: {'attribute': 1, 'place': 502, 'formula': [502001, 502002, 502003, 502004, 502005, 502006, 502007], 'activity_formula': []}, + 9201: {'attribute': 6, 'place': 703, 'formula': [701014, 701015, 701016, 701017, 701018], 'activity_formula': []}, + 9202: {'attribute': 6, 'place': 703, 'formula': [701014, 701015, 701016, 701017, 701018], 'activity_formula': []}, + 9203: {'attribute': 6, 'place': 704, 'formula': [701008, 701009, 701010, 701011, 701012, 701013], 'activity_formula': []}, + 9204: {'attribute': 6, 'place': 704, 'formula': [701008, 701009, 701010, 701011, 701012, 701013], 'activity_formula': []}, + 9205: {'attribute': 6, 'place': 705, 'formula': [701019, 701020, 701021, 701022], 'activity_formula': []}, + 9206: {'attribute': 6, 'place': 705, 'formula': [701019, 701020, 701021, 701022], 'activity_formula': []}, + 9207: {'attribute': 6, 'place': 706, 'formula': [701001, 701002, 701003, 701004, 701005, 701006, 701007], 'activity_formula': [9900005, 9900006]}, + 9208: {'attribute': 6, 'place': 706, 'formula': [701001, 701002, 701003, 701004, 701005, 701006, 701007], 'activity_formula': [9900005, 9900006]}, +} + +DIC_ISLAND_SHOP_ITEM = { + 103000: {'resource_consume': {2000: 30}, 'items': {3000: 10}}, + 103001: {'resource_consume': {2001: 30}, 'items': {3001: 10}}, + 103002: {'resource_consume': {2008: 30}, 'items': {3002: 10}}, + 103003: {'resource_consume': {2008: 30}, 'items': {3003: 10}}, + 103004: {'resource_consume': {2000: 6}, 'items': {3004: 1}}, + 411000: {'resource_consume': {1: 20}, 'items': {1000: 1}}, + 411001: {'resource_consume': {1: 40}, 'items': {1001: 1}}, + 411002: {'resource_consume': {1: 40}, 'items': {1002: 1}}, + 411003: {'resource_consume': {1: 60}, 'items': {1003: 1}}, + 411004: {'resource_consume': {1: 100}, 'items': {1004: 1}}, + 411005: {'resource_consume': {1: 20}, 'items': {1005: 1}}, + 411006: {'resource_consume': {1: 60}, 'items': {1006: 1}}, + 411007: {'resource_consume': {1: 120}, 'items': {1007: 1}}, + 411008: {'resource_consume': {1: 20}, 'items': {1008: 1}}, + 411009: {'resource_consume': {1: 120}, 'items': {1009: 1}}, + 411010: {'resource_consume': {1: 60}, 'items': {1010: 1}}, + 411011: {'resource_consume': {1: 120}, 'items': {1011: 1}}, + 411012: {'resource_consume': {1: 80}, 'items': {1012: 1}}, + 411014: {'resource_consume': {1: 150}, 'items': {1014: 1}}, + 411015: {'resource_consume': {1: 160}, 'items': {1015: 1}}, + 411016: {'resource_consume': {1: 100}, 'items': {1016: 1}}, + 411017: {'resource_consume': {1: 120}, 'items': {1017: 1}}, + 411018: {'resource_consume': {1: 140}, 'items': {1018: 1}}, + 411019: {'resource_consume': {1: 180}, 'items': {1019: 1}}, + 411020: {'resource_consume': {1: 80}, 'items': {1020: 1}}, + 411021: {'resource_consume': {1: 240}, 'items': {1021: 1}}, + 411022: {'resource_consume': {1: 280}, 'items': {1022: 1}}, + 411023: {'resource_consume': {1: 120}, 'items': {4006: 1}}, + 411024: {'resource_consume': {1: 180}, 'items': {4008: 1}}, +} + +DIC_ISLAND_SEASON = { + 1: {'end_time': '2026-02-05 12:00:00', 'task_list': [80011001, 80011002, 80011003, 80011004, 80011005, 80011006, 80011007, 80011008, 80011009, 80011010, 80011011, 80011012, 80011013, 80011014, 80011015, 80011016, 80011017, 80011018, 80011019, 80011020, 80011021, 80011022, 80011023, 80011024, 80011025, 80011026, 80011027, 80011028, 80011029, 80011030]}, +} + +DIC_ISLAND_SEASONAL_TASK = { + 80011001: {'name': {'cn': '麦田守望', 'en': 'Watching the Fields', 'jp': '畑の見張り'}, 'type': 4, 'target': {2000: 500}}, + 80011002: {'name': {'cn': '动物食品', 'en': 'The Beasts Hunger', 'jp': 'アニマルフード'}, 'type': 4, 'target': {2008: 500}}, + 80011003: {'name': {'cn': '开拓豆源', 'en': 'Beans or Bust', 'jp': '豆供給開拓'}, 'type': 4, 'target': {2006: 500}}, + 80011004: {'name': {'cn': '稻米供应', 'en': 'More Rice!', 'jp': 'お米生産'}, 'type': 4, 'target': {2002: 500}}, + 80011005: {'name': {'cn': '黄金粮仓', 'en': 'Golden Granary', 'jp': '黄金米蔵'}, 'type': 4, 'target': {2001: 500}}, + 80011006: {'name': {'cn': '橙色活力', 'en': 'The Juiciest of Oranges', 'jp': '元気オレンジ'}, 'type': 4, 'target': {2004: 250}}, + 80011007: {'name': {'cn': '乳品补给', 'en': 'Donations of Dairy', 'jp': 'ミルク補給'}, 'type': 4, 'target': {2603: 250}}, + 80011008: {'name': {'cn': '甜蜜引擎', 'en': 'Sugar in the Tank', 'jp': 'スイートエンジン'}, 'type': 4, 'target': {3017: 250}}, + 80011009: {'name': {'cn': '咖啡供应', 'en': 'Needs More Coffee', 'jp': 'コーヒー供給'}, 'type': 4, 'target': {3005: 250}}, + 80011010: {'name': {'cn': '烤肉能量', 'en': 'Meat Is Energy', 'jp': '焼き肉エナジー'}, 'type': 4, 'target': {3029: 250}}, + 80011011: {'name': {'cn': '调味基础', 'en': 'Basic Seasoning', 'jp': '味付基本'}, 'type': 4, 'target': {2007: 100}}, + 80011012: {'name': {'cn': '健康饮食', 'en': 'A Healthy Menu', 'jp': 'ヘルシー献立'}, 'type': 4, 'target': {3015: 100}}, + 80011013: {'name': {'cn': '营养组合', 'en': 'Nutritional Combos', 'jp': '栄養セット'}, 'type': 4, 'target': {3033: 100}}, + 80011014: {'name': {'cn': '拿铁时光', 'en': 'Latte Time', 'jp': 'ラテタイム'}, 'type': 4, 'target': {3007: 100}}, + 80011015: {'name': {'cn': '禽肉快炒', 'en': 'Stir-Fry Resupply', 'jp': '肉を炒めて'}, 'type': 4, 'target': {3032: 100}}, + 80011016: {'name': {'cn': '便携快餐', 'en': 'Fast Food', 'jp': 'タイパ食事'}, 'type': 4, 'target': {3034: 50}}, + 80011017: {'name': {'cn': '首次接收', 'en': 'Your First Receipt', 'jp': '初めての接収'}, 'type': 13, 'target': {}}, + 80011018: {'name': {'cn': '稳定入库', 'en': 'Safely Stored', 'jp': '安心納品'}, 'type': 13, 'target': {}}, + 80011019: {'name': {'cn': '定期补给', 'en': 'Regular Resupply', 'jp': '定期補充'}, 'type': 13, 'target': {}}, + 80011020: {'name': {'cn': '高效接收', 'en': 'Efficient Delivery', 'jp': '高効率納品'}, 'type': 13, 'target': {}}, + 80011021: {'name': {'cn': '补给充足', 'en': 'Well Stocked', 'jp': '在庫は余裕'}, 'type': 13, 'target': {}}, + 80011022: {'name': {'cn': '永续储备', 'en': 'Sustainable Reserves', 'jp': '備蓄は永久的'}, 'type': 13, 'target': {}}, + 80011023: {'name': {'cn': '发展根基', 'en': 'Foundation for Development', 'jp': '発展の礎'}, 'type': 13, 'target': {}}, + 80011024: {'name': {'cn': '初识订单', 'en': 'Your First Request', 'jp': '初めての依頼'}, 'type': 3, 'target': {}}, + 80011025: {'name': {'cn': '稳定交付', 'en': 'A Reliable Helper', 'jp': '安心依頼'}, 'type': 3, 'target': {}}, + 80011026: {'name': {'cn': '坚实后盾', 'en': 'Firm Support', 'jp': '堅実なサポート'}, 'type': 3, 'target': {}}, + 80011027: {'name': {'cn': '订单专家', 'en': 'Request Master', 'jp': '依頼のプロ'}, 'type': 3, 'target': {}}, + 80011028: {'name': {'cn': '发展支柱', 'en': 'Pillar of Development', 'jp': '発展の柱'}, 'type': 3, 'target': {}}, + 80011029: {'name': {'cn': '开发核心', 'en': 'Core of Development', 'jp': '発展の中心'}, 'type': 3, 'target': {}}, + 80011030: {'name': {'cn': '繁荣之基', 'en': 'Foundation for Prosperity', 'jp': '繁栄の礎'}, 'type': 3, 'target': {}}, +} + +DIC_ISLAND_RESTAURANT_RECIPE = { + 601: {3011: 601001, 3012: 601002, 3013: 601003, 3014: 601004, 3015: 601005, 3101: 601101, 3102: 601102}, + 602: {3017: 602001, 3018: 602002, 3019: 602003, 3020: 602004, 3021: 602005, 3022: 602006, 3103: 602101, 3104: 602102, 3105: 602103}, + 603: {3023: 603001, 3009: 603002, 3024: 603003, 3025: 603004, 3026: 603005, 3028: 603006, 3106: 603101, 3107: 603102, 3108: 603103}, + 604: {3029: 604001, 3030: 604002, 3032: 604004, 3033: 604005, 3034: 604006, 3109: 604101, 3110: 604102}, + 901: {3059: 901001, 3005: 901002, 3006: 901003, 3007: 901004, 3008: 901005, 3010: 901006, 3111: 901101, 3112: 901102, 3113: 901103}, +} + +DIC_ISLAND_TECHNOLOGY = { + 210101: {'name': {'cn': '解锁林场伐木岗位', 'en': 'Unlock: Logging Slot', 'jp': '開放:伐採配置枠'}, 'tech_belong': 2, 'axis': (1, 1), 'island_level': 5}, + 220101: {'name': {'cn': '解锁矿山采矿岗位', 'en': 'Unlock: Mining Slot', 'jp': '開放:鉱山採掘配置枠'}, 'tech_belong': 2, 'axis': (1, 6.5), 'island_level': 6}, + 220501: {'name': {'cn': '手动采矿效率提升I', 'en': 'Manual Mining Efficiency+ I', 'jp': '手動採掘効率+I'}, 'tech_belong': 2, 'axis': (3, 10), 'island_level': 7}, + 210401: {'name': {'cn': '手动伐木恢复加快', 'en': 'Manual Logging Resource Recovery+', 'jp': '手動伐採資源回復+'}, 'tech_belong': 2, 'axis': (3.5, 4.5), 'island_level': 8}, + 220201: {'name': {'cn': '铝矿勘探技术', 'en': 'Bauxite Mining Techniques', 'jp': 'アルミ鉱石探鉱'}, 'tech_belong': 2, 'axis': (4, 8.5), 'island_level': 9}, + 220401: {'name': {'cn': '手动采矿恢复加快', 'en': 'Manual Mining Resource Recovery+', 'jp': '手動採掘資源回復+'}, 'tech_belong': 2, 'axis': (6, 10), 'island_level': 9}, + 210102: {'name': {'cn': '林场伐木岗位增加I', 'en': 'Logging Slot+ I', 'jp': '伐採配置枠+I'}, 'tech_belong': 2, 'axis': (5, 1), 'island_level': 11}, + 210201: {'name': {'cn': '实用之木生产技术', 'en': 'Workable Wood Harvesting Techniques', 'jp': '実用の木材伐採'}, 'tech_belong': 2, 'axis': (4, 3), 'island_level': 11}, + 220202: {'name': {'cn': '铁矿勘探技术', 'en': 'Iron Ore Exploration Techniques', 'jp': '鉄鉱石探鉱'}, 'tech_belong': 2, 'axis': (8, 8.5), 'island_level': 12}, + 210501: {'name': {'cn': '手动伐木效率提升I', 'en': 'Manual Logging Efficiency+ I', 'jp': '手動伐採効率+I'}, 'tech_belong': 2, 'axis': (6.5, 4.5), 'island_level': 13}, + 220502: {'name': {'cn': '手动采矿效率提升II', 'en': 'Manual Mining Efficiency+ II', 'jp': '手動採掘効率+II'}, 'tech_belong': 2, 'axis': (9, 10), 'island_level': 15}, + 220102: {'name': {'cn': '矿山采矿岗位增加I', 'en': 'Mining Slot+ I', 'jp': '採掘配置枠+I'}, 'tech_belong': 2, 'axis': (9, 6.5), 'island_level': 16}, + 220203: {'name': {'cn': '硫矿勘探技术', 'en': 'Sulfur Deposit Exploration Techniques', 'jp': '硫黄鉱石探鉱'}, 'tech_belong': 2, 'axis': (11, 8.5), 'island_level': 16}, + 210202: {'name': {'cn': '精选之木生产技术', 'en': 'Premium Wood Harvesting Techniques', 'jp': 'プレミアム木材伐採'}, 'tech_belong': 2, 'axis': (9, 3), 'island_level': 17}, + 210502: {'name': {'cn': '手动伐木效率提升II', 'en': 'Manual Logging Efficiency+ II', 'jp': '手動伐採効率+II'}, 'tech_belong': 2, 'axis': (11.5, 4.5), 'island_level': 18}, + 220103: {'name': {'cn': '矿山采矿岗位增加II', 'en': 'Mining Slot+ II', 'jp': '採掘配置枠+II'}, 'tech_belong': 2, 'axis': (14, 6.5), 'island_level': 21}, + 220204: {'name': {'cn': '银矿勘探技术', 'en': 'Silver Ore Exploration Techniques', 'jp': '銀鉱石探鉱'}, 'tech_belong': 2, 'axis': (14, 8.5), 'island_level': 21}, + 210103: {'name': {'cn': '林场伐木岗位增加II', 'en': 'Logging Slot+ II', 'jp': '伐採配置枠+II'}, 'tech_belong': 2, 'axis': (14, 1), 'island_level': 24}, + 210203: {'name': {'cn': '典雅之木生产技术', 'en': 'Elegant Wood Harvesting Techniques', 'jp': 'エレガント木材伐採'}, 'tech_belong': 2, 'axis': (14, 3), 'island_level': 24}, + 210104: {'name': {'cn': '林场伐木岗位增加III', 'en': 'Logging Slot+ III', 'jp': '伐採配置枠+III'}, 'tech_belong': 2, 'axis': (17, 1), 'island_level': 26}, + 220104: {'name': {'cn': '矿山采矿岗位增加III', 'en': 'Mining Slot+ III', 'jp': '採掘配置枠+III'}, 'tech_belong': 2, 'axis': (17, 6.5), 'island_level': 29}, + 210601: {'name': {'cn': '伐木岗位效率提升', 'en': 'Logging Slot Efficiency+', 'jp': '伐採配置枠効率+'}, 'tech_belong': 2, 'axis': (20, 4.5), 'island_level': 35}, + 220601: {'name': {'cn': '采矿岗位效率提升', 'en': 'Mining Slot Efficiency+', 'jp': '採掘配置枠効率+'}, 'tech_belong': 2, 'axis': (20, 10), 'island_level': 41}, + 310301: {'name': {'cn': '扩建晨露农场I', 'en': 'Morningdew Farm Expansion I', 'jp': '朝露農場拡張I'}, 'tech_belong': 3, 'axis': (1, 1), 'island_level': 6}, + 310201: {'name': {'cn': '牧草种植技术', 'en': 'Grass Cultivation Techniques', 'jp': '牧草栽培'}, 'tech_belong': 3, 'axis': (1, 9), 'island_level': 6}, + 310302: {'name': {'cn': '扩建晨露农场II', 'en': 'Morningdew Farm Expansion II', 'jp': '朝露農場拡張II'}, 'tech_belong': 3, 'axis': (4, 1), 'island_level': 7}, + 320301: {'name': {'cn': '扩建青芽苗圃I', 'en': 'Newsprout Nursery Expansion I', 'jp': '青々苗場拡張I'}, 'tech_belong': 3, 'axis': (4, 5), 'island_level': 7}, + 310101: {'name': {'cn': '解锁农场管理岗位', 'en': 'Unlock: Farm Slot', 'jp': '開放:農場配置枠'}, 'tech_belong': 3, 'axis': (7, 3), 'island_level': 8}, + 310202: {'name': {'cn': '旱稻种植技术', 'en': 'Upland Rice Cultivation Techniques', 'jp': '陸稲栽培技術'}, 'tech_belong': 3, 'axis': (4, 9), 'island_level': 8}, + 330301: {'name': {'cn': '扩建坠香果园I', 'en': 'Sweetscent Orchard Expansion I', 'jp': '薫る果樹園拡張I'}, 'tech_belong': 3, 'axis': (7, 7), 'island_level': 9}, + 310303: {'name': {'cn': '扩建晨露农场III', 'en': 'Morningdew Farm Expansion III', 'jp': '朝露農場拡張III'}, 'tech_belong': 3, 'axis': (7, 1), 'island_level': 11}, + 310304: {'name': {'cn': '扩建晨露农场IV', 'en': 'Morningdew Farm Expansion IV', 'jp': '朝露農場拡張IV'}, 'tech_belong': 3, 'axis': (10, 1), 'island_level': 12}, + 330101: {'name': {'cn': '解锁果园管理岗位', 'en': 'Unlock: Orchard Slot', 'jp': '開放:果樹園配置枠'}, 'tech_belong': 3, 'axis': (10, 7), 'island_level': 12}, + 310305: {'name': {'cn': '扩建晨露农场V', 'en': 'Morningdew Farm Expansion V', 'jp': '朝露農場拡張V'}, 'tech_belong': 3, 'axis': (13, 1), 'island_level': 13}, + 320202: {'name': {'cn': '棉花种植技术', 'en': 'Cotton Cultivation Techniques', 'jp': '綿栽培'}, 'tech_belong': 3, 'axis': (10, 9), 'island_level': 13}, + 320101: {'name': {'cn': '解锁苗圃管理岗位', 'en': 'Unlock: Nursery Slot', 'jp': '開放:苗場配置枠'}, 'tech_belong': 3, 'axis': (10, 5), 'island_level': 14}, + 320302: {'name': {'cn': '扩建青芽苗圃II', 'en': 'Newsprout Nursery Expansion II', 'jp': '青々苗場拡張II'}, 'tech_belong': 3, 'axis': (13, 5), 'island_level': 15}, + 330302: {'name': {'cn': '扩建坠香果园II', 'en': 'Sweetscent Orchard Expansion II', 'jp': '薫る果樹園拡張II'}, 'tech_belong': 3, 'axis': (13, 7), 'island_level': 15}, + 310306: {'name': {'cn': '扩建晨露农场VI', 'en': 'Morningdew Farm Expansion VI', 'jp': '朝露農場拡張VI'}, 'tech_belong': 3, 'axis': (16, 1), 'island_level': 16}, + 330102: {'name': {'cn': '果园管理岗位增加I', 'en': 'Orchard Slot+ I', 'jp': '果樹園配置枠+I'}, 'tech_belong': 3, 'axis': (16, 7), 'island_level': 17}, + 310102: {'name': {'cn': '农场管理岗位增加I', 'en': 'Farm Slot+ I', 'jp': '農場配置枠+I'}, 'tech_belong': 3, 'axis': (16, 3), 'island_level': 18}, + 320303: {'name': {'cn': '扩建青芽苗圃III', 'en': 'Newsprout Nursery Expansion III', 'jp': '青々苗場拡張III'}, 'tech_belong': 3, 'axis': (16, 5), 'island_level': 19}, + 330201: {'name': {'cn': '橡胶树种植技术', 'en': 'Rubber Tree Cultivation Techniques', 'jp': 'ゴムの木栽培'}, 'tech_belong': 3, 'axis': (16, 9), 'island_level': 19}, + 310001: {'name': {'cn': '手动播种范围增加', 'en': 'Manual Sowing Range+', 'jp': '手動種まき範囲+'}, 'tech_belong': 3, 'axis': (19, 3), 'island_level': 20}, + 310307: {'name': {'cn': '扩建晨露农场VII', 'en': 'Morningdew Farm Expansion VII', 'jp': '朝露農場拡張VII'}, 'tech_belong': 3, 'axis': (19, 1), 'island_level': 22}, + 320205: {'name': {'cn': '薰衣草种植技术', 'en': 'Lavender Cultivation Techniques', 'jp': 'ラベンダー栽培'}, 'tech_belong': 3, 'axis': (22, 9), 'island_level': 22}, + 310308: {'name': {'cn': '扩建晨露农场VIII', 'en': 'Morningdew Farm Expansion VIII', 'jp': '朝露農場拡張VIII'}, 'tech_belong': 3, 'axis': (22, 1), 'island_level': 23}, + 330303: {'name': {'cn': '扩建坠香果园III', 'en': 'Sweetscent Orchard Expansion III', 'jp': '薫る果樹園拡張III'}, 'tech_belong': 3, 'axis': (19, 7), 'island_level': 24}, + 310103: {'name': {'cn': '农场管理岗位增加II', 'en': 'Farm Slot+ II', 'jp': '農場配置枠+II'}, 'tech_belong': 3, 'axis': (25, 3), 'island_level': 25}, + 330103: {'name': {'cn': '果园管理岗位增加II', 'en': 'Orchard Slot+ II', 'jp': '果樹園配置枠+II'}, 'tech_belong': 3, 'axis': (25, 7), 'island_level': 26}, + 310309: {'name': {'cn': '扩建晨露农场IX', 'en': 'Morningdew Farm Expansion IX', 'jp': '朝露農場拡張IX'}, 'tech_belong': 3, 'axis': (25, 1), 'island_level': 27}, + 320304: {'name': {'cn': '扩建青芽苗圃IV', 'en': 'Newsprout Nursery Expansion IV', 'jp': '青々苗場拡張IV'}, 'tech_belong': 3, 'axis': (25, 5), 'island_level': 32}, + 320102: {'name': {'cn': '苗圃管理岗位增加', 'en': 'Nursery Slot+', 'jp': '苗場配置枠+'}, 'tech_belong': 3, 'axis': (28, 5), 'island_level': 34}, + 330104: {'name': {'cn': '果园管理岗位增加III', 'en': 'Orchard Slot+ III', 'jp': '果樹園配置枠+III'}, 'tech_belong': 3, 'axis': (28, 7), 'island_level': 37}, + 310104: {'name': {'cn': '农场管理岗位增加III', 'en': 'Farm Slot+ III', 'jp': '農場配置枠+III'}, 'tech_belong': 3, 'axis': (28, 3), 'island_level': 39}, + 410301: {'name': {'cn': '更多的鸡!I', 'en': 'More Chickens! I', 'jp': 'もっと鶏を!I'}, 'tech_belong': 4, 'axis': (1, 1), 'island_level': 6}, + 420301: {'name': {'cn': '哼哼猪养殖', 'en': 'Oinky Oinky Pig Raising', 'jp': 'ブーブーブタ養殖'}, 'tech_belong': 4, 'axis': (1, 3), 'island_level': 7}, + 410302: {'name': {'cn': '更多的鸡!II', 'en': 'More Chickens! II', 'jp': 'もっと鶏を!II'}, 'tech_belong': 4, 'axis': (4, 1), 'island_level': 8}, + 420302: {'name': {'cn': '更多的猪!I', 'en': 'More Pigs! I', 'jp': 'もっと豚を!I'}, 'tech_belong': 4, 'axis': (4, 3), 'island_level': 8}, + 400001: {'name': {'cn': '牧场额外产出', 'en': 'Ranch Product Range+', 'jp': '牧場生産品目+'}, 'tech_belong': 4, 'axis': (1, 7), 'island_level': 9}, + 430301: {'name': {'cn': '哞哞牛养殖', 'en': 'Moo Moo Cow Raising', 'jp': 'モーモーウシ養殖'}, 'tech_belong': 4, 'axis': (4, 5), 'island_level': 9}, + 430302: {'name': {'cn': '更多的牛!I', 'en': 'More Cows! I', 'jp': 'もっと牛を!I'}, 'tech_belong': 4, 'axis': (7, 5), 'island_level': 10}, + 440301: {'name': {'cn': '咩咩羊养殖', 'en': 'Baa Baa Sheep Raising', 'jp': 'メェメーヒツジ養殖'}, 'tech_belong': 4, 'axis': (7, 7), 'island_level': 11}, + 440302: {'name': {'cn': '更多的羊!I', 'en': 'More Sheep! I', 'jp': 'もっと羊を!I'}, 'tech_belong': 4, 'axis': (10, 7), 'island_level': 12}, + 420303: {'name': {'cn': '更多的猪!II', 'en': 'More Pigs! II', 'jp': 'もっと豚を!II'}, 'tech_belong': 4, 'axis': (10, 3), 'island_level': 13}, + 410303: {'name': {'cn': '更多的鸡!III', 'en': 'More Chickens! III', 'jp': 'もっと鶏を!III'}, 'tech_belong': 4, 'axis': (10, 1), 'island_level': 14}, + 430303: {'name': {'cn': '更多的牛!II', 'en': 'More Cows! II', 'jp': 'もっと牛を!II'}, 'tech_belong': 4, 'axis': (13, 5), 'island_level': 15}, + 410304: {'name': {'cn': '更多的鸡!IV', 'en': 'More Chickens! IV', 'jp': 'もっと鶏を!IV'}, 'tech_belong': 4, 'axis': (13, 1), 'island_level': 16}, + 440303: {'name': {'cn': '更多的羊!II', 'en': 'More Sheep! II', 'jp': 'もっと羊を!II'}, 'tech_belong': 4, 'axis': (13, 7), 'island_level': 17}, + 410305: {'name': {'cn': '更多的鸡!V', 'en': 'More Chickens! V', 'jp': 'もっと鶏を!V'}, 'tech_belong': 4, 'axis': (16, 1), 'island_level': 21}, + 420304: {'name': {'cn': '更多的猪!III', 'en': 'More Pigs! III', 'jp': 'もっと豚を!III'}, 'tech_belong': 4, 'axis': (16, 3), 'island_level': 22}, + 430304: {'name': {'cn': '更多的牛!III', 'en': 'More Cows! III', 'jp': 'もっと牛を!III'}, 'tech_belong': 4, 'axis': (16, 5), 'island_level': 25}, + 450301: {'name': {'cn': '蜂蜜采集点增加I', 'en': 'Honey Gathering Sites+ I', 'jp': 'はちみつ採集地+I'}, 'tech_belong': 4, 'axis': (16, 9), 'island_level': 26}, + 440304: {'name': {'cn': '更多的羊!III', 'en': 'More Sheep! III', 'jp': 'もっと羊を!III'}, 'tech_belong': 4, 'axis': (16, 7), 'island_level': 27}, + 450302: {'name': {'cn': '蜂蜜采集点增加II', 'en': 'Honey Gathering Sites+ II', 'jp': 'はちみつ採集地+II'}, 'tech_belong': 4, 'axis': (19, 9), 'island_level': 30}, + 500211: {'name': {'cn': '咖啡树种植技术', 'en': 'Coffee Tree Cultivation Techniques', 'jp': 'コーヒーの木栽培技術'}, 'tech_belong': 5, 'axis': (1, 1), 'island_level': 6}, + 500212: {'name': {'cn': '玉米种植技术', 'en': 'Corn Cultivation Techniques', 'jp': 'とうもろこし栽培'}, 'tech_belong': 5, 'axis': (1, 5), 'island_level': 7}, + 500231: {'name': {'cn': '苹果树种植技术', 'en': 'Apple Tree Cultivation Techniques', 'jp': 'りんごの木栽培'}, 'tech_belong': 5, 'axis': (1, 3), 'island_level': 8}, + 550201: {'name': {'cn': '起司食谱', 'en': 'Cheese', 'jp': 'チーズ'}, 'tech_belong': 5, 'axis': (4, 1), 'island_level': 8}, + 500213: {'name': {'cn': '大豆种植技术', 'en': 'Soy Bean Cultivation Techniques', 'jp': '大豆栽培'}, 'tech_belong': 5, 'axis': (4, 8), 'island_level': 9}, + 500215: {'name': {'cn': '白菜种植技术', 'en': 'Napa Cabbage Cultivation Techniques', 'jp': '白菜栽培'}, 'tech_belong': 5, 'axis': (7, 5), 'island_level': 9}, + 520001: {'name': {'cn': '建设白熊饮品', 'en': 'Unlock: Polar Bear Teahouse', 'jp': '開放:白クマ茶房'}, 'tech_belong': 5, 'axis': (4, 3), 'island_level': 9}, + 500214: {'name': {'cn': '土豆种植技术', 'en': 'Potato Cultivation Techniques', 'jp': 'じゃがいも栽培'}, 'tech_belong': 5, 'axis': (6, 10), 'island_level': 10}, + 500232: {'name': {'cn': '柑橘树种植技术', 'en': 'Citrus Tree Cultivation Techniques', 'jp': '柑橘類の木栽培'}, 'tech_belong': 5, 'axis': (7, 3), 'island_level': 10}, + 550202: {'name': {'cn': '拿铁食谱', 'en': 'Latte', 'jp': 'ラテ'}, 'tech_belong': 5, 'axis': (7, 1), 'island_level': 10}, + 500001: {'name': {'cn': '解锁美食搭配', 'en': 'Unlock: Dish Arrangement', 'jp': '開放:料理組み合わせ'}, 'tech_belong': 5, 'axis': (1, 10), 'island_level': 11}, + 510201: {'name': {'cn': '肉沫烧豆腐食谱', 'en': 'Tofu with Minced Meat', 'jp': '肉そぼろ豆腐'}, 'tech_belong': 5, 'axis': (7, 8), 'island_level': 11}, + 510202: {'name': {'cn': '蛋包饭食谱', 'en': 'Omurice', 'jp': 'オムライス'}, 'tech_belong': 5, 'axis': (10, 9), 'island_level': 11}, + 510203: {'name': {'cn': '白菜豆腐汤食谱', 'en': 'Cabbage and Tofu Soup', 'jp': '白菜と豆腐のスープ'}, 'tech_belong': 5, 'axis': (10, 7), 'island_level': 12}, + 550203: {'name': {'cn': '柑橘咖啡食谱', 'en': 'Citrus Coffee', 'jp': 'シトラスコーヒー'}, 'tech_belong': 5, 'axis': (16, 1), 'island_level': 12}, + 320201: {'name': {'cn': '草莓种植技术', 'en': 'Strawberry Cultivation Techniques', 'jp': 'いちご栽培'}, 'tech_belong': 5, 'axis': (10, 1), 'island_level': 12}, + 500233: {'name': {'cn': '香蕉树种植技术', 'en': 'Banana Tree Cultivation Techniques', 'jp': 'バナナの木栽培'}, 'tech_belong': 5, 'axis': (10, 3), 'island_level': 13}, + 500234: {'name': {'cn': '芒果树种植技术', 'en': 'Mango Tree Cultivation Techniques', 'jp': 'マンゴーの木栽培'}, 'tech_belong': 5, 'axis': (10, 5), 'island_level': 14}, + 510204: {'name': {'cn': '蔬菜沙拉食谱', 'en': 'Vegetable Salad', 'jp': '野菜サラダ'}, 'tech_belong': 5, 'axis': (13, 8), 'island_level': 14}, + 500235: {'name': {'cn': '柠檬树种植技术', 'en': 'Lemon Tree Cultivation Techniques', 'jp': 'レモンの木栽培'}, 'tech_belong': 5, 'axis': (13, 2), 'island_level': 15}, + 520201: {'name': {'cn': '香蕉芒果汁食谱', 'en': 'Banana and Mango Juice', 'jp': 'バナナマンゴージュース'}, 'tech_belong': 5, 'axis': (13, 4), 'island_level': 15}, + 520202: {'name': {'cn': '蜂蜜柠檬水食谱', 'en': 'Honey and Lemon Water', 'jp': 'はちみつレモン水'}, 'tech_belong': 5, 'axis': (16, 3), 'island_level': 16}, + 530001: {'name': {'cn': '建设啾啾简餐', 'en': 'Unlock: Manjuu Eatery', 'jp': '開放:饅頭軽食'}, 'tech_belong': 5, 'axis': (16, 5), 'island_level': 16}, + 320203: {'name': {'cn': '茶树种植技术', 'en': 'Tea Tree Cultivation Techniques', 'jp': '茶の木栽培'}, 'tech_belong': 5, 'axis': (22, 1), 'island_level': 16}, + 520203: {'name': {'cn': '草莓蜂蜜冰沙食谱', 'en': 'Strawberry Honey Frappé', 'jp': 'ストロベリーハニーフラッペ'}, 'tech_belong': 5, 'axis': (19, 3), 'island_level': 17}, + 500236: {'name': {'cn': '牛油果树种植技术', 'en': 'Avocado Tree Cultivation Techniques', 'jp': 'アボカドの木栽培'}, 'tech_belong': 5, 'axis': (13, 10), 'island_level': 18}, + 530205: {'name': {'cn': '苹果派食谱', 'en': 'Apple Pie', 'jp': 'アップルパイ'}, 'tech_belong': 5, 'axis': (19, 5), 'island_level': 18}, + 520205: {'name': {'cn': '草莓蜜沁食谱', 'en': 'Strawberry Lemon Drink', 'jp': 'いちごレモンドリンク'}, 'tech_belong': 5, 'axis': (22, 3), 'island_level': 19}, + 530206: {'name': {'cn': '香橙派食谱', 'en': 'Orange Pie', 'jp': 'オレンジパイ'}, 'tech_belong': 5, 'axis': (19, 7), 'island_level': 19}, + 530202: {'name': {'cn': '芒果糯米饭食谱', 'en': 'Sticky Rice with Mango', 'jp': 'マンゴーともち米の蒸し飯'}, 'tech_belong': 5, 'axis': (22, 5), 'island_level': 20}, + 320204: {'name': {'cn': '胡萝卜种植技术', 'en': 'Carrot Cultivation Techniques', 'jp': 'ニンジン栽培技術'}, 'tech_belong': 5, 'axis': (16, 10), 'island_level': 21}, + 550204: {'name': {'cn': '草莓奶绿食谱', 'en': 'Strawberry Milkshake', 'jp': 'いちごミルクシェイク'}, 'tech_belong': 5, 'axis': (25, 1), 'island_level': 21}, + 540001: {'name': {'cn': '建设乌鱼烤肉', 'en': "Unlock: Fin-'n'-Feather Grill", 'jp': '開放:烏魚焼肉'}, 'tech_belong': 5, 'axis': (19, 10), 'island_level': 22}, + 540201: {'name': {'cn': '禽肉土豆拼盘食谱', 'en': "Chicken and Potato Hors d'Oeuvre", 'jp': '鶏肉とポテトの盛り合わせ'}, 'tech_belong': 5, 'axis': (22, 10), 'island_level': 23}, + 520204: {'name': {'cn': '薰衣草茶食谱', 'en': 'Lavender Tea', 'jp': 'ラベンダーティー'}, 'tech_belong': 5, 'axis': (25, 3), 'island_level': 24}, + 530203: {'name': {'cn': '香蕉可丽饼食谱', 'en': 'Banana Crêpe', 'jp': 'バナナクレープ'}, 'tech_belong': 5, 'axis': (28, 5), 'island_level': 24}, + 320206: {'name': {'cn': '洋葱种植技术', 'en': 'Onion Cultivation Techniques', 'jp': '玉ねぎ栽培技術'}, 'tech_belong': 5, 'axis': (25, 10), 'island_level': 25}, + 540202: {'name': {'cn': '爆炒禽肉食谱', 'en': 'Stir-Fried Chicken', 'jp': '鶏肉炒め'}, 'tech_belong': 5, 'axis': (28, 10), 'island_level': 27}, + 530204: {'name': {'cn': '草莓夏洛特食谱', 'en': 'Strawberry Charlotte', 'jp': 'いちごシャルロット'}, 'tech_belong': 5, 'axis': (31, 5), 'island_level': 28}, + 540204: {'name': {'cn': '胡萝卜厚蛋烧食谱', 'en': 'Rolled Carrot Omelette', 'jp': 'ニンジン厚焼き玉子'}, 'tech_belong': 5, 'axis': (31, 10), 'island_level': 29}, + 510101: {'name': {'cn': '有鱼餐馆岗位增加', 'en': 'Golden Koi Restaurant Slot+', 'jp': '有魚飯店配置枠+'}, 'tech_belong': 5, 'axis': (29, 8), 'island_level': 30}, + 540205: {'name': {'cn': '汉堡肉饭食谱', 'en': 'Steak Bowl', 'jp': 'ハンバーグ丼'}, 'tech_belong': 5, 'axis': (34, 10), 'island_level': 32}, + 520101: {'name': {'cn': '白熊饮品岗位增加', 'en': 'Polar Bear Teahouse Slot+', 'jp': '白クマ茶房配置枠+'}, 'tech_belong': 5, 'axis': (34, 3), 'island_level': 35}, + 530101: {'name': {'cn': '啾啾简餐岗位增加', 'en': 'Manjuu Eatery Slot+', 'jp': '饅頭軽食配置枠+'}, 'tech_belong': 5, 'axis': (37, 5), 'island_level': 41}, + 540101: {'name': {'cn': '乌鱼烤肉岗位增加', 'en': "Fin-'n'-Feather Grill Slot+", 'jp': '烏魚焼肉配置枠+'}, 'tech_belong': 5, 'axis': (37, 10), 'island_level': 47}, + 610101: {'name': {'cn': '货运委托上限提升I', 'en': 'Transport Job Limit+ I', 'jp': '輸送依頼上限+I'}, 'tech_belong': 6, 'axis': (1, 1), 'island_level': 6}, + 610401: {'name': {'cn': '货运效率提升I', 'en': 'Transport Efficiency+ I', 'jp': '輸送効率+I'}, 'tech_belong': 6, 'axis': (4, 1), 'island_level': 8}, + 610102: {'name': {'cn': '货运委托上限提升II', 'en': 'Transport Job Limit+ II', 'jp': '輸送依頼上限+II'}, 'tech_belong': 6, 'axis': (7, 1), 'island_level': 11}, + 630201: {'name': {'cn': '记事本生产工艺', 'en': 'Notebook', 'jp': 'メモ帳'}, 'tech_belong': 6, 'axis': (4, 3), 'island_level': 11}, + 610402: {'name': {'cn': '货运效率提升II', 'en': 'Transport Efficiency+ II', 'jp': '輸送効率+II'}, 'tech_belong': 6, 'axis': (10, 1), 'island_level': 13}, + 630202: {'name': {'cn': '桌椅生产工艺', 'en': 'Chair and Desk', 'jp': '机と椅子'}, 'tech_belong': 6, 'axis': (7, 3), 'island_level': 13}, + 620101: {'name': {'cn': '啾咖啡岗位增加', 'en': 'Café Manjuu Slot+', 'jp': '饅頭カフェ配置枠+'}, 'tech_belong': 6, 'axis': (1, 9), 'island_level': 15}, + 640001: {'name': {'cn': '解锁工业生产设备', 'en': 'Unlock: Manufactured Items', 'jp': '開放:工業アイテム'}, 'tech_belong': 6, 'axis': (4, 5), 'island_level': 15}, + 630101: {'name': {'cn': '木料加工岗位增加', 'en': 'Lumber Processing Slot+', 'jp': '木材加工配置枠+'}, 'tech_belong': 6, 'axis': (13, 3), 'island_level': 16}, + 610403: {'name': {'cn': '货运效率提升III', 'en': 'Transport Efficiency+ III', 'jp': '輸送効率+III'}, 'tech_belong': 6, 'axis': (13, 1), 'island_level': 17}, + 640201: {'name': {'cn': '铁钉生产工艺', 'en': 'Nails', 'jp': '鉄釘'}, 'tech_belong': 6, 'axis': (7, 5), 'island_level': 18}, + 660001: {'name': {'cn': '解锁手工制作设备', 'en': 'Unlock: Arts & Crafts Items', 'jp': '開放:手工業アイテム'}, 'tech_belong': 6, 'axis': (4, 7), 'island_level': 19}, + 630203: {'name': {'cn': '精选木桶生产工艺', 'en': 'Choice Wooden Barrel', 'jp': 'オーク樽'}, 'tech_belong': 6, 'axis': (16, 3), 'island_level': 20}, + 640101: {'name': {'cn': '工业生产岗位增加', 'en': 'Industrial Production Slot+', 'jp': '工業生産配置枠+'}, 'tech_belong': 6, 'axis': (13, 5), 'island_level': 20}, + 640202: {'name': {'cn': '电缆生产工艺', 'en': 'Cable', 'jp': 'ケーブル'}, 'tech_belong': 6, 'axis': (10, 5), 'island_level': 20}, + 660201: {'name': {'cn': '皮革生产工艺', 'en': 'Leather', 'jp': '革'}, 'tech_belong': 6, 'axis': (7, 7), 'island_level': 21}, + 640203: {'name': {'cn': '硫酸生产工艺', 'en': 'Chemicals', 'jp': '化学品'}, 'tech_belong': 6, 'axis': (16, 5), 'island_level': 22}, + 660202: {'name': {'cn': '绳索生产工艺', 'en': 'Rope', 'jp': 'ロープ'}, 'tech_belong': 6, 'axis': (10, 7), 'island_level': 22}, + 660203: {'name': {'cn': '手套生产工艺', 'en': 'Gloves', 'jp': '手袋'}, 'tech_belong': 6, 'axis': (13, 7), 'island_level': 23}, + 650001: {'name': {'cn': '解锁电子加工设备', 'en': 'Unlock: Electronic Items', 'jp': '開放:電化アイテム'}, 'tech_belong': 6, 'axis': (10, 9), 'island_level': 24}, + 630204: {'name': {'cn': '文件柜生产工艺', 'en': 'Filing Cabinet', 'jp': 'ファイルキャビネット'}, 'tech_belong': 6, 'axis': (19, 3), 'island_level': 26}, + 660204: {'name': {'cn': '香囊生产工艺', 'en': 'Aroma Sachet', 'jp': '香り袋'}, 'tech_belong': 6, 'axis': (16, 7), 'island_level': 26}, + 640204: {'name': {'cn': '火药生产工艺', 'en': 'Gunpowder', 'jp': '火薬'}, 'tech_belong': 6, 'axis': (19, 5), 'island_level': 27}, + 650201: {'name': {'cn': '钟表生产工艺', 'en': 'Clock', 'jp': '時計'}, 'tech_belong': 6, 'axis': (16, 9), 'island_level': 27}, + 660101: {'name': {'cn': '手工制作岗位增加', 'en': 'Arts & Crafts Slot+', 'jp': '手工制作配置枠+'}, 'tech_belong': 6, 'axis': (19, 7), 'island_level': 28}, + 640205: {'name': {'cn': '餐具生产工艺', 'en': 'Utensils', 'jp': '食器'}, 'tech_belong': 6, 'axis': (22, 5), 'island_level': 30}, + 660205: {'name': {'cn': '鞋靴生产工艺', 'en': 'Shoes', 'jp': '靴'}, 'tech_belong': 6, 'axis': (22, 7), 'island_level': 31}, + 650101: {'name': {'cn': '电子加工岗位增加', 'en': 'Electronics Production Slot+', 'jp': '電子加工配置枠+'}, 'tech_belong': 6, 'axis': (22, 9), 'island_level': 33}, + 660206: {'name': {'cn': '绷带生产工艺', 'en': 'Wound Dressings', 'jp': '包帯'}, 'tech_belong': 6, 'axis': (25, 7), 'island_level': 35}, + 650202: {'name': {'cn': '蓄电池生产工艺', 'en': 'Battery', 'jp': '蓄電池'}, 'tech_belong': 6, 'axis': (25, 9), 'island_level': 36}, + 650203: {'name': {'cn': '净水滤芯生产工艺', 'en': 'Water Filter', 'jp': '浄水フィルター'}, 'tech_belong': 6, 'axis': (28, 9), 'island_level': 42}, +} diff --git a/module/island/season_task.py b/module/island/season_task.py new file mode 100644 index 0000000000..a958b4c748 --- /dev/null +++ b/module/island/season_task.py @@ -0,0 +1,191 @@ +from yaml import safe_dump + +import module.config.server as server +from module.base.button import ButtonGrid +from module.base.decorator import cached_property, del_cached_property, Config +from module.base.timer import Timer +from module.base.utils import area_offset +from module.island.assets import * +from module.island.data import DIC_ISLAND_SEASONAL_TASK +from module.island.ui import IslandUI, ISLAND_SEASON_TASK_SCROLL +from module.logger import logger +from module.map_detection.utils import Points +from module.ocr.ocr import DigitCounter, Ocr +from module.ui.page import page_island_season + +if server.server == 'cn': + lang = 'cnocr' +elif server.server == 'en': + lang = 'azur_lane' +else: + lang = server.server +TASK_NAME_OCR = Ocr([], lang=lang, letter=(64, 64, 64), name='TASK_NAME_OCR') +TASK_COUNTER_OCR = DigitCounter([], letter=(128, 128, 128), name='TASK_COUNTER_OCR') + +class IslandSeasonTaskHandler(IslandUI): + def _get_bars(self): + """ + Returns: + np.array: [[x1, y1], [x2, y2]], location of the bar icon upper left corner. + """ + area = (43, 178, 875, 478) + image = self.image_crop(area, copy=True) + bars = TEMPLATE_ISLAND_SEASON_TASK_ICON.match_multi(image, threshold=5) + bars = Points([(0., b.area[1]) for b in bars]).group(threshold=5) + logger.attr('bars_icon', len(bars)) + return bars + + def wait_until_bar_appear(self, skip_first_screenshot=False): + """ + After entering season task page, + tasks are not loaded that fast, + wait until any bar icon appears. + """ + confirm_timer = Timer(1.5, count=3).start() + for _ in self.loop(skip_first=skip_first_screenshot): + bars = self._get_bars() + if len(bars): + if confirm_timer.reached(): + return + else: + pass + else: + confirm_timer.reset() + + @cached_property + def task_grid(self): + return self.task_bar_grid() + + def task_bar_grid(self): + """ + Returns: + ButtonGrid: + """ + bars = self._get_bars() + count = len(bars) + if count == 0: + logger.warning('Unable to find bar icon, assume task list is at top') + origin_y = 178 + delta_y = 229 + row = 2 + elif count == 1: + y_list = bars[:, 1] + # -16 to adjust the bar position to grid position + origin_y = y_list[0] - 16 + 178 + delta_y = 229 + row = 1 + elif count == 2: + y_list = bars[:, 1] + origin_y = min(y_list) - 16 + 178 + delta_y = abs(y_list[1] - y_list[0]) + row = 2 + else: + logger.warning(f'Too many bars found ({count}), assume max rows') + y_list = bars[:, 1] + origin_y = min(y_list) - 16 + 178 + delta_y = abs(y_list[1] - y_list[0]) + row = 2 + task_grid = ButtonGrid( + origin=(43, origin_y), delta=(394, delta_y), + button_shape=(375, 210), grid_shape=(3, row), + name='SEASONAL_TASK_GRID' + ) + return task_grid + + @Config.when(SERVER='jp') + def task_id_parse(self, string): + string = string.replace('一', 'ー').replace('へ', 'ヘ') + import jellyfish + min_key = '' + min_distance = 100 + for key, value in DIC_ISLAND_SEASONAL_TASK.items(): + distance = jellyfish.levenshtein_distance(value['name']['jp'], string) + if distance < min_distance: + min_distance = distance + min_key = key + if min_distance < 3: + return min_key + logger.warning(f'Unknown task name: {string}') + return None + + @Config.when(SERVER=None) + def task_id_parse(self, string): + for key, value in DIC_ISLAND_SEASONAL_TASK.items(): + if string == value['name'][server.server]: + return key + logger.warning(f'Unknown task name: {string}') + return None + + def predict(self, grid: ButtonGrid): + """ + Predicts all tasks in the given grid. + + Args: + grid (ButtonGrid): + """ + name_area = (30, 18, 250, 52) + counter_area = (270, 20, 360, 50) + name_list = [self.image_crop(area, copy=True) for area in grid.crop(name_area).buttons] + name_list = TASK_NAME_OCR.ocr(name_list, direct_ocr=True) + task_id_list = [self.task_id_parse(name) for name in name_list] + counter_list = [self.image_crop(area, copy=True) for area in grid.crop(counter_area).buttons] + counter_list = [ + TASK_COUNTER_OCR.ocr([image], direct_ocr=True) + for image in counter_list + ] + for task_id, counter_result, button in zip(task_id_list, counter_list, grid.buttons): + if task_id is None: + continue + target = DIC_ISLAND_SEASONAL_TASK[task_id]['target'] + if target: + target_item = list(target.keys())[0] + current, _, total = counter_result + obtained = TEMPLATE_ISLAND_SEASON_TASK_OBTAINED.match(self.image_crop(button, copy=True)) + yield task_id, (target_item, current, total), obtained + + def scan_all(self): + """ + Scans all seasonal tasks on the island season page. + + Returns: + dict: { + recipe_id: (item_id, current, total) + } + """ + self.wait_until_bar_appear() + logger.hr('Scanning seasonal tasks') + ISLAND_SEASON_TASK_SCROLL.set_top(main=self) + unfinished_tasks = {} + while 1: + for task_id, (target_item, current, total), obtained in self.predict(self.task_grid): + if current < total: + unfinished_tasks[task_id] = (target_item, current, total) + if obtained: + logger.info(f'Detect obtained task, early stop scanning') + return unfinished_tasks + if ISLAND_SEASON_TASK_SCROLL.at_bottom(main=self): + logger.info('Task list reach bottom, stop') + break + else: + ISLAND_SEASON_TASK_SCROLL.next_page(main=self, page=0.5) + del_cached_property(self, 'task_grid') + continue + return unfinished_tasks + + def run(self): + """ + Pages: + in: Any page + out: page_island + + Returns: + dict: { + recipe_id: (item_id, current, total) + } + """ + self.ui_ensure(page_island_season) + self.island_season_bottom_navbar_ensure(left=3) + result = self.scan_all() + value = safe_dump(result) + self.config.cross_set(keys="IslandInfo.IslandSeasonTask.TaskDict", value=value) + self.config.task_delay(server_update=True) diff --git a/module/island/technology.py b/module/island/technology.py new file mode 100644 index 0000000000..48798caa36 --- /dev/null +++ b/module/island/technology.py @@ -0,0 +1,129 @@ +import cv2 +import numpy as np +from yaml import safe_dump + +from module.base.button import Button +from module.base.mask import Mask +from module.base.utils import color_similarity_2d, rgb2luma, load_image, random_rectangle_vector, area_offset, crop +from module.island.data import DIC_ISLAND_TECHNOLOGY +from module.island.ui import IslandUI +from module.ui.page import page_island_technology + +DELTA_X = 136 + 2/3 +DELTA_Y = 60 +ORIGIN_X = -5/3 +ORIGIN_Y = 46 +LEFT_STRIP = 167 +MASK_ISLAND_TECHNOLOGY = Mask('./assets/mask/MASK_ISLAND_TECHNOLOGY.png') +TECHNOLOGY_LENGTH = { + '2': 3139 - 1280 + LEFT_STRIP, + '3': 4231 - 1280 + LEFT_STRIP, + '4': 3003 - 1280 + LEFT_STRIP, + '5': 5462 - 1280 + LEFT_STRIP, + '6': 4233 - 1280 + LEFT_STRIP, +} +DETECTION_AREA = (167, 54, 1280, 720) +DETECTION_AREA_MASK = (1098, 646, 1280, 720) +BUTTON_AREA = (-110, -26, 110, 26) + + +def extract_flowchart(image): + brightness = rgb2luma(image) + black = color_similarity_2d(image, (7, 10, 17)) + brightness_mask = cv2.inRange(brightness, 160, 255) + black_mask = cv2.inRange(black, 245, 255) + mask = cv2.bitwise_or(brightness_mask, black_mask) + contours, _ = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + filled_mask = np.zeros_like(mask) + cv2.drawContours(filled_mask, contours, -1, 255, thickness=cv2.FILLED) + filled_mask = MASK_ISLAND_TECHNOLOGY.apply(filled_mask) + filled_mask = filled_mask[:, LEFT_STRIP:] + return filled_mask + +def get_technology_tab_and_position(index): + tech_info = DIC_ISLAND_TECHNOLOGY[index] + tab = tech_info['tech_belong'] + axis_x, axis_y = tech_info['axis'] + position_x = ORIGIN_X + DELTA_X * axis_x + position_y = ORIGIN_Y + DELTA_Y * axis_y + return tab, (position_x, position_y) + +class IslandTechnologyHandler(IslandUI): + """ + Currently only supports checking tab 2,3,4,5,6. + """ + def get_technology_view_position(self, tab): + globe_view = load_image(f'./assets/island/technology/technology_chart_{tab}.png') + extracted_flowchart = extract_flowchart(self.device.image) + result = cv2.matchTemplate(globe_view, extracted_flowchart, cv2.TM_CCOEFF_NORMED) + _, similarity, _, loca = cv2.minMaxLoc(result) + return loca[0] + + def _island_technology_swipe(self, forward=True): + detection_area = DETECTION_AREA + direction_vector = (-600, 0) if forward else (600, 0) + p1, p2 = random_rectangle_vector( + direction_vector, box=detection_area, random_range=(-50, -50, 50, 50), padding=20 + ) + self.device.drag(p1, p2, segments=2, shake=(0, 25), point_random=(0, 0, 0, 0), shake_random=(0, -5, 0, 5)) + + def technology_reset_view(self, skip_first_screenshot=True): + active = self._island_technology_side_navbar_get_active() + for _ in range(10): # tab 5 has 4400 length, so 5 swipes are not enough + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + position_x = self.get_technology_view_position(tab=active) + if position_x < 3: + break + self._island_technology_swipe(forward=False) + self.device.click_record_remove('DRAG') + + def scan_all(self): + all_technology = {} + for index in DIC_ISLAND_TECHNOLOGY.keys(): + if DIC_ISLAND_TECHNOLOGY[index]['tech_belong'] not in [2, 3, 4, 5, 6]: + continue + tab, position = get_technology_tab_and_position(index) + all_technology[index] = { + 'tab': tab, + 'position': position, + 'active': False, + } + technology_by_tab = [{} for _ in range(5)] + for index, info in all_technology.items(): + technology_by_tab[info['tab'] - 2][index] = info['position'] + for tab in range(2, 7): + self.island_technology_side_navbar_ensure(tab=tab) + self.technology_reset_view() + position_x_old = None + for _ in self.loop(): + position_x = self.get_technology_view_position(tab=tab) + if position_x_old is not None: + if position_x - position_x_old < 5: + break + position_x_old = position_x + for index, (tech_pos_x, tech_pos_y) in technology_by_tab[tab - 2].items(): + tech_pos_x_in_view = tech_pos_x - position_x + if (DETECTION_AREA[0] - BUTTON_AREA[0] <= LEFT_STRIP + tech_pos_x_in_view <= DETECTION_AREA[2] - BUTTON_AREA[2] + and not ( + tech_pos_y > DETECTION_AREA_MASK[1] + BUTTON_AREA[1] + and LEFT_STRIP + tech_pos_x_in_view >= DETECTION_AREA_MASK[0] + )): + tech_button = crop(self.device.image, area=area_offset(BUTTON_AREA, (LEFT_STRIP + tech_pos_x_in_view, tech_pos_y))) + luma = rgb2luma(tech_button) + color = np.mean(luma.flatten()) + if color > 160: + all_technology[index]['active'] = True + self._island_technology_swipe(forward=True) + self.device.click_record_remove('DRAG') + return {index: info['active'] for index, info in all_technology.items()} + + def run(self): + self.ui_ensure(page_island_technology) + result = self.scan_all() + value = safe_dump(result) + self.config.cross_set(keys="IslandInfo.IslandTechnology.TechnologyStatus", value=value) + + diff --git a/module/island/ui.py b/module/island/ui.py new file mode 100644 index 0000000000..42ee186aba --- /dev/null +++ b/module/island/ui.py @@ -0,0 +1,99 @@ +from module.base.button import ButtonGrid +from module.base.decorator import cached_property +from module.island.assets import * +from module.ui.navbar import Navbar +from module.ui.scroll import Scroll +from module.ui.ui import UI + + +ISLAND_SEASON_TASK_SCROLL = Scroll( + ISLAND_SEASON_TASK_SCROLL_AREA.button, + color=(128, 128, 128), + name="ISLAND_SEASON_TASK_SCROLL" +) + + +class IslandUI(UI): + def ui_additional(self, get_ship=True): + return super().ui_additional(get_ship=False) + + @cached_property + def _island_season_bottom_navbar(self): + """ + 5 options: + homepage, + pt_reward, + season_task, + season_shop, + season_rank + """ + island_season_bottom_navbar = ButtonGrid( + origin=(54, 677), delta=(246.5, 0), + button_shape=(186, 33), grid_shape=(5, 1), + name='ISLAND_SEASON_BOTTOM_NAVBAR' + ) + return Navbar(grids=island_season_bottom_navbar, + active_color=(237, 237, 237), + inactive_color=(65, 78, 96), + active_count=500, + inactive_count=500) + + def island_season_bottom_navbar_ensure(self, left=None, right=None): + """ + Args: + left (int): + 1 for homepage, + 2 for pt_reward, + 3 for season_task, + 4 for season_shop, + 5 for season_rank + right (int): + 1 for season_rank, + 2 for season_shop, + 3 for season_task, + 4 for pt_reward, + 5 for homepage + """ + if self._island_season_bottom_navbar.set(self, left=left, right=right): + return True + return False + + @cached_property + def _island_technology_side_navbar(self): + island_technology_side_navbar = ButtonGrid( + origin=(13, 107), delta=(0, 196/3), + button_shape=(128, 43), grid_shape=(1, 5) + ) + return Navbar(grids=island_technology_side_navbar, + active_color=(30, 143, 255), + inactive_color=(50, 52, 55), + active_count=500, + inactive_count=500) + + def _island_technology_side_navbar_get_active(self): + active, _, _ = self._island_technology_side_navbar.get_info(main=self) + if active is None: + return 1 + return active + 2 + + def island_technology_side_navbar_ensure(self, tab=1, skip_first_screenshot=True): + """ + Tab 2, 3, 4, 5, 6 corresponds to _island_technology_side_navbar 1, 2, 3, 4, 5 + Tab 1 is a special situation where the botton icon is chosen, + and all the navbar icons are inactive. + """ + for _ in self.loop(skip_first=skip_first_screenshot): + active = self._island_technology_side_navbar_get_active() + if active == tab: + return True + if tab == 1: + self.device.click(ISLAND_TECHNOLOGY_TAB1) + continue + else: + if active == 1: + self.device.click(self._island_technology_side_navbar.grids.buttons[tab-2]) + continue + else: + self._island_technology_side_navbar.set(self, upper=tab-1) + return True + return False diff --git a/module/ui/assets.py b/module/ui/assets.py index 9bdf14a578..3f253a1907 100644 --- a/module/ui/assets.py +++ b/module/ui/assets.py @@ -29,6 +29,7 @@ DORMMENU_CHECK = Button(area={'cn': (261, 487, 334, 587), 'en': (261, 487, 334, 587), 'jp': (261, 487, 334, 587), 'tw': (261, 487, 334, 587)}, color={'cn': (181, 172, 178), 'en': (181, 172, 178), 'jp': (181, 172, 178), 'tw': (181, 172, 178)}, button={'cn': (261, 487, 334, 587), 'en': (261, 487, 334, 587), 'jp': (261, 487, 334, 587), 'tw': (261, 487, 334, 587)}, file={'cn': './assets/cn/ui/DORMMENU_CHECK.png', 'en': './assets/en/ui/DORMMENU_CHECK.png', 'jp': './assets/jp/ui/DORMMENU_CHECK.png', 'tw': './assets/tw/ui/DORMMENU_CHECK.png'}) DORMMENU_GOTO_ACADEMY = Button(area={'cn': (261, 487, 334, 587), 'en': (261, 487, 334, 587), 'jp': (261, 487, 334, 587), 'tw': (261, 487, 334, 587)}, color={'cn': (181, 172, 178), 'en': (181, 172, 178), 'jp': (181, 172, 178), 'tw': (181, 172, 178)}, button={'cn': (261, 487, 334, 587), 'en': (261, 487, 334, 587), 'jp': (261, 487, 334, 587), 'tw': (261, 487, 334, 587)}, file={'cn': './assets/cn/ui/DORMMENU_GOTO_ACADEMY.png', 'en': './assets/en/ui/DORMMENU_GOTO_ACADEMY.png', 'jp': './assets/jp/ui/DORMMENU_GOTO_ACADEMY.png', 'tw': './assets/tw/ui/DORMMENU_GOTO_ACADEMY.png'}) DORMMENU_GOTO_DORM = Button(area={'cn': (408, 494, 541, 587), 'en': (408, 494, 541, 587), 'jp': (408, 494, 541, 587), 'tw': (408, 494, 541, 587)}, color={'cn': (167, 148, 137), 'en': (167, 148, 137), 'jp': (167, 148, 137), 'tw': (167, 148, 137)}, button={'cn': (408, 494, 541, 587), 'en': (408, 494, 541, 587), 'jp': (408, 494, 541, 587), 'tw': (408, 494, 541, 587)}, file={'cn': './assets/cn/ui/DORMMENU_GOTO_DORM.png', 'en': './assets/en/ui/DORMMENU_GOTO_DORM.png', 'jp': './assets/jp/ui/DORMMENU_GOTO_DORM.png', 'tw': './assets/tw/ui/DORMMENU_GOTO_DORM.png'}) +DORMMENU_GOTO_ISLAND = Button(area={'cn': (771, 400, 950, 508), 'en': (771, 400, 950, 508), 'jp': (771, 400, 950, 508), 'tw': (771, 400, 950, 508)}, color={'cn': (177, 180, 191), 'en': (177, 180, 191), 'jp': (177, 180, 191), 'tw': (177, 180, 191)}, button={'cn': (771, 400, 950, 508), 'en': (771, 400, 950, 508), 'jp': (771, 400, 950, 508), 'tw': (771, 400, 950, 508)}, file={'cn': './assets/cn/ui/DORMMENU_GOTO_ISLAND.png', 'en': './assets/cn/ui/DORMMENU_GOTO_ISLAND.png', 'jp': './assets/cn/ui/DORMMENU_GOTO_ISLAND.png', 'tw': './assets/cn/ui/DORMMENU_GOTO_ISLAND.png'}) DORMMENU_GOTO_MAIN = Button(area={'cn': (261, 487, 334, 587), 'en': (261, 487, 334, 587), 'jp': (261, 487, 334, 587), 'tw': (261, 487, 334, 587)}, color={'cn': (181, 172, 178), 'en': (181, 172, 178), 'jp': (181, 172, 178), 'tw': (181, 172, 178)}, button={'cn': (150, 153, 437, 279), 'en': (150, 153, 437, 279), 'jp': (150, 153, 437, 279), 'tw': (150, 153, 437, 279)}, file={'cn': './assets/cn/ui/DORMMENU_GOTO_MAIN.png', 'en': './assets/en/ui/DORMMENU_GOTO_MAIN.png', 'jp': './assets/jp/ui/DORMMENU_GOTO_MAIN.png', 'tw': './assets/tw/ui/DORMMENU_GOTO_MAIN.png'}) DORMMENU_GOTO_MEOWFFICER = Button(area={'cn': (634, 512, 749, 569), 'en': (634, 512, 749, 569), 'jp': (634, 512, 749, 569), 'tw': (634, 512, 749, 569)}, color={'cn': (144, 153, 176), 'en': (144, 153, 176), 'jp': (144, 153, 176), 'tw': (144, 153, 176)}, button={'cn': (634, 512, 749, 569), 'en': (634, 512, 749, 569), 'jp': (634, 512, 749, 569), 'tw': (634, 512, 749, 569)}, file={'cn': './assets/cn/ui/DORMMENU_GOTO_MEOWFFICER.png', 'en': './assets/en/ui/DORMMENU_GOTO_MEOWFFICER.png', 'jp': './assets/jp/ui/DORMMENU_GOTO_MEOWFFICER.png', 'tw': './assets/tw/ui/DORMMENU_GOTO_MEOWFFICER.png'}) DORMMENU_GOTO_PRIVATE_QUARTERS = Button(area={'cn': (998, 581, 1148, 601), 'en': (998, 581, 1148, 601), 'jp': (998, 581, 1148, 601), 'tw': (998, 581, 1148, 601)}, color={'cn': (140, 140, 139), 'en': (140, 140, 139), 'jp': (140, 140, 139), 'tw': (140, 140, 139)}, button={'cn': (1010, 336, 1140, 596), 'en': (1010, 336, 1140, 596), 'jp': (1010, 336, 1140, 596), 'tw': (1010, 336, 1140, 596)}, file={'cn': './assets/cn/ui/DORMMENU_GOTO_PRIVATE_QUARTERS.png', 'en': './assets/en/ui/DORMMENU_GOTO_PRIVATE_QUARTERS.png', 'jp': './assets/jp/ui/DORMMENU_GOTO_PRIVATE_QUARTERS.png', 'tw': './assets/tw/ui/DORMMENU_GOTO_PRIVATE_QUARTERS.png'}) @@ -48,6 +49,28 @@ IDLE = Button(area={'cn': (864, 672, 873, 688), 'en': (864, 672, 873, 688), 'jp': (864, 672, 873, 688), 'tw': (864, 672, 873, 688)}, color={'cn': (158, 159, 167), 'en': (158, 159, 167), 'jp': (158, 159, 167), 'tw': (158, 159, 167)}, button={'cn': (864, 672, 873, 688), 'en': (864, 672, 873, 688), 'jp': (864, 672, 873, 688), 'tw': (864, 672, 873, 688)}, file={'cn': './assets/cn/ui/IDLE.png', 'en': './assets/en/ui/IDLE.png', 'jp': './assets/jp/ui/IDLE.png', 'tw': './assets/tw/ui/IDLE.png'}) IDLE_2 = Button(area={'cn': (864, 672, 873, 688), 'en': (864, 672, 873, 688), 'jp': (864, 672, 873, 688), 'tw': (864, 672, 873, 688)}, color={'cn': (173, 178, 186), 'en': (173, 178, 186), 'jp': (173, 178, 186), 'tw': (173, 178, 186)}, button={'cn': (864, 672, 873, 688), 'en': (864, 672, 873, 688), 'jp': (864, 672, 873, 688), 'tw': (864, 672, 873, 688)}, file={'cn': './assets/cn/ui/IDLE_2.png', 'en': './assets/cn/ui/IDLE_2.png', 'jp': './assets/cn/ui/IDLE_2.png', 'tw': './assets/cn/ui/IDLE_2.png'}) IDLE_3 = Button(area={'cn': (864, 672, 873, 688), 'en': (864, 672, 873, 688), 'jp': (864, 672, 873, 688), 'tw': (864, 672, 873, 688)}, color={'cn': (185, 183, 182), 'en': (185, 183, 182), 'jp': (185, 183, 182), 'tw': (185, 183, 182)}, button={'cn': (864, 672, 873, 688), 'en': (864, 672, 873, 688), 'jp': (864, 672, 873, 688), 'tw': (864, 672, 873, 688)}, file={'cn': './assets/cn/ui/IDLE_3.png', 'en': './assets/cn/ui/IDLE_3.png', 'jp': './assets/cn/ui/IDLE_3.png', 'tw': './assets/cn/ui/IDLE_3.png'}) +ISLAND_CHECK = Button(area={'cn': (1208, 24, 1248, 64), 'en': (1208, 24, 1248, 64), 'jp': (1208, 24, 1248, 64), 'tw': (1208, 24, 1248, 64)}, color={'cn': (209, 210, 206), 'en': (209, 210, 206), 'jp': (209, 210, 206), 'tw': (209, 210, 206)}, button={'cn': (1208, 24, 1248, 64), 'en': (1208, 24, 1248, 64), 'jp': (1208, 24, 1248, 64), 'tw': (1208, 24, 1248, 64)}, file={'cn': './assets/cn/ui/ISLAND_CHECK.png', 'en': './assets/cn/ui/ISLAND_CHECK.png', 'jp': './assets/cn/ui/ISLAND_CHECK.png', 'tw': './assets/cn/ui/ISLAND_CHECK.png'}) +ISLAND_COMMISSION_CHECK = Button(area={'cn': (199, 134, 373, 184), 'en': (199, 134, 373, 184), 'jp': (199, 134, 373, 184), 'tw': (199, 134, 373, 184)}, color={'cn': (195, 194, 192), 'en': (195, 194, 192), 'jp': (195, 194, 192), 'tw': (195, 194, 192)}, button={'cn': (199, 134, 373, 184), 'en': (199, 134, 373, 184), 'jp': (199, 134, 373, 184), 'tw': (199, 134, 373, 184)}, file={'cn': './assets/cn/ui/ISLAND_COMMISSION_CHECK.png', 'en': './assets/cn/ui/ISLAND_COMMISSION_CHECK.png', 'jp': './assets/jp/ui/ISLAND_COMMISSION_CHECK.png', 'tw': './assets/cn/ui/ISLAND_COMMISSION_CHECK.png'}) +ISLAND_GOTO_ISLAND_MAP = Button(area={'cn': (840, 23, 880, 63), 'en': (840, 23, 880, 63), 'jp': (840, 23, 880, 63), 'tw': (840, 23, 880, 63)}, color={'cn': (197, 199, 196), 'en': (197, 199, 196), 'jp': (197, 199, 196), 'tw': (197, 199, 196)}, button={'cn': (840, 23, 880, 63), 'en': (840, 23, 880, 63), 'jp': (840, 23, 880, 63), 'tw': (840, 23, 880, 63)}, file={'cn': './assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png', 'en': './assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png', 'jp': './assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png', 'tw': './assets/cn/ui/ISLAND_GOTO_ISLAND_MAP.png'}) +ISLAND_GOTO_ISLAND_PHONE = Button(area={'cn': (1208, 24, 1248, 64), 'en': (1208, 24, 1248, 64), 'jp': (1208, 24, 1248, 64), 'tw': (1208, 24, 1248, 64)}, color={'cn': (209, 210, 206), 'en': (209, 210, 206), 'jp': (209, 210, 206), 'tw': (209, 210, 206)}, button={'cn': (1208, 24, 1248, 64), 'en': (1208, 24, 1248, 64), 'jp': (1208, 24, 1248, 64), 'tw': (1208, 24, 1248, 64)}, file={'cn': './assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png', 'en': './assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png', 'jp': './assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png', 'tw': './assets/cn/ui/ISLAND_GOTO_ISLAND_PHONE.png'}) +ISLAND_GOTO_ISLAND_SEASON = Button(area={'cn': (931, 24, 971, 64), 'en': (931, 24, 971, 64), 'jp': (931, 24, 971, 64), 'tw': (931, 24, 971, 64)}, color={'cn': (202, 204, 200), 'en': (202, 204, 200), 'jp': (202, 204, 200), 'tw': (202, 204, 200)}, button={'cn': (931, 24, 971, 64), 'en': (931, 24, 971, 64), 'jp': (931, 24, 971, 64), 'tw': (931, 24, 971, 64)}, file={'cn': './assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png', 'en': './assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png', 'jp': './assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png', 'tw': './assets/cn/ui/ISLAND_GOTO_ISLAND_SEASON.png'}) +ISLAND_GOTO_ISLAND_SHOP = Button(area={'cn': (747, 25, 787, 65), 'en': (747, 25, 787, 65), 'jp': (747, 25, 787, 65), 'tw': (747, 25, 787, 65)}, color={'cn': (195, 196, 194), 'en': (195, 196, 194), 'jp': (195, 196, 194), 'tw': (195, 196, 194)}, button={'cn': (747, 25, 787, 65), 'en': (747, 25, 787, 65), 'jp': (747, 25, 787, 65), 'tw': (747, 25, 787, 65)}, file={'cn': './assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png', 'en': './assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png', 'jp': './assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png', 'tw': './assets/cn/ui/ISLAND_GOTO_ISLAND_SHOP.png'}) +ISLAND_GOTO_ISLAND_TECHNOLOGY = Button(area={'cn': (1025, 26, 1068, 65), 'en': (1025, 26, 1068, 65), 'jp': (1025, 26, 1068, 65), 'tw': (1025, 26, 1068, 65)}, color={'cn': (181, 182, 179), 'en': (181, 182, 179), 'jp': (181, 182, 179), 'tw': (181, 182, 179)}, button={'cn': (1025, 26, 1068, 65), 'en': (1025, 26, 1068, 65), 'jp': (1025, 26, 1068, 65), 'tw': (1025, 26, 1068, 65)}, file={'cn': './assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png', 'en': './assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png', 'jp': './assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png', 'tw': './assets/cn/ui/ISLAND_GOTO_ISLAND_TECHNOLOGY.png'}) +ISLAND_MANAGE_CHECK = Button(area={'cn': (123, 19, 219, 45), 'en': (123, 19, 219, 45), 'jp': (123, 19, 219, 45), 'tw': (123, 19, 219, 45)}, color={'cn': (85, 90, 102), 'en': (85, 90, 102), 'jp': (85, 90, 102), 'tw': (85, 90, 102)}, button={'cn': (123, 19, 219, 45), 'en': (123, 19, 219, 45), 'jp': (123, 19, 219, 45), 'tw': (123, 19, 219, 45)}, file={'cn': './assets/cn/ui/ISLAND_MANAGE_CHECK.png', 'en': './assets/cn/ui/ISLAND_MANAGE_CHECK.png', 'jp': './assets/jp/ui/ISLAND_MANAGE_CHECK.png', 'tw': './assets/cn/ui/ISLAND_MANAGE_CHECK.png'}) +ISLAND_MAP_CHECK = Button(area={'cn': (122, 19, 217, 47), 'en': (122, 19, 217, 47), 'jp': (122, 19, 217, 47), 'tw': (122, 19, 217, 47)}, color={'cn': (93, 102, 112), 'en': (93, 102, 112), 'jp': (93, 102, 112), 'tw': (93, 102, 112)}, button={'cn': (122, 19, 217, 47), 'en': (122, 19, 217, 47), 'jp': (122, 19, 217, 47), 'tw': (122, 19, 217, 47)}, file={'cn': './assets/cn/ui/ISLAND_MAP_CHECK.png', 'en': './assets/cn/ui/ISLAND_MAP_CHECK.png', 'jp': './assets/jp/ui/ISLAND_MAP_CHECK.png', 'tw': './assets/cn/ui/ISLAND_MAP_CHECK.png'}) +ISLAND_ORDER_CHECK = Button(area={'cn': (125, 19, 220, 46), 'en': (125, 19, 220, 46), 'jp': (125, 19, 220, 46), 'tw': (125, 19, 220, 46)}, color={'cn': (79, 88, 100), 'en': (79, 88, 100), 'jp': (79, 88, 100), 'tw': (79, 88, 100)}, button={'cn': (125, 19, 220, 46), 'en': (125, 19, 220, 46), 'jp': (125, 19, 220, 46), 'tw': (125, 19, 220, 46)}, file={'cn': './assets/cn/ui/ISLAND_ORDER_CHECK.png', 'en': './assets/cn/ui/ISLAND_ORDER_CHECK.png', 'jp': './assets/jp/ui/ISLAND_ORDER_CHECK.png', 'tw': './assets/cn/ui/ISLAND_ORDER_CHECK.png'}) +ISLAND_PHONE_CHECK = Button(area={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, color={'cn': (113, 126, 143), 'en': (113, 126, 143), 'jp': (113, 126, 143), 'tw': (113, 126, 143)}, button={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_CHECK.png', 'en': './assets/cn/ui/ISLAND_PHONE_CHECK.png', 'jp': './assets/cn/ui/ISLAND_PHONE_CHECK.png', 'tw': './assets/cn/ui/ISLAND_PHONE_CHECK.png'}) +ISLAND_PHONE_GOTO_ISLAND = Button(area={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, color={'cn': (113, 126, 143), 'en': (113, 126, 143), 'jp': (113, 126, 143), 'tw': (113, 126, 143)}, button={'cn': (0, 0, 829, 720), 'en': (0, 0, 829, 720), 'jp': (0, 0, 829, 720), 'tw': (0, 0, 829, 720)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png', 'en': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png', 'jp': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png', 'tw': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND.png'}) +ISLAND_PHONE_GOTO_ISLAND_COMMISSION = Button(area={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, color={'cn': (113, 126, 143), 'en': (113, 126, 143), 'jp': (113, 126, 143), 'tw': (113, 126, 143)}, button={'cn': (897, 329, 1032, 458), 'en': (897, 329, 1032, 458), 'jp': (897, 329, 1032, 458), 'tw': (897, 329, 1032, 458)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png', 'en': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png', 'jp': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png', 'tw': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_COMMISSION.png'}) +ISLAND_PHONE_GOTO_ISLAND_MANAGE = Button(area={'cn': (1072, 485, 1125, 538), 'en': (1072, 485, 1125, 538), 'jp': (1072, 485, 1125, 538), 'tw': (1072, 485, 1125, 538)}, color={'cn': (180, 221, 124), 'en': (180, 221, 124), 'jp': (180, 221, 124), 'tw': (180, 221, 124)}, button={'cn': (1072, 485, 1125, 538), 'en': (1072, 485, 1125, 538), 'jp': (1072, 485, 1125, 538), 'tw': (1072, 485, 1125, 538)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png', 'en': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png', 'jp': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png', 'tw': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_MANAGE.png'}) +ISLAND_PHONE_GOTO_ISLAND_ORDER = Button(area={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, color={'cn': (113, 126, 143), 'en': (113, 126, 143), 'jp': (113, 126, 143), 'tw': (113, 126, 143)}, button={'cn': (900, 200, 1212, 300), 'en': (900, 200, 1212, 300), 'jp': (900, 200, 1212, 300), 'tw': (900, 200, 1212, 300)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png', 'en': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png', 'jp': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png', 'tw': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_ORDER.png'}) +ISLAND_PHONE_GOTO_ISLAND_STORAGE = Button(area={'cn': (899, 484, 955, 539), 'en': (899, 484, 955, 539), 'jp': (899, 484, 955, 539), 'tw': (899, 484, 955, 539)}, color={'cn': (138, 168, 215), 'en': (138, 168, 215), 'jp': (138, 168, 215), 'tw': (138, 168, 215)}, button={'cn': (899, 484, 955, 539), 'en': (899, 484, 955, 539), 'jp': (899, 484, 955, 539), 'tw': (899, 484, 955, 539)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png', 'en': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png', 'jp': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png', 'tw': './assets/cn/ui/ISLAND_PHONE_GOTO_ISLAND_STORAGE.png'}) +ISLAND_PHONE_GOTO_MAIN = Button(area={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, color={'cn': (113, 126, 143), 'en': (113, 126, 143), 'jp': (113, 126, 143), 'tw': (113, 126, 143)}, button={'cn': (1033, 638, 1080, 684), 'en': (1033, 638, 1080, 684), 'jp': (1033, 638, 1080, 684), 'tw': (1033, 638, 1080, 684)}, file={'cn': './assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png', 'en': './assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png', 'jp': './assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png', 'tw': './assets/cn/ui/ISLAND_PHONE_GOTO_MAIN.png'}) +ISLAND_SEASON_CHECK = Button(area={'cn': (125, 21, 218, 46), 'en': (125, 21, 218, 46), 'jp': (125, 21, 218, 46), 'tw': (125, 21, 218, 46)}, color={'cn': (60, 68, 81), 'en': (60, 68, 81), 'jp': (60, 68, 81), 'tw': (60, 68, 81)}, button={'cn': (125, 21, 218, 46), 'en': (125, 21, 218, 46), 'jp': (125, 21, 218, 46), 'tw': (125, 21, 218, 46)}, file={'cn': './assets/cn/ui/ISLAND_SEASON_CHECK.png', 'en': './assets/cn/ui/ISLAND_SEASON_CHECK.png', 'jp': './assets/jp/ui/ISLAND_SEASON_CHECK.png', 'tw': './assets/cn/ui/ISLAND_SEASON_CHECK.png'}) +ISLAND_SHOP_CHECK = Button(area={'cn': (994, 25, 1016, 46), 'en': (994, 25, 1016, 46), 'jp': (994, 25, 1016, 46), 'tw': (994, 25, 1016, 46)}, color={'cn': (220, 188, 75), 'en': (220, 188, 75), 'jp': (220, 188, 75), 'tw': (220, 188, 75)}, button={'cn': (994, 25, 1016, 46), 'en': (994, 25, 1016, 46), 'jp': (994, 25, 1016, 46), 'tw': (994, 25, 1016, 46)}, file={'cn': './assets/cn/ui/ISLAND_SHOP_CHECK.png', 'en': './assets/cn/ui/ISLAND_SHOP_CHECK.png', 'jp': './assets/cn/ui/ISLAND_SHOP_CHECK.png', 'tw': './assets/cn/ui/ISLAND_SHOP_CHECK.png'}) +ISLAND_STORAGE_CHECK = Button(area={'cn': (159, 99, 195, 117), 'en': (159, 99, 195, 117), 'jp': (159, 99, 195, 117), 'tw': (159, 99, 195, 117)}, color={'cn': (104, 105, 108), 'en': (104, 105, 108), 'jp': (104, 105, 108), 'tw': (104, 105, 108)}, button={'cn': (159, 99, 195, 117), 'en': (159, 99, 195, 117), 'jp': (159, 99, 195, 117), 'tw': (159, 99, 195, 117)}, file={'cn': './assets/cn/ui/ISLAND_STORAGE_CHECK.png', 'en': './assets/cn/ui/ISLAND_STORAGE_CHECK.png', 'jp': './assets/jp/ui/ISLAND_STORAGE_CHECK.png', 'tw': './assets/cn/ui/ISLAND_STORAGE_CHECK.png'}) +ISLAND_STORAGE_EXIT = Button(area={'cn': (1124, 86, 1163, 123), 'en': (1124, 86, 1163, 123), 'jp': (1124, 86, 1163, 123), 'tw': (1124, 86, 1163, 123)}, color={'cn': (228, 228, 228), 'en': (228, 228, 228), 'jp': (228, 228, 228), 'tw': (228, 228, 228)}, button={'cn': (1124, 86, 1163, 123), 'en': (1124, 86, 1163, 123), 'jp': (1124, 86, 1163, 123), 'tw': (1124, 86, 1163, 123)}, file={'cn': './assets/cn/ui/ISLAND_STORAGE_EXIT.png', 'en': './assets/cn/ui/ISLAND_STORAGE_EXIT.png', 'jp': './assets/cn/ui/ISLAND_STORAGE_EXIT.png', 'tw': './assets/cn/ui/ISLAND_STORAGE_EXIT.png'}) +ISLAND_TECHNOLOGY_CHECK = Button(area={'cn': (123, 19, 218, 46), 'en': (123, 19, 218, 46), 'jp': (123, 19, 218, 46), 'tw': (123, 19, 218, 46)}, color={'cn': (86, 90, 102), 'en': (86, 90, 102), 'jp': (86, 90, 102), 'tw': (86, 90, 102)}, button={'cn': (123, 19, 218, 46), 'en': (123, 19, 218, 46), 'jp': (123, 19, 218, 46), 'tw': (123, 19, 218, 46)}, file={'cn': './assets/cn/ui/ISLAND_TECHNOLOGY_CHECK.png', 'en': './assets/cn/ui/ISLAND_TECHNOLOGY_CHECK.png', 'jp': './assets/jp/ui/ISLAND_TECHNOLOGY_CHECK.png', 'tw': './assets/cn/ui/ISLAND_TECHNOLOGY_CHECK.png'}) MAIN_GOTO_BUILD = Button(area={'cn': (958, 665, 1113, 714), 'en': (962, 688, 1109, 711), 'jp': (1035, 674, 1088, 702), 'tw': (963, 671, 1091, 709)}, color={'cn': (129, 83, 76), 'en': (145, 88, 79), 'jp': (187, 131, 125), 'tw': (145, 93, 85)}, button={'cn': (958, 665, 1113, 714), 'en': (962, 688, 1109, 711), 'jp': (1035, 674, 1088, 702), 'tw': (963, 671, 1091, 709)}, file={'cn': './assets/cn/ui/MAIN_GOTO_BUILD.png', 'en': './assets/en/ui/MAIN_GOTO_BUILD.png', 'jp': './assets/jp/ui/MAIN_GOTO_BUILD.png', 'tw': './assets/tw/ui/MAIN_GOTO_BUILD.png'}) MAIN_GOTO_CAMPAIGN = Button(area={'cn': (1029, 304, 1102, 342), 'en': (1027, 307, 1118, 333), 'jp': (1019, 305, 1096, 343), 'tw': (1026, 303, 1104, 344)}, color={'cn': (240, 213, 157), 'en': (243, 219, 165), 'jp': (239, 210, 155), 'tw': (240, 213, 162)}, button={'cn': (1021, 292, 1160, 432), 'en': (1018, 293, 1156, 431), 'jp': (1006, 288, 1155, 436), 'tw': (1014, 288, 1159, 433)}, file={'cn': './assets/cn/ui/MAIN_GOTO_CAMPAIGN.png', 'en': './assets/en/ui/MAIN_GOTO_CAMPAIGN.png', 'jp': './assets/jp/ui/MAIN_GOTO_CAMPAIGN.png', 'tw': './assets/tw/ui/MAIN_GOTO_CAMPAIGN.png'}) MAIN_GOTO_DOCK = Button(area={'cn': (172, 668, 326, 715), 'en': (172, 668, 326, 715), 'jp': (172, 668, 326, 715), 'tw': (172, 668, 326, 715)}, color={'cn': (72, 90, 122), 'en': (72, 90, 122), 'jp': (72, 90, 122), 'tw': (72, 90, 122)}, button={'cn': (172, 668, 326, 715), 'en': (172, 668, 326, 715), 'jp': (172, 668, 326, 715), 'tw': (172, 668, 326, 715)}, file={'cn': './assets/cn/ui/MAIN_GOTO_DOCK.png', 'en': './assets/en/ui/MAIN_GOTO_DOCK.png', 'jp': './assets/jp/ui/MAIN_GOTO_DOCK.png', 'tw': './assets/tw/ui/MAIN_GOTO_DOCK.png'}) diff --git a/module/ui/page.py b/module/ui/page.py index 8ec4956731..64661437e8 100644 --- a/module/ui/page.py +++ b/module/ui/page.py @@ -276,6 +276,47 @@ def link(self, button, destination): page_dormmenu.link(button=DORMMENU_GOTO_PRIVATE_QUARTERS, destination=page_private_quarters) page_private_quarters.link(button=PQ_GOTO_MAIN, destination=page_main) +# Island +page_island = Page(ISLAND_CHECK) +page_dormmenu.link(button=DORMMENU_GOTO_ISLAND, destination=page_island) + +page_island_shop = Page(ISLAND_SHOP_CHECK) # use coin icon as check +page_island.link(button=ISLAND_GOTO_ISLAND_SHOP, destination=page_island_shop) +page_island_shop.link(button=BACK_ARROW_WHITE, destination=page_island) + +page_island_map = Page(ISLAND_MAP_CHECK) +page_island.link(button=ISLAND_GOTO_ISLAND_MAP, destination=page_island_map) +page_island_map.link(button=BACK_ARROW_WHITE, destination=page_island) + +page_island_season = Page(ISLAND_SEASON_CHECK) +page_island.link(button=ISLAND_GOTO_ISLAND_SEASON, destination=page_island_season) +page_island_season.link(button=BACK_ARROW_WHITE, destination=page_island) + +page_island_technology = Page(ISLAND_TECHNOLOGY_CHECK) +page_island.link(button=ISLAND_GOTO_ISLAND_TECHNOLOGY, destination=page_island_technology) +page_island_technology.link(button=BACK_ARROW_WHITE, destination=page_island) + +page_island_phone = Page(ISLAND_PHONE_CHECK) +page_island.link(button=ISLAND_GOTO_ISLAND_PHONE, destination=page_island_phone) +page_island_phone.link(button=ISLAND_PHONE_GOTO_ISLAND, destination=page_island) +page_island_phone.link(button=ISLAND_PHONE_GOTO_MAIN, destination=page_main) + +page_island_order = Page(ISLAND_ORDER_CHECK) +page_island_phone.link(button=ISLAND_PHONE_GOTO_ISLAND_ORDER, destination=page_island_order) +page_island_order.link(button=BACK_ARROW_WHITE, destination=page_island_phone) + +page_island_commission = Page(ISLAND_COMMISSION_CHECK) # IslandShipOrder +page_island_phone.link(button=ISLAND_PHONE_GOTO_ISLAND_COMMISSION, destination=page_island_commission) +page_island_commission.link(button=BACK_ARROW_WHITE, destination=page_island_phone) + +page_island_storage = Page(ISLAND_STORAGE_CHECK) +page_island_phone.link(button=ISLAND_PHONE_GOTO_ISLAND_STORAGE, destination=page_island_storage) +page_island_storage.link(button=ISLAND_STORAGE_EXIT, destination=page_island_phone) + +page_island_manage = Page(ISLAND_MANAGE_CHECK) +page_island_phone.link(button=ISLAND_PHONE_GOTO_ISLAND_MANAGE, destination=page_island_manage) +page_island_manage.link(button=BACK_ARROW_WHITE, destination=page_island_phone) + # Game room & choose game page_game_room = Page(GAME_ROOM_CHECK) page_academy.link(button=ACADEMY_GOTO_GAME_ROOM, destination=page_game_room)