Merge pull request #2996 from guoh064/meta_reward
Add: Dossier Meta Reward Receive
BIN
assets/cn/meta_reward/DOSSIER_REWARD_CHECK.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/cn/meta_reward/DOSSIER_REWARD_ENTER.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/cn/meta_reward/DOSSIER_REWARD_RECEIVE.BUTTON.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/cn/meta_reward/DOSSIER_REWARD_RECEIVE.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 248 B |
BIN
assets/en/meta_reward/DOSSIER_REWARD_CHECK.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/en/meta_reward/DOSSIER_REWARD_ENTER.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/en/meta_reward/DOSSIER_REWARD_RECEIVE.BUTTON.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/en/meta_reward/DOSSIER_REWARD_RECEIVE.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 248 B |
BIN
assets/jp/meta_reward/DOSSIER_REWARD_CHECK.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/jp/meta_reward/DOSSIER_REWARD_ENTER.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/jp/meta_reward/DOSSIER_REWARD_RECEIVE.BUTTON.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/jp/meta_reward/DOSSIER_REWARD_RECEIVE.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 248 B |
Before Width: | Height: | Size: 248 B |
@ -4,6 +4,9 @@ from module.base.template import Template
|
||||
# This file was automatically generated by dev_tools/button_extract.py.
|
||||
# Don't modify it manually.
|
||||
|
||||
DOSSIER_REWARD_CHECK = Button(area={'cn': (120, 14, 231, 40), 'en': (120, 14, 316, 39), 'jp': (119, 13, 231, 39), 'tw': (120, 14, 231, 40)}, color={'cn': (176, 159, 160), 'en': (130, 105, 104), 'jp': (183, 169, 170), 'tw': (176, 159, 160)}, button={'cn': (120, 14, 231, 40), 'en': (120, 14, 316, 39), 'jp': (119, 13, 231, 39), 'tw': (120, 14, 231, 40)}, file={'cn': './assets/cn/meta_reward/DOSSIER_REWARD_CHECK.png', 'en': './assets/en/meta_reward/DOSSIER_REWARD_CHECK.png', 'jp': './assets/jp/meta_reward/DOSSIER_REWARD_CHECK.png', 'tw': './assets/cn/meta_reward/DOSSIER_REWARD_CHECK.png'})
|
||||
DOSSIER_REWARD_ENTER = Button(area={'cn': (244, 645, 404, 709), 'en': (244, 645, 404, 709), 'jp': (244, 645, 404, 709), 'tw': (244, 645, 404, 709)}, color={'cn': (104, 87, 80), 'en': (104, 87, 80), 'jp': (104, 87, 80), 'tw': (104, 87, 80)}, button={'cn': (244, 645, 404, 709), 'en': (244, 645, 404, 709), 'jp': (244, 645, 404, 709), 'tw': (244, 645, 404, 709)}, file={'cn': './assets/cn/meta_reward/DOSSIER_REWARD_ENTER.png', 'en': './assets/en/meta_reward/DOSSIER_REWARD_ENTER.png', 'jp': './assets/jp/meta_reward/DOSSIER_REWARD_ENTER.png', 'tw': './assets/cn/meta_reward/DOSSIER_REWARD_ENTER.png'})
|
||||
DOSSIER_REWARD_RECEIVE = Button(area={'cn': (426, 617, 432, 628), 'en': (426, 617, 432, 628), 'jp': (426, 617, 432, 628), 'tw': (426, 617, 432, 628)}, color={'cn': (214, 117, 103), 'en': (214, 117, 103), 'jp': (214, 117, 103), 'tw': (214, 117, 103)}, button={'cn': (320, 622, 428, 651), 'en': (320, 622, 428, 651), 'jp': (320, 622, 428, 651), 'tw': (320, 622, 428, 651)}, file={'cn': './assets/cn/meta_reward/DOSSIER_REWARD_RECEIVE.png', 'en': './assets/en/meta_reward/DOSSIER_REWARD_RECEIVE.png', 'jp': './assets/jp/meta_reward/DOSSIER_REWARD_RECEIVE.png', 'tw': './assets/cn/meta_reward/DOSSIER_REWARD_RECEIVE.png'})
|
||||
META_REWARD_NOTICE = Button(area={'cn': (1070, 508, 1075, 523), 'en': (1070, 508, 1075, 523), 'jp': (1070, 508, 1075, 523), 'tw': (1070, 508, 1075, 523)}, color={'cn': (249, 182, 57), 'en': (249, 182, 57), 'jp': (249, 182, 57), 'tw': (249, 182, 57)}, button={'cn': (1070, 508, 1075, 523), 'en': (1070, 508, 1075, 523), 'jp': (1070, 508, 1075, 523), 'tw': (1070, 508, 1075, 523)}, file={'cn': './assets/cn/meta_reward/META_REWARD_NOTICE.png', 'en': './assets/en/meta_reward/META_REWARD_NOTICE.png', 'jp': './assets/jp/meta_reward/META_REWARD_NOTICE.png', 'tw': './assets/cn/meta_reward/META_REWARD_NOTICE.png'})
|
||||
REWARD_CHECK = Button(area={'cn': (31, 486, 64, 543), 'en': (35, 487, 62, 541), 'jp': (31, 486, 64, 543), 'tw': (31, 486, 64, 543)}, color={'cn': (199, 164, 165), 'en': (203, 169, 170), 'jp': (206, 172, 174), 'tw': (199, 164, 165)}, button={'cn': (31, 486, 64, 543), 'en': (35, 487, 62, 541), 'jp': (31, 486, 64, 543), 'tw': (31, 486, 64, 543)}, file={'cn': './assets/cn/meta_reward/REWARD_CHECK.png', 'en': './assets/en/meta_reward/REWARD_CHECK.png', 'jp': './assets/jp/meta_reward/REWARD_CHECK.png', 'tw': './assets/cn/meta_reward/REWARD_CHECK.png'})
|
||||
REWARD_ENTER = Button(area={'cn': (1109, 535, 1187, 554), 'en': (1106, 532, 1199, 544), 'jp': (1108, 535, 1188, 554), 'tw': (1109, 535, 1187, 554)}, color={'cn': (199, 195, 201), 'en': (213, 212, 217), 'jp': (215, 207, 214), 'tw': (199, 195, 201)}, button={'cn': (1109, 535, 1187, 554), 'en': (1106, 532, 1199, 544), 'jp': (1108, 535, 1188, 554), 'tw': (1109, 535, 1187, 554)}, file={'cn': './assets/cn/meta_reward/REWARD_ENTER.png', 'en': './assets/en/meta_reward/REWARD_ENTER.png', 'jp': './assets/jp/meta_reward/REWARD_ENTER.png', 'tw': './assets/cn/meta_reward/REWARD_ENTER.png'})
|
||||
|
@ -1,103 +1,13 @@
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import *
|
||||
from module.combat.combat import Combat
|
||||
from module.logger import logger
|
||||
from module.meta_reward.assets import *
|
||||
from module.template.assets import TEMPLATE_META_DOCK_RED_DOT
|
||||
from module.ui.assets import BACK_ARROW
|
||||
from module.os_ash.assets import DOSSIER_LIST
|
||||
from module.ui.page import page_meta
|
||||
from module.ui.ui import UI
|
||||
|
||||
|
||||
class MetaReward(Combat, UI):
|
||||
def meta_labo_get_sidebar_icon_button(self):
|
||||
"""
|
||||
Get icon button of meta ship.
|
||||
|
||||
Returns:
|
||||
list[Button]: Enter button
|
||||
|
||||
Pages:
|
||||
in: page_meta
|
||||
"""
|
||||
# Where the click buttons are
|
||||
detection_area = (8, 385, 147, 680)
|
||||
# Offset inside to avoid clicking on edge
|
||||
pad = 2
|
||||
|
||||
list_enter = []
|
||||
dots = TEMPLATE_META_DOCK_RED_DOT.match_multi(self.image_crop(detection_area), threshold=5)
|
||||
logger.info(f'Possible meta ships found: {len(dots)}')
|
||||
for button in dots:
|
||||
button = button.move(vector=detection_area[:2])
|
||||
enter = button.crop(area=(-129, 3, 3, 42), name='META_SHIP_ENTRANCE')
|
||||
enter.area = area_limit(enter.area, detection_area)
|
||||
enter._button = area_pad(enter.area, pad)
|
||||
list_enter.append(enter)
|
||||
return list_enter
|
||||
|
||||
def meta_labo_sidebar_swipe(self, downward=True, skip_first_screenshot=True):
|
||||
"""
|
||||
Swipe down meta lab sidebar to search for red dots.
|
||||
|
||||
|
||||
Args:
|
||||
downward (boot): direction of vertical swipe
|
||||
skip_first_screenshot (bool):
|
||||
|
||||
Returns:
|
||||
bool: If found possible red dot.
|
||||
"""
|
||||
# Where meta dock scroll part is
|
||||
detection_area = (8, 392, 233, 680)
|
||||
direction_vector = (0, -200) if downward else (0, 200)
|
||||
|
||||
for _ in range(5):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
icon = self.meta_labo_get_sidebar_icon_button()
|
||||
if len(icon):
|
||||
return True
|
||||
|
||||
p1, p2 = random_rectangle_vector(
|
||||
direction_vector, box=detection_area, random_range=(-30, -30, 30, 30), padding=20)
|
||||
self.device.drag(p1, p2, segments=2, shake=(0, 25), point_random=(0, 0, 0, 0), shake_random=(-3, 0, 3, 0))
|
||||
self.device.sleep(0.3)
|
||||
|
||||
logger.info('No more dossier reward for receiving')
|
||||
return False
|
||||
|
||||
def meta_labo_sidebar_icon_button_click(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Click possible dossier ship icon if red dot appears.
|
||||
|
||||
Returns:
|
||||
bool: If clicked
|
||||
"""
|
||||
timer = Timer(2, count=5)
|
||||
clicked = False
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
icon = self.meta_labo_get_sidebar_icon_button()
|
||||
if not len(icon):
|
||||
break
|
||||
if timer.reached():
|
||||
logger.info('Click on possible ship icon for further check')
|
||||
self.device.click(icon[0])
|
||||
# After clicking the icon will enlarge, resulting in original icon to no more match.
|
||||
timer.reset()
|
||||
clicked = True
|
||||
continue
|
||||
|
||||
return clicked
|
||||
|
||||
class BeaconReward(Combat, UI):
|
||||
def meta_reward_notice_appear(self):
|
||||
"""
|
||||
Returns:
|
||||
@ -182,54 +92,8 @@ class MetaReward(Combat, UI):
|
||||
|
||||
logger.info(f'Meta reward receive finished, received={received}')
|
||||
return received
|
||||
|
||||
def meta_reward_exit(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Pages:
|
||||
in: REWARD_CHECK
|
||||
out: page_meta
|
||||
"""
|
||||
logger.info('Meta reward exit')
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(REWARD_CHECK, offset=(20, 20)):
|
||||
if self.appear_then_click(BACK_ARROW, offset=(20, 20), interval=3):
|
||||
continue
|
||||
|
||||
#ENd
|
||||
if self.appear(REWARD_ENTER, offset=(20, 20)):
|
||||
return
|
||||
|
||||
def get_meta_reward(self):
|
||||
'''
|
||||
Wrapper for actual meta reward check and obtain process.
|
||||
|
||||
Pages: page_meta
|
||||
'''
|
||||
logger.info('Check meta ship reward status')
|
||||
if self.meta_reward_notice_appear():
|
||||
self.meta_reward_enter()
|
||||
self.meta_reward_receive()
|
||||
self.meta_reward_exit()
|
||||
|
||||
def search_for_dossier_reward(self):
|
||||
# Check for red dots on dossier ship lists
|
||||
logger.info('Search for dossier ship')
|
||||
while self.meta_labo_sidebar_swipe():
|
||||
# After clicking the ship icon will enlarge.
|
||||
self.meta_labo_sidebar_icon_button_click()
|
||||
logger.info('Check dossier ship')
|
||||
self.get_meta_reward()
|
||||
|
||||
def has_possible_dossier_reward(self, is_dossier):
|
||||
return (is_dossier and "dossier" in self.config.OpsiAshBeacon_AttackMode)
|
||||
|
||||
def run(self, dossier=True):
|
||||
# Server check
|
||||
def run(self):
|
||||
if self.config.SERVER in ['cn', 'en', 'jp']:
|
||||
pass
|
||||
else:
|
||||
@ -237,18 +101,118 @@ class MetaReward(Combat, UI):
|
||||
return
|
||||
|
||||
self.ui_ensure(page_meta)
|
||||
|
||||
# OpsiAshBeacon currently does not have a is_dossier property, so needs to do if/else here.
|
||||
# Deal current ship reward first.
|
||||
logger.info('Check current ship')
|
||||
self.get_meta_reward()
|
||||
|
||||
# If dossier beacon is not enabled, or MetaReward is invoked
|
||||
# by AshBeaconAssist, do not need to check dossier
|
||||
if self.has_possible_dossier_reward(is_dossier=dossier):
|
||||
# self.search_for_dossier_reward()
|
||||
logger.info('Dossier meta reward receiving feature is temporarily disabled by the developer. \nPlease receive it by yourself for the time.')
|
||||
if self.meta_reward_notice_appear():
|
||||
self.meta_reward_enter()
|
||||
self.meta_reward_receive()
|
||||
|
||||
|
||||
class DossierReward(Combat, UI):
|
||||
def meta_reward_notice_appear(self):
|
||||
"""
|
||||
Returns:
|
||||
bool: If appear.
|
||||
|
||||
Page:
|
||||
in: dossier meta page
|
||||
"""
|
||||
self.device.screenshot()
|
||||
if self.appear(DOSSIER_REWARD_RECEIVE, offset=(100, 100), threshold=30):
|
||||
logger.info('Found dossier reward red dot')
|
||||
return True
|
||||
else:
|
||||
logger.info('MetaReward is called by current beacon, skip dossier reward check')
|
||||
logger.info('No dossier reward red dot')
|
||||
return False
|
||||
|
||||
def meta_reward_enter(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Pages:
|
||||
in: dossier meta page
|
||||
out: DOSSIER_REWARD_CHECK
|
||||
"""
|
||||
logger.info('Dossier reward enter')
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
self.device.click(DOSSIER_REWARD_ENTER)
|
||||
continue
|
||||
|
||||
# End
|
||||
if self.appear(DOSSIER_REWARD_CHECK, offset=(20, 20)):
|
||||
break
|
||||
|
||||
def meta_reward_receive(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Args:
|
||||
skip_first_screenshot:
|
||||
|
||||
Returns:
|
||||
bool: If received.
|
||||
|
||||
Pages:
|
||||
in: DOSSIER_REWARD_CHECK
|
||||
out: DOSSIER_REWARD_CHECK
|
||||
"""
|
||||
logger.hr('Dossier reward receive', level=1)
|
||||
confirm_timer = Timer(1, count=3).start()
|
||||
received = False
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(DOSSIER_REWARD_RECEIVE, offset=(20, 20), interval=3) and DOSSIER_REWARD_RECEIVE.match_appear_on(
|
||||
self.device.image):
|
||||
self.device.click(DOSSIER_REWARD_RECEIVE)
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.handle_popup_confirm('DOSSIER_REWARD'):
|
||||
# Lock new META ships
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.handle_get_items():
|
||||
received = True
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.handle_get_ship():
|
||||
received = True
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
|
||||
# End
|
||||
if not self.appear(DOSSIER_REWARD_RECEIVE, offset=(20, 20)):
|
||||
if confirm_timer.reached():
|
||||
break
|
||||
else:
|
||||
confirm_timer.reset()
|
||||
|
||||
logger.info(f'Dossier reward receive finished, received={received}')
|
||||
return received
|
||||
|
||||
def run(self):
|
||||
if self.config.SERVER in ['cn', 'en', 'jp']:
|
||||
pass
|
||||
else:
|
||||
logger.info(f'MetaReward is not supported in {self.config.SERVER}, please contact server maintainers')
|
||||
return
|
||||
|
||||
|
||||
from module.os_ash.meta import OpsiAshBeacon
|
||||
OpsiAshBeacon(self.config, self.device).ensure_dossier_page()
|
||||
if self.meta_reward_notice_appear():
|
||||
self.meta_reward_enter()
|
||||
self.meta_reward_receive()
|
||||
|
||||
|
||||
class MetaReward(BeaconReward, DossierReward):
|
||||
def run(self, category="beacon"):
|
||||
if category == "beacon":
|
||||
BeaconReward(self.config, self.device).run()
|
||||
elif category == "dossier":
|
||||
DossierReward(self.config, self.device).run()
|
||||
else:
|
||||
logger.info(f'Possible wrong parameter {category}, please contact the developers.')
|
||||
|
@ -75,7 +75,8 @@ def _server_support_dossier_auto_attack():
|
||||
|
||||
|
||||
class OpsiAshBeacon(Meta):
|
||||
_meta_receive_count = 0
|
||||
_meta_receive = []
|
||||
_meta_category = "undefined"
|
||||
|
||||
def _attack_meta(self, skip_first_screenshot=True):
|
||||
"""
|
||||
@ -111,7 +112,8 @@ class OpsiAshBeacon(Meta):
|
||||
continue
|
||||
if MetaState.COMPLETE == state:
|
||||
self._handle_ash_beacon_reward()
|
||||
self._meta_receive_count += 1
|
||||
if not self._meta_category in self._meta_receive:
|
||||
self._meta_receive.append(self._meta_category)
|
||||
# Check other tasks after kill a meta
|
||||
self.config.check_task_switch()
|
||||
continue
|
||||
@ -230,7 +232,7 @@ class OpsiAshBeacon(Meta):
|
||||
|
||||
def _pre_attack(self):
|
||||
"""
|
||||
Some pre_attack preparations.
|
||||
Some pre_attack preparations, including recording meta category.
|
||||
In beacon:
|
||||
ask for help if needed
|
||||
In dossier:
|
||||
@ -239,11 +241,13 @@ class OpsiAshBeacon(Meta):
|
||||
"""
|
||||
# Page beacon or dossier
|
||||
if self.appear(BEACON_LIST, offset=(20, 20)):
|
||||
self._meta_category = "beacon"
|
||||
if self.config.OpsiAshBeacon_OneHitMode or self.config.OpsiAshBeacon_RequestAssist:
|
||||
if not self._ask_for_help():
|
||||
return False
|
||||
return True
|
||||
if self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
self._meta_category = "dossier"
|
||||
# can auto attack but not auto attacking
|
||||
if _server_support_dossier_auto_attack() and self.config.OpsiAshBeacon_DossierAutoAttackMode \
|
||||
and self.appear(META_AUTO_ATTACK_START, offset=(5, 5)):
|
||||
@ -441,6 +445,25 @@ class OpsiAshBeacon(Meta):
|
||||
if self.appear_then_click(META_ENTRANCE, offset=(20, 300), interval=2):
|
||||
continue
|
||||
|
||||
def ensure_dossier_page(self, skip_first_screenshot=True):
|
||||
self.ui_ensure(page_reward)
|
||||
self._ensure_meta_page()
|
||||
logger.info('Ensure dossier meta page')
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
logger.info('In dossier page')
|
||||
return True
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
if self.appear(ASH_SHOWDOWN, offset=(30, 30)):
|
||||
self.device.click(META_MAIN_DOSSIER_ENTRANCE)
|
||||
continue
|
||||
|
||||
def _begin_beacon(self):
|
||||
logger.hr('Meta Beacon Attack')
|
||||
if not _server_support():
|
||||
@ -453,8 +476,9 @@ class OpsiAshBeacon(Meta):
|
||||
self._begin_beacon()
|
||||
|
||||
with self.config.multi_set():
|
||||
if self._meta_receive_count > 0:
|
||||
MetaReward(self.config, self.device).run()
|
||||
for meta in self._meta_receive:
|
||||
MetaReward(self.config, self.device).run(category=meta)
|
||||
self._meta_receive = []
|
||||
self.config.task_delay(server_update=True)
|
||||
|
||||
|
||||
@ -583,7 +607,7 @@ class AshBeaconAssist(Meta):
|
||||
self.ui_ensure(page_reward)
|
||||
|
||||
if self._begin_meta_assist():
|
||||
MetaReward(self.config, self.device).run(dossier=False)
|
||||
MetaReward(self.config, self.device).run()
|
||||
self.config.task_delay(server_update=True)
|
||||
else:
|
||||
self.config.task_delay(minute=(10, 20))
|
||||
|
@ -30,7 +30,6 @@ TEMPLATE_FORMATION_1 = Template(file={'cn': './assets/cn/template/TEMPLATE_FORMA
|
||||
TEMPLATE_FORMATION_2 = Template(file={'cn': './assets/cn/template/TEMPLATE_FORMATION_2.png', 'en': './assets/en/template/TEMPLATE_FORMATION_2.png', 'jp': './assets/jp/template/TEMPLATE_FORMATION_2.png', 'tw': './assets/tw/template/TEMPLATE_FORMATION_2.png'})
|
||||
TEMPLATE_FORMATION_3 = Template(file={'cn': './assets/cn/template/TEMPLATE_FORMATION_3.png', 'en': './assets/en/template/TEMPLATE_FORMATION_3.png', 'jp': './assets/jp/template/TEMPLATE_FORMATION_3.png', 'tw': './assets/tw/template/TEMPLATE_FORMATION_3.png'})
|
||||
TEMPLATE_MAP_WALK_OUT_OF_STEP = Template(file={'cn': './assets/cn/template/TEMPLATE_MAP_WALK_OUT_OF_STEP.png', 'en': './assets/en/template/TEMPLATE_MAP_WALK_OUT_OF_STEP.png', 'jp': './assets/jp/template/TEMPLATE_MAP_WALK_OUT_OF_STEP.png', 'tw': './assets/tw/template/TEMPLATE_MAP_WALK_OUT_OF_STEP.png'})
|
||||
TEMPLATE_META_DOCK_RED_DOT = Template(file={'cn': './assets/cn/template/TEMPLATE_META_DOCK_RED_DOT.png', 'en': './assets/en/template/TEMPLATE_META_DOCK_RED_DOT.png', 'jp': './assets/jp/template/TEMPLATE_META_DOCK_RED_DOT.png', 'tw': './assets/tw/template/TEMPLATE_META_DOCK_RED_DOT.png'})
|
||||
TEMPLATE_OPERATIONS_ADD = Template(file={'cn': './assets/cn/template/TEMPLATE_OPERATIONS_ADD.png', 'en': './assets/en/template/TEMPLATE_OPERATIONS_ADD.png', 'jp': './assets/jp/template/TEMPLATE_OPERATIONS_ADD.png', 'tw': './assets/tw/template/TEMPLATE_OPERATIONS_ADD.png'})
|
||||
TEMPLATE_OPERATIONS_RED_DOT = Template(file={'cn': './assets/cn/template/TEMPLATE_OPERATIONS_RED_DOT.png', 'en': './assets/en/template/TEMPLATE_OPERATIONS_RED_DOT.png', 'jp': './assets/jp/template/TEMPLATE_OPERATIONS_RED_DOT.png', 'tw': './assets/tw/template/TEMPLATE_OPERATIONS_RED_DOT.png'})
|
||||
TEMPLATE_OS_AllyCargo = Template(file={'cn': './assets/cn/template/TEMPLATE_OS_AllyCargo.png', 'en': './assets/en/template/TEMPLATE_OS_AllyCargo.png', 'jp': './assets/jp/template/TEMPLATE_OS_AllyCargo.png', 'tw': './assets/tw/template/TEMPLATE_OS_AllyCargo.png'})
|
||||
|