1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-19 11:53:35 +08:00

Merge pull request #5468 from LmeSzinc/dev

Add: Light & Shadow Fashion Shoot! (event_20260122_cn)
This commit is contained in:
LmeSzinc
2026-01-23 02:50:57 +08:00
committed by GitHub
57 changed files with 377 additions and 658 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -275,3 +275,5 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
| 20251218 | event 20251218 cn | A Note Through the Firmament | 响彻于天穹之音 | A Note Through the Firmament | 天穹に響く音謡 | - | | 20251218 | event 20251218 cn | A Note Through the Firmament | 响彻于天穹之音 | A Note Through the Firmament | 天穹に響く音謡 | - |
| 20251231 | event 20251218 cn | A Note Through the Firmament | - | - | - | 響徹於天穹之音 | | 20251231 | event 20251218 cn | A Note Through the Firmament | - | - | - | 響徹於天穹之音 |
| 20260115 | event 20231221 cn | Light-Chasing Sea of Stars Rerun | 复刻星海逐光 | Light-Chasing Sea of Stars Rerun | 光追う星の海(復刻) | - | | 20260115 | event 20231221 cn | Light-Chasing Sea of Stars Rerun | 复刻星海逐光 | Light-Chasing Sea of Stars Rerun | 光追う星の海(復刻) | - |
| 20260122 | coalition 20260122 | Light & Shadow Fashion Shoot! | 光影风尚-拍摄进行时 | Light & Shadow Fashion Shoot! | 特集写真-撮影進行中 | - |
| 20260122 | event 20220526 cn | Pledge of the Radiant Court | - | - | - | 泠誓光庭 |

View File

@@ -614,7 +614,7 @@
"AmbushEvade": true "AmbushEvade": true
}, },
"Coalition": { "Coalition": {
"Mode": "area1-normal", "Mode": "hard",
"Fleet": "single" "Fleet": "single"
}, },
"StopCondition": { "StopCondition": {
@@ -1185,7 +1185,7 @@
"AmbushEvade": true "AmbushEvade": true
}, },
"Coalition": { "Coalition": {
"Mode": "area1-normal", "Mode": "sp",
"Fleet": "single" "Fleet": "single"
}, },
"StopCondition": { "StopCondition": {

View File

@@ -36,6 +36,17 @@ DAL_SWITCH_MULTI = Button(area={'cn': (1060, 473, 1204, 500), 'en': (1061, 474,
DAL_SWITCH_SINGLE = Button(area={'cn': (910, 473, 1055, 500), 'en': (915, 475, 1051, 499), 'jp': (917, 474, 1035, 499), 'tw': (945, 478, 1013, 495)}, color={'cn': (223, 223, 223), 'en': (193, 193, 193), 'jp': (215, 215, 215), 'tw': (168, 168, 168)}, button={'cn': (910, 473, 1055, 500), 'en': (915, 475, 1051, 499), 'jp': (917, 474, 1035, 499), 'tw': (945, 478, 1013, 495)}, file={'cn': './assets/cn/coalition/DAL_SWITCH_SINGLE.png', 'en': './assets/en/coalition/DAL_SWITCH_SINGLE.png', 'jp': './assets/jp/coalition/DAL_SWITCH_SINGLE.png', 'tw': './assets/tw/coalition/DAL_SWITCH_SINGLE.png'}) DAL_SWITCH_SINGLE = Button(area={'cn': (910, 473, 1055, 500), 'en': (915, 475, 1051, 499), 'jp': (917, 474, 1035, 499), 'tw': (945, 478, 1013, 495)}, color={'cn': (223, 223, 223), 'en': (193, 193, 193), 'jp': (215, 215, 215), 'tw': (168, 168, 168)}, button={'cn': (910, 473, 1055, 500), 'en': (915, 475, 1051, 499), 'jp': (917, 474, 1035, 499), 'tw': (945, 478, 1013, 495)}, file={'cn': './assets/cn/coalition/DAL_SWITCH_SINGLE.png', 'en': './assets/en/coalition/DAL_SWITCH_SINGLE.png', 'jp': './assets/jp/coalition/DAL_SWITCH_SINGLE.png', 'tw': './assets/tw/coalition/DAL_SWITCH_SINGLE.png'})
EMPTY_FLAGSHIP = Button(area={'cn': (247, 237, 277, 267), 'en': (247, 237, 277, 267), 'jp': (247, 237, 277, 267), 'tw': (247, 237, 277, 267)}, color={'cn': (76, 64, 56), 'en': (76, 64, 56), 'jp': (76, 64, 56), 'tw': (76, 64, 56)}, button={'cn': (247, 237, 277, 267), 'en': (247, 237, 277, 267), 'jp': (247, 237, 277, 267), 'tw': (247, 237, 277, 267)}, file={'cn': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'en': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'jp': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'tw': './assets/cn/coalition/EMPTY_FLAGSHIP.png'}) EMPTY_FLAGSHIP = Button(area={'cn': (247, 237, 277, 267), 'en': (247, 237, 277, 267), 'jp': (247, 237, 277, 267), 'tw': (247, 237, 277, 267)}, color={'cn': (76, 64, 56), 'en': (76, 64, 56), 'jp': (76, 64, 56), 'tw': (76, 64, 56)}, button={'cn': (247, 237, 277, 267), 'en': (247, 237, 277, 267), 'jp': (247, 237, 277, 267), 'tw': (247, 237, 277, 267)}, file={'cn': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'en': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'jp': './assets/cn/coalition/EMPTY_FLAGSHIP.png', 'tw': './assets/cn/coalition/EMPTY_FLAGSHIP.png'})
EMPTY_VANGUARD = Button(area={'cn': (515, 237, 545, 267), 'en': (515, 237, 545, 267), 'jp': (515, 237, 545, 267), 'tw': (515, 237, 545, 267)}, color={'cn': (52, 52, 53), 'en': (52, 52, 53), 'jp': (52, 52, 53), 'tw': (52, 52, 53)}, button={'cn': (515, 237, 545, 267), 'en': (515, 237, 545, 267), 'jp': (515, 237, 545, 267), 'tw': (515, 237, 545, 267)}, file={'cn': './assets/cn/coalition/EMPTY_VANGUARD.png', 'en': './assets/cn/coalition/EMPTY_VANGUARD.png', 'jp': './assets/cn/coalition/EMPTY_VANGUARD.png', 'tw': './assets/cn/coalition/EMPTY_VANGUARD.png'}) EMPTY_VANGUARD = Button(area={'cn': (515, 237, 545, 267), 'en': (515, 237, 545, 267), 'jp': (515, 237, 545, 267), 'tw': (515, 237, 545, 267)}, color={'cn': (52, 52, 53), 'en': (52, 52, 53), 'jp': (52, 52, 53), 'tw': (52, 52, 53)}, button={'cn': (515, 237, 545, 267), 'en': (515, 237, 545, 267), 'jp': (515, 237, 545, 267), 'tw': (515, 237, 545, 267)}, file={'cn': './assets/cn/coalition/EMPTY_VANGUARD.png', 'en': './assets/cn/coalition/EMPTY_VANGUARD.png', 'jp': './assets/cn/coalition/EMPTY_VANGUARD.png', 'tw': './assets/cn/coalition/EMPTY_VANGUARD.png'})
FASHION_COALITION_CHECK = Button(area={'cn': (102, 19, 177, 51), 'en': (102, 19, 177, 51), 'jp': (102, 19, 177, 51), 'tw': (102, 19, 177, 51)}, color={'cn': (109, 104, 89), 'en': (109, 104, 89), 'jp': (109, 104, 89), 'tw': (109, 104, 89)}, button={'cn': (102, 19, 177, 51), 'en': (102, 19, 177, 51), 'jp': (102, 19, 177, 51), 'tw': (102, 19, 177, 51)}, file={'cn': './assets/cn/coalition/FASHION_COALITION_CHECK.png', 'en': './assets/cn/coalition/FASHION_COALITION_CHECK.png', 'jp': './assets/cn/coalition/FASHION_COALITION_CHECK.png', 'tw': './assets/cn/coalition/FASHION_COALITION_CHECK.png'})
FASHION_EASY = Button(area={'cn': (136, 223, 199, 263), 'en': (136, 223, 199, 263), 'jp': (136, 223, 199, 263), 'tw': (136, 223, 199, 263)}, color={'cn': (225, 199, 197), 'en': (225, 199, 197), 'jp': (225, 199, 197), 'tw': (225, 199, 197)}, button={'cn': (136, 223, 199, 263), 'en': (136, 223, 199, 263), 'jp': (136, 223, 199, 263), 'tw': (136, 223, 199, 263)}, file={'cn': './assets/cn/coalition/FASHION_EASY.png', 'en': './assets/cn/coalition/FASHION_EASY.png', 'jp': './assets/cn/coalition/FASHION_EASY.png', 'tw': './assets/cn/coalition/FASHION_EASY.png'})
FASHION_EX = Button(area={'cn': (844, 246, 923, 301), 'en': (844, 246, 923, 301), 'jp': (844, 246, 923, 301), 'tw': (844, 246, 923, 301)}, color={'cn': (140, 115, 114), 'en': (140, 115, 114), 'jp': (140, 115, 114), 'tw': (140, 115, 114)}, button={'cn': (844, 246, 923, 301), 'en': (844, 246, 923, 301), 'jp': (844, 246, 923, 301), 'tw': (844, 246, 923, 301)}, file={'cn': './assets/cn/coalition/FASHION_EX.png', 'en': './assets/cn/coalition/FASHION_EX.png', 'jp': './assets/cn/coalition/FASHION_EX.png', 'tw': './assets/cn/coalition/FASHION_EX.png'})
FASHION_HARD = Button(area={'cn': (485, 167, 554, 215), 'en': (485, 167, 554, 215), 'jp': (485, 167, 554, 215), 'tw': (485, 167, 554, 215)}, color={'cn': (152, 136, 129), 'en': (152, 136, 129), 'jp': (152, 136, 129), 'tw': (152, 136, 129)}, button={'cn': (485, 167, 554, 215), 'en': (485, 167, 554, 215), 'jp': (485, 167, 554, 215), 'tw': (485, 167, 554, 215)}, file={'cn': './assets/cn/coalition/FASHION_HARD.png', 'en': './assets/cn/coalition/FASHION_HARD.png', 'jp': './assets/cn/coalition/FASHION_HARD.png', 'tw': './assets/cn/coalition/FASHION_HARD.png'})
FASHION_MODE_BATTLE = Button(area={'cn': (152, 635, 213, 669), 'en': (152, 635, 213, 669), 'jp': (152, 635, 213, 669), 'tw': (152, 635, 213, 669)}, color={'cn': (140, 133, 117), 'en': (140, 133, 117), 'jp': (140, 133, 117), 'tw': (140, 133, 117)}, button={'cn': (152, 635, 213, 669), 'en': (152, 635, 213, 669), 'jp': (152, 635, 213, 669), 'tw': (152, 635, 213, 669)}, file={'cn': './assets/cn/coalition/FASHION_MODE_BATTLE.png', 'en': './assets/cn/coalition/FASHION_MODE_BATTLE.png', 'jp': './assets/cn/coalition/FASHION_MODE_BATTLE.png', 'tw': './assets/cn/coalition/FASHION_MODE_BATTLE.png'})
FASHION_MODE_STORY = Button(area={'cn': (154, 629, 220, 666), 'en': (154, 629, 220, 666), 'jp': (154, 629, 220, 666), 'tw': (154, 629, 220, 666)}, color={'cn': (141, 134, 116), 'en': (141, 134, 116), 'jp': (141, 134, 116), 'tw': (141, 134, 116)}, button={'cn': (154, 629, 220, 666), 'en': (154, 629, 220, 666), 'jp': (154, 629, 220, 666), 'tw': (154, 629, 220, 666)}, file={'cn': './assets/cn/coalition/FASHION_MODE_STORY.png', 'en': './assets/cn/coalition/FASHION_MODE_STORY.png', 'jp': './assets/cn/coalition/FASHION_MODE_STORY.png', 'tw': './assets/cn/coalition/FASHION_MODE_STORY.png'})
FASHION_NORMAL = Button(area={'cn': (322, 295, 392, 334), 'en': (322, 295, 392, 334), 'jp': (322, 295, 392, 334), 'tw': (322, 295, 392, 334)}, color={'cn': (219, 196, 198), 'en': (219, 196, 198), 'jp': (219, 196, 198), 'tw': (219, 196, 198)}, button={'cn': (322, 295, 392, 334), 'en': (322, 295, 392, 334), 'jp': (322, 295, 392, 334), 'tw': (322, 295, 392, 334)}, file={'cn': './assets/cn/coalition/FASHION_NORMAL.png', 'en': './assets/cn/coalition/FASHION_NORMAL.png', 'jp': './assets/cn/coalition/FASHION_NORMAL.png', 'tw': './assets/cn/coalition/FASHION_NORMAL.png'})
FASHION_PT_OCR = Button(area={'cn': (881, 658, 937, 674), 'en': (881, 658, 937, 674), 'jp': (881, 658, 937, 674), 'tw': (881, 658, 937, 674)}, color={'cn': (136, 127, 122), 'en': (136, 127, 122), 'jp': (136, 127, 122), 'tw': (136, 127, 122)}, button={'cn': (881, 658, 937, 674), 'en': (881, 658, 937, 674), 'jp': (881, 658, 937, 674), 'tw': (881, 658, 937, 674)}, file={'cn': './assets/cn/coalition/FASHION_PT_OCR.png', 'en': './assets/cn/coalition/FASHION_PT_OCR.png', 'jp': './assets/cn/coalition/FASHION_PT_OCR.png', 'tw': './assets/cn/coalition/FASHION_PT_OCR.png'})
FASHION_SP = Button(area={'cn': (704, 194, 762, 242), 'en': (704, 194, 762, 242), 'jp': (704, 194, 762, 242), 'tw': (704, 194, 762, 242)}, color={'cn': (146, 133, 135), 'en': (146, 133, 135), 'jp': (146, 133, 135), 'tw': (146, 133, 135)}, button={'cn': (704, 194, 762, 242), 'en': (704, 194, 762, 242), 'jp': (704, 194, 762, 242), 'tw': (704, 194, 762, 242)}, file={'cn': './assets/cn/coalition/FASHION_SP.png', 'en': './assets/cn/coalition/FASHION_SP.png', 'jp': './assets/cn/coalition/FASHION_SP.png', 'tw': './assets/cn/coalition/FASHION_SP.png'})
FASHION_SWITCH_MULTI = Button(area={'cn': (1075, 457, 1206, 485), 'en': (1075, 457, 1206, 485), 'jp': (1075, 457, 1206, 485), 'tw': (1075, 457, 1206, 485)}, color={'cn': (233, 183, 63), 'en': (233, 183, 63), 'jp': (233, 183, 63), 'tw': (233, 183, 63)}, button={'cn': (1075, 457, 1206, 485), 'en': (1075, 457, 1206, 485), 'jp': (1075, 457, 1206, 485), 'tw': (1075, 457, 1206, 485)}, file={'cn': './assets/cn/coalition/FASHION_SWITCH_MULTI.png', 'en': './assets/cn/coalition/FASHION_SWITCH_MULTI.png', 'jp': './assets/cn/coalition/FASHION_SWITCH_MULTI.png', 'tw': './assets/cn/coalition/FASHION_SWITCH_MULTI.png'})
FASHION_SWITCH_SINGLE = Button(area={'cn': (929, 457, 1059, 485), 'en': (929, 457, 1059, 485), 'jp': (929, 457, 1059, 485), 'tw': (929, 457, 1059, 485)}, color={'cn': (230, 181, 62), 'en': (230, 181, 62), 'jp': (230, 181, 62), 'tw': (230, 181, 62)}, button={'cn': (929, 457, 1059, 485), 'en': (929, 457, 1059, 485), 'jp': (929, 457, 1059, 485), 'tw': (929, 457, 1059, 485)}, file={'cn': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png', 'en': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png', 'jp': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png', 'tw': './assets/cn/coalition/FASHION_SWITCH_SINGLE.png'})
FLEET_NOT_PREPARED = Button(area={'cn': (1008, 310, 1110, 334), 'en': (1008, 310, 1110, 334), 'jp': (1008, 310, 1110, 334), 'tw': (1008, 310, 1110, 334)}, color={'cn': (106, 106, 112), 'en': (106, 106, 112), 'jp': (106, 106, 112), 'tw': (108, 107, 112)}, button={'cn': (1008, 310, 1110, 334), 'en': (1008, 310, 1110, 334), 'jp': (1008, 310, 1110, 334), 'tw': (1008, 310, 1110, 334)}, file={'cn': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'en': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'jp': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'tw': './assets/tw/coalition/FLEET_NOT_PREPARED.png'}) FLEET_NOT_PREPARED = Button(area={'cn': (1008, 310, 1110, 334), 'en': (1008, 310, 1110, 334), 'jp': (1008, 310, 1110, 334), 'tw': (1008, 310, 1110, 334)}, color={'cn': (106, 106, 112), 'en': (106, 106, 112), 'jp': (106, 106, 112), 'tw': (108, 107, 112)}, button={'cn': (1008, 310, 1110, 334), 'en': (1008, 310, 1110, 334), 'jp': (1008, 310, 1110, 334), 'tw': (1008, 310, 1110, 334)}, file={'cn': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'en': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'jp': './assets/cn/coalition/FLEET_NOT_PREPARED.png', 'tw': './assets/tw/coalition/FLEET_NOT_PREPARED.png'})
FROSTFALL_COALITION_CHECK = Button(area={'cn': (118, 14, 227, 39), 'en': (118, 16, 221, 36), 'jp': (118, 14, 227, 39), 'tw': (118, 14, 227, 39)}, color={'cn': (145, 161, 200), 'en': (116, 130, 168), 'jp': (150, 166, 204), 'tw': (152, 168, 206)}, button={'cn': (118, 14, 227, 39), 'en': (118, 16, 221, 36), 'jp': (118, 14, 227, 39), 'tw': (118, 14, 227, 39)}, file={'cn': './assets/cn/coalition/FROSTFALL_COALITION_CHECK.png', 'en': './assets/en/coalition/FROSTFALL_COALITION_CHECK.png', 'jp': './assets/jp/coalition/FROSTFALL_COALITION_CHECK.png', 'tw': './assets/tw/coalition/FROSTFALL_COALITION_CHECK.png'}) FROSTFALL_COALITION_CHECK = Button(area={'cn': (118, 14, 227, 39), 'en': (118, 16, 221, 36), 'jp': (118, 14, 227, 39), 'tw': (118, 14, 227, 39)}, color={'cn': (145, 161, 200), 'en': (116, 130, 168), 'jp': (150, 166, 204), 'tw': (152, 168, 206)}, button={'cn': (118, 14, 227, 39), 'en': (118, 16, 221, 36), 'jp': (118, 14, 227, 39), 'tw': (118, 14, 227, 39)}, file={'cn': './assets/cn/coalition/FROSTFALL_COALITION_CHECK.png', 'en': './assets/en/coalition/FROSTFALL_COALITION_CHECK.png', 'jp': './assets/jp/coalition/FROSTFALL_COALITION_CHECK.png', 'tw': './assets/tw/coalition/FROSTFALL_COALITION_CHECK.png'})
FROSTFALL_EX = Button(area={'cn': (622, 372, 649, 384), 'en': (622, 372, 649, 384), 'jp': (622, 372, 649, 384), 'tw': (622, 372, 649, 384)}, color={'cn': (198, 152, 252), 'en': (198, 152, 252), 'jp': (198, 152, 252), 'tw': (182, 127, 252)}, button={'cn': (622, 372, 649, 384), 'en': (622, 372, 649, 384), 'jp': (622, 372, 649, 384), 'tw': (622, 372, 649, 384)}, file={'cn': './assets/cn/coalition/FROSTFALL_EX.png', 'en': './assets/en/coalition/FROSTFALL_EX.png', 'jp': './assets/jp/coalition/FROSTFALL_EX.png', 'tw': './assets/tw/coalition/FROSTFALL_EX.png'}) FROSTFALL_EX = Button(area={'cn': (622, 372, 649, 384), 'en': (622, 372, 649, 384), 'jp': (622, 372, 649, 384), 'tw': (622, 372, 649, 384)}, color={'cn': (198, 152, 252), 'en': (198, 152, 252), 'jp': (198, 152, 252), 'tw': (182, 127, 252)}, button={'cn': (622, 372, 649, 384), 'en': (622, 372, 649, 384), 'jp': (622, 372, 649, 384), 'tw': (622, 372, 649, 384)}, file={'cn': './assets/cn/coalition/FROSTFALL_EX.png', 'en': './assets/en/coalition/FROSTFALL_EX.png', 'jp': './assets/jp/coalition/FROSTFALL_EX.png', 'tw': './assets/tw/coalition/FROSTFALL_EX.png'})

View File

@@ -6,6 +6,7 @@ from module.coalition.combat import CoalitionCombat
from module.exception import ScriptEnd, ScriptError from module.exception import ScriptEnd, ScriptError
from module.logger import logger from module.logger import logger
from module.ocr.ocr import Digit from module.ocr.ocr import Digit
from module.ui.page import page_campaign_menu
class AcademyPtOcr(Digit): class AcademyPtOcr(Digit):
@@ -22,6 +23,7 @@ class AcademyPtOcr(Digit):
pass pass
return super().after_process(result) return super().after_process(result)
class DALPtOcr(Digit): class DALPtOcr(Digit):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@@ -55,7 +57,9 @@ class Coalition(CoalitionCombat, CampaignEvent):
# use generic ocr model # use generic ocr model
ocr = Digit(NEONCITY_PT_OCR, name='OCR_PT', lang='cnocr', letter=(208, 208, 208), threshold=128) ocr = Digit(NEONCITY_PT_OCR, name='OCR_PT', lang='cnocr', letter=(208, 208, 208), threshold=128)
elif event == 'coalition_20251120': elif event == 'coalition_20251120':
ocr = DALPtOcr(DAL_PT_OCR, name='OCR_PT' ,letter=(255, 213, 69), threshold=128) ocr = DALPtOcr(DAL_PT_OCR, name='OCR_PT', letter=(255, 213, 69), threshold=128)
elif event == 'coalition_20260122':
ocr = Digit(FASHION_PT_OCR, name='OCR_PT', letter=(41, 40, 40), threshold=128)
else: else:
logger.error(f'ocr object is not defined in event {event}') logger.error(f'ocr object is not defined in event {event}')
raise ScriptError raise ScriptError
@@ -71,6 +75,16 @@ class Coalition(CoalitionCombat, CampaignEvent):
return pt return pt
@property
def _coalition_has_oil_icon(self):
"""
Game devs are too asshole to drop oil display for UI design
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/5214
"""
if self.config.Campaign_Event == 'coalition_20260122':
return False
return True
def triggered_stop_condition(self, oil_check=False, pt_check=False): def triggered_stop_condition(self, oil_check=False, pt_check=False):
""" """
Returns: Returns:
@@ -83,7 +97,7 @@ class Coalition(CoalitionCombat, CampaignEvent):
self.config.Scheduler_Enable = False self.config.Scheduler_Enable = False
return True return True
# Oil limit # Oil limit
if oil_check: if oil_check and self._coalition_has_oil_icon:
if self.get_oil() < max(500, self.config.StopCondition_OilLimit): if self.get_oil() < max(500, self.config.StopCondition_OilLimit):
logger.hr('Triggered stop condition: Oil limit') logger.hr('Triggered stop condition: Oil limit')
self.config.task_delay(minute=(120, 240)) self.config.task_delay(minute=(120, 240))
@@ -173,10 +187,10 @@ class Coalition(CoalitionCombat, CampaignEvent):
logger.info(f'Count: {self.run_count}') logger.info(f'Count: {self.run_count}')
# UI switches # UI switches
# if self.config.SERVER in ['tw']: if not self._coalition_has_oil_icon:
# self.ui_goto(page_campaign_menu) self.ui_goto(page_campaign_menu)
# if self.triggered_stop_condition(oil_check=True): if self.triggered_stop_condition(oil_check=True):
# break break
self.device.stuck_record_clear() self.device.stuck_record_clear()
self.device.click_record_clear() self.device.click_record_clear()
self.ui_goto_coalition() self.ui_goto_coalition()
@@ -206,3 +220,9 @@ class Coalition(CoalitionCombat, CampaignEvent):
# Scheduler # Scheduler
if self.config.task_switched(): if self.config.task_switched():
self.config.task_stop() self.config.task_stop()
if __name__ == '__main__':
self = Coalition('alas5', task='Coalition')
self.device.screenshot()
self.get_event_pt()

View File

@@ -52,6 +52,10 @@ class CoalitionUI(Combat):
elif event == 'coalition_20251120': elif event == 'coalition_20251120':
logger.info('Coalition event coalition_20251120 has no mode switch') logger.info('Coalition event coalition_20251120 has no mode switch')
return return
elif event == 'coalition_20260122':
mode_switch = Switch('CoalitionMode', offset=(20, 20))
mode_switch.add_state('story', FASHION_MODE_STORY)
mode_switch.add_state('battle', FASHION_MODE_BATTLE)
else: else:
logger.error(f'MODE_SWITCH is not defined in event {event}') logger.error(f'MODE_SWITCH is not defined in event {event}')
raise ScriptError raise ScriptError
@@ -85,6 +89,9 @@ class CoalitionUI(Combat):
elif event == 'coalition_20251120': elif event == 'coalition_20251120':
fleet_switch.add_state('single', DAL_SWITCH_SINGLE) fleet_switch.add_state('single', DAL_SWITCH_SINGLE)
fleet_switch.add_state('multi', DAL_SWITCH_MULTI) fleet_switch.add_state('multi', DAL_SWITCH_MULTI)
elif event == 'coalition_20260122':
fleet_switch.add_state('single', FASHION_SWITCH_SINGLE)
fleet_switch.add_state('multi', FASHION_SWITCH_MULTI)
else: else:
logger.error(f'FLEET_SWITCH is not defined in event {event}') logger.error(f'FLEET_SWITCH is not defined in event {event}')
raise ScriptError raise ScriptError
@@ -107,24 +114,25 @@ class CoalitionUI(Combat):
Button: Entrance button Button: Entrance button
""" """
dic = { dic = {
# FROSTFALL
('coalition_20230323', 'tc1'): FROSTFALL_TC1, ('coalition_20230323', 'tc1'): FROSTFALL_TC1,
('coalition_20230323', 'tc2'): FROSTFALL_TC2, ('coalition_20230323', 'tc2'): FROSTFALL_TC2,
('coalition_20230323', 'tc3'): FROSTFALL_TC3, ('coalition_20230323', 'tc3'): FROSTFALL_TC3,
('coalition_20230323', 'sp'): FROSTFALL_SP, ('coalition_20230323', 'sp'): FROSTFALL_SP,
('coalition_20230323', 'ex'): FROSTFALL_EX, ('coalition_20230323', 'ex'): FROSTFALL_EX,
# ACADEMY
('coalition_20240627', 'easy'): ACADEMY_EASY, ('coalition_20240627', 'easy'): ACADEMY_EASY,
('coalition_20240627', 'normal'): ACADEMY_NORMAL, ('coalition_20240627', 'normal'): ACADEMY_NORMAL,
('coalition_20240627', 'hard'): ACADEMY_HARD, ('coalition_20240627', 'hard'): ACADEMY_HARD,
('coalition_20240627', 'sp'): ACADEMY_SP, ('coalition_20240627', 'sp'): ACADEMY_SP,
('coalition_20240627', 'ex'): ACADEMY_EX, ('coalition_20240627', 'ex'): ACADEMY_EX,
# NEONCITY
('coalition_20250626', 'easy'): NEONCITY_EASY, ('coalition_20250626', 'easy'): NEONCITY_EASY,
('coalition_20250626', 'normal'): NEONCITY_NORMAL, ('coalition_20250626', 'normal'): NEONCITY_NORMAL,
('coalition_20250626', 'hard'): NEONCITY_HARD, ('coalition_20250626', 'hard'): NEONCITY_HARD,
('coalition_20250626', 'sp'): NEONCITY_SP, ('coalition_20250626', 'sp'): NEONCITY_SP,
('coalition_20250626', 'ex'): NEONCITY_EX, ('coalition_20250626', 'ex'): NEONCITY_EX,
# DAL
('coalition_20251120', 'area1-normal'): DAL_AREA1, ('coalition_20251120', 'area1-normal'): DAL_AREA1,
('coalition_20251120', 'area2-normal'): DAL_AREA2, ('coalition_20251120', 'area2-normal'): DAL_AREA2,
('coalition_20251120', 'area3-normal'): DAL_AREA3, ('coalition_20251120', 'area3-normal'): DAL_AREA3,
@@ -137,6 +145,12 @@ class CoalitionUI(Combat):
('coalition_20251120', 'area4-hard'): DAL_AREA4, ('coalition_20251120', 'area4-hard'): DAL_AREA4,
('coalition_20251120', 'area5-hard'): DAL_AREA5, ('coalition_20251120', 'area5-hard'): DAL_AREA5,
('coalition_20251120', 'area6-hard'): DAL_AREA6, ('coalition_20251120', 'area6-hard'): DAL_AREA6,
# FASHION
('coalition_20260122', 'easy'): FASHION_EASY,
('coalition_20260122', 'normal'): FASHION_NORMAL,
('coalition_20260122', 'hard'): FASHION_HARD,
('coalition_20260122', 'sp'): FASHION_SP,
('coalition_20260122', 'ex'): FASHION_EX,
} }
stage = stage.lower() stage = stage.lower()
try: try:
@@ -149,12 +163,14 @@ class CoalitionUI(Combat):
def coalition_20251120_get_entrance_difficulty(event, stage): def coalition_20251120_get_entrance_difficulty(event, stage):
""" """
Args: Args:
event (str): Event name.
stage (str): Stage name. stage (str): Stage name.
Returns: Returns:
Button: Entrance difficulty button Button: Entrance difficulty button
""" """
dic = { dic = {
# DAL
('coalition_20251120', 'area1-normal'): DAL_NORMAL, ('coalition_20251120', 'area1-normal'): DAL_NORMAL,
('coalition_20251120', 'area2-normal'): DAL_NORMAL, ('coalition_20251120', 'area2-normal'): DAL_NORMAL,
('coalition_20251120', 'area3-normal'): DAL_NORMAL, ('coalition_20251120', 'area3-normal'): DAL_NORMAL,
@@ -186,24 +202,25 @@ class CoalitionUI(Combat):
int: Number of battles int: Number of battles
""" """
dic = { dic = {
# FROSTFALL
('coalition_20230323', 'tc1'): 1, ('coalition_20230323', 'tc1'): 1,
('coalition_20230323', 'tc2'): 2, ('coalition_20230323', 'tc2'): 2,
('coalition_20230323', 'tc3'): 3, ('coalition_20230323', 'tc3'): 3,
('coalition_20230323', 'sp'): 1, ('coalition_20230323', 'sp'): 1,
('coalition_20230323', 'ex'): 1, ('coalition_20230323', 'ex'): 1,
# ACADEMY
('coalition_20240627', 'easy'): 1, ('coalition_20240627', 'easy'): 1,
('coalition_20240627', 'normal'): 2, ('coalition_20240627', 'normal'): 2,
('coalition_20240627', 'hard'): 3, ('coalition_20240627', 'hard'): 3,
('coalition_20240627', 'sp'): 4, ('coalition_20240627', 'sp'): 4,
('coalition_20240627', 'ex'): 5, ('coalition_20240627', 'ex'): 5,
# NEONCITY
('coalition_20250626', 'easy'): 1, ('coalition_20250626', 'easy'): 1,
('coalition_20250626', 'normal'): 2, ('coalition_20250626', 'normal'): 2,
('coalition_20250626', 'hard'): 3, ('coalition_20250626', 'hard'): 3,
('coalition_20250626', 'sp'): 4, ('coalition_20250626', 'sp'): 4,
('coalition_20250626', 'ex'): 5, ('coalition_20250626', 'ex'): 5,
# DAL
('coalition_20251120', 'area1-normal'): 2, ('coalition_20251120', 'area1-normal'): 2,
('coalition_20251120', 'area2-normal'): 3, ('coalition_20251120', 'area2-normal'): 3,
('coalition_20251120', 'area3-normal'): 3, ('coalition_20251120', 'area3-normal'): 3,
@@ -216,6 +233,12 @@ class CoalitionUI(Combat):
('coalition_20251120', 'area4-hard'): 3, ('coalition_20251120', 'area4-hard'): 3,
('coalition_20251120', 'area5-hard'): 3, ('coalition_20251120', 'area5-hard'): 3,
('coalition_20251120', 'area6-hard'): 4, ('coalition_20251120', 'area6-hard'): 4,
# FASHION
('coalition_20260122', 'easy'): 1,
('coalition_20260122', 'normal'): 2,
('coalition_20260122', 'hard'): 3,
('coalition_20260122', 'sp'): 4,
('coalition_20260122', 'ex'): 5,
} }
stage = stage.lower() stage = stage.lower()
try: try:
@@ -241,6 +264,9 @@ class CoalitionUI(Combat):
return NEONCITY_FLEET_PREPARATION return NEONCITY_FLEET_PREPARATION
elif event == 'coalition_20251120': elif event == 'coalition_20251120':
return DAL_FLEET_PREPARATION return DAL_FLEET_PREPARATION
elif event == 'coalition_20260122':
# FASHION reuses NEONCITY, just (-12, -12) shifted
return NEONCITY_FLEET_PREPARATION
else: else:
logger.error(f'FLEET_PREPARATION is not defined in event {event}') logger.error(f'FLEET_PREPARATION is not defined in event {event}')
raise ScriptError raise ScriptError
@@ -261,10 +287,12 @@ class CoalitionUI(Combat):
# No fleet switch in TC1 # No fleet switch in TC1
if stage in ['tc1', 'sp']: if stage in ['tc1', 'sp']:
return False return False
if event == 'coalition_20240627': if event in [
if stage in ['easy', 'sp', 'ex']: 'coalition_20240627',
return False 'coalition_20250626',
if event == 'coalition_20250626': 'coalition_20260122',
]:
# easy is single fleet, SP and EX must must multiple fleets
if stage in ['easy', 'sp', 'ex']: if stage in ['easy', 'sp', 'ex']:
return False return False
@@ -297,13 +325,12 @@ class CoalitionUI(Combat):
logger.info(f'{DAL_DIFFICULTY_EXIT} -> {DAL_DIFFICULTY_EXIT}') logger.info(f'{DAL_DIFFICULTY_EXIT} -> {DAL_DIFFICULTY_EXIT}')
continue continue
def enter_map(self, event, stage, mode, skip_first_screenshot=True): def enter_map(self, event, stage, mode):
""" """
Args: Args:
event (str): Event name such as 'coalition_20230323' event (str): Event name such as 'coalition_20230323'
stage (str): Stage name such as 'TC3' stage (str): Stage name such as 'TC3'
mode (str): 'single' or 'multi' mode (str): 'single' or 'multi'
skip_first_screenshot:
Pages: Pages:
in: in_coalition in: in_coalition
@@ -321,12 +348,8 @@ class CoalitionUI(Combat):
campaign_click = 0 campaign_click = 0
campaign_difficulty_click = 0 campaign_difficulty_click = 0
fleet_click = 0 fleet_click = 0
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
for _ in self.loop():
# Check errors # Check errors
if campaign_click > 5: if campaign_click > 5:
logger.critical(f"Failed to enter {button}, too many click on {button}") logger.critical(f"Failed to enter {button}, too many click on {button}")

View File

@@ -41,6 +41,7 @@ MOVE_DOWN = Button(area={'cn': (148, 647, 155, 669), 'en': (148, 647, 155, 669),
MOVE_LEFT_DOWN = Button(area={'cn': (67, 668, 112, 707), 'en': (67, 668, 112, 707), 'jp': (67, 668, 112, 707), 'tw': (67, 668, 112, 707)}, color={'cn': (65, 80, 100), 'en': (65, 80, 100), 'jp': (65, 80, 100), 'tw': (65, 80, 100)}, button={'cn': (67, 668, 112, 707), 'en': (67, 668, 112, 707), 'jp': (67, 668, 112, 707), 'tw': (67, 668, 112, 707)}, file={'cn': './assets/cn/combat/MOVE_LEFT_DOWN.png', 'en': './assets/en/combat/MOVE_LEFT_DOWN.png', 'jp': './assets/jp/combat/MOVE_LEFT_DOWN.png', 'tw': './assets/tw/combat/MOVE_LEFT_DOWN.png'}) MOVE_LEFT_DOWN = Button(area={'cn': (67, 668, 112, 707), 'en': (67, 668, 112, 707), 'jp': (67, 668, 112, 707), 'tw': (67, 668, 112, 707)}, color={'cn': (65, 80, 100), 'en': (65, 80, 100), 'jp': (65, 80, 100), 'tw': (65, 80, 100)}, button={'cn': (67, 668, 112, 707), 'en': (67, 668, 112, 707), 'jp': (67, 668, 112, 707), 'tw': (67, 668, 112, 707)}, file={'cn': './assets/cn/combat/MOVE_LEFT_DOWN.png', 'en': './assets/en/combat/MOVE_LEFT_DOWN.png', 'jp': './assets/jp/combat/MOVE_LEFT_DOWN.png', 'tw': './assets/tw/combat/MOVE_LEFT_DOWN.png'})
NEW_SHIP = Button(area={'cn': (206, 87, 213, 93), 'en': (206, 87, 213, 93), 'jp': (206, 87, 213, 93), 'tw': (206, 87, 213, 93)}, color={'cn': (235, 171, 60), 'en': (235, 171, 60), 'jp': (235, 171, 60), 'tw': (235, 171, 60)}, button={'cn': (206, 87, 213, 93), 'en': (206, 87, 213, 93), 'jp': (206, 87, 213, 93), 'tw': (206, 87, 213, 93)}, file={'cn': './assets/cn/combat/NEW_SHIP.png', 'en': './assets/en/combat/NEW_SHIP.png', 'jp': './assets/jp/combat/NEW_SHIP.png', 'tw': './assets/tw/combat/NEW_SHIP.png'}) NEW_SHIP = Button(area={'cn': (206, 87, 213, 93), 'en': (206, 87, 213, 93), 'jp': (206, 87, 213, 93), 'tw': (206, 87, 213, 93)}, color={'cn': (235, 171, 60), 'en': (235, 171, 60), 'jp': (235, 171, 60), 'tw': (235, 171, 60)}, button={'cn': (206, 87, 213, 93), 'en': (206, 87, 213, 93), 'jp': (206, 87, 213, 93), 'tw': (206, 87, 213, 93)}, file={'cn': './assets/cn/combat/NEW_SHIP.png', 'en': './assets/en/combat/NEW_SHIP.png', 'jp': './assets/jp/combat/NEW_SHIP.png', 'tw': './assets/tw/combat/NEW_SHIP.png'})
OPTS_INFO_D = Button(area={'cn': (602, 151, 703, 179), 'en': (565, 143, 692, 179), 'jp': (512, 154, 605, 176), 'tw': (602, 152, 702, 177)}, color={'cn': (157, 115, 123), 'en': (171, 116, 110), 'jp': (201, 187, 191), 'tw': (164, 130, 137)}, button={'cn': (583, 605, 677, 628), 'en': (590, 587, 627, 647), 'jp': (574, 596, 685, 635), 'tw': (583, 604, 676, 627)}, file={'cn': './assets/cn/combat/OPTS_INFO_D.png', 'en': './assets/en/combat/OPTS_INFO_D.png', 'jp': './assets/jp/combat/OPTS_INFO_D.png', 'tw': './assets/tw/combat/OPTS_INFO_D.png'}) OPTS_INFO_D = Button(area={'cn': (602, 151, 703, 179), 'en': (565, 143, 692, 179), 'jp': (512, 154, 605, 176), 'tw': (602, 152, 702, 177)}, color={'cn': (157, 115, 123), 'en': (171, 116, 110), 'jp': (201, 187, 191), 'tw': (164, 130, 137)}, button={'cn': (583, 605, 677, 628), 'en': (590, 587, 627, 647), 'jp': (574, 596, 685, 635), 'tw': (583, 604, 676, 627)}, file={'cn': './assets/cn/combat/OPTS_INFO_D.png', 'en': './assets/en/combat/OPTS_INFO_D.png', 'jp': './assets/jp/combat/OPTS_INFO_D.png', 'tw': './assets/tw/combat/OPTS_INFO_D.png'})
QUIT_RECONFIRM = Button(area={'cn': (749, 501, 828, 540), 'en': (761, 495, 818, 523), 'jp': (746, 490, 830, 530), 'tw': (754, 491, 825, 522)}, color={'cn': (207, 140, 133), 'en': (208, 147, 141), 'jp': (203, 138, 132), 'tw': (211, 158, 152)}, button={'cn': (749, 501, 828, 540), 'en': (761, 495, 818, 523), 'jp': (746, 490, 830, 530), 'tw': (754, 491, 825, 522)}, file={'cn': './assets/cn/combat/QUIT_RECONFIRM.png', 'en': './assets/en/combat/QUIT_RECONFIRM.png', 'jp': './assets/jp/combat/QUIT_RECONFIRM.png', 'tw': './assets/tw/combat/QUIT_RECONFIRM.png'})
READY_AIR_RAID = Button(area={'cn': (887, 618, 907, 628), 'en': (887, 618, 907, 628), 'jp': (887, 618, 907, 628), 'tw': (887, 618, 907, 628)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (887, 618, 907, 628), 'en': (887, 618, 907, 628), 'jp': (887, 618, 907, 628), 'tw': (887, 618, 907, 628)}, file={'cn': './assets/cn/combat/READY_AIR_RAID.png', 'en': './assets/en/combat/READY_AIR_RAID.png', 'jp': './assets/jp/combat/READY_AIR_RAID.png', 'tw': './assets/tw/combat/READY_AIR_RAID.png'}) READY_AIR_RAID = Button(area={'cn': (887, 618, 907, 628), 'en': (887, 618, 907, 628), 'jp': (887, 618, 907, 628), 'tw': (887, 618, 907, 628)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (887, 618, 907, 628), 'en': (887, 618, 907, 628), 'jp': (887, 618, 907, 628), 'tw': (887, 618, 907, 628)}, file={'cn': './assets/cn/combat/READY_AIR_RAID.png', 'en': './assets/en/combat/READY_AIR_RAID.png', 'jp': './assets/jp/combat/READY_AIR_RAID.png', 'tw': './assets/tw/combat/READY_AIR_RAID.png'})
READY_TORPEDO = Button(area={'cn': (1038, 611, 1046, 619), 'en': (1038, 611, 1046, 619), 'jp': (1038, 611, 1046, 619), 'tw': (1038, 611, 1046, 619)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1038, 611, 1046, 619), 'en': (1038, 611, 1046, 619), 'jp': (1038, 611, 1046, 619), 'tw': (1038, 611, 1046, 619)}, file={'cn': './assets/cn/combat/READY_TORPEDO.png', 'en': './assets/en/combat/READY_TORPEDO.png', 'jp': './assets/jp/combat/READY_TORPEDO.png', 'tw': './assets/tw/combat/READY_TORPEDO.png'}) READY_TORPEDO = Button(area={'cn': (1038, 611, 1046, 619), 'en': (1038, 611, 1046, 619), 'jp': (1038, 611, 1046, 619), 'tw': (1038, 611, 1046, 619)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1038, 611, 1046, 619), 'en': (1038, 611, 1046, 619), 'jp': (1038, 611, 1046, 619), 'tw': (1038, 611, 1046, 619)}, file={'cn': './assets/cn/combat/READY_TORPEDO.png', 'en': './assets/en/combat/READY_TORPEDO.png', 'jp': './assets/jp/combat/READY_TORPEDO.png', 'tw': './assets/tw/combat/READY_TORPEDO.png'})
SUBMARINE_AVAILABLE_CHECK_1 = Button(area={'cn': (707, 660, 712, 665), 'en': (707, 660, 712, 665), 'jp': (707, 660, 712, 665), 'tw': (707, 660, 712, 665)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (707, 660, 712, 665), 'en': (707, 660, 712, 665), 'jp': (707, 660, 712, 665), 'tw': (707, 660, 712, 665)}, file={'cn': './assets/cn/combat/SUBMARINE_AVAILABLE_CHECK_1.png', 'en': './assets/en/combat/SUBMARINE_AVAILABLE_CHECK_1.png', 'jp': './assets/jp/combat/SUBMARINE_AVAILABLE_CHECK_1.png', 'tw': './assets/tw/combat/SUBMARINE_AVAILABLE_CHECK_1.png'}) SUBMARINE_AVAILABLE_CHECK_1 = Button(area={'cn': (707, 660, 712, 665), 'en': (707, 660, 712, 665), 'jp': (707, 660, 712, 665), 'tw': (707, 660, 712, 665)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (707, 660, 712, 665), 'en': (707, 660, 712, 665), 'jp': (707, 660, 712, 665), 'tw': (707, 660, 712, 665)}, file={'cn': './assets/cn/combat/SUBMARINE_AVAILABLE_CHECK_1.png', 'en': './assets/en/combat/SUBMARINE_AVAILABLE_CHECK_1.png', 'jp': './assets/jp/combat/SUBMARINE_AVAILABLE_CHECK_1.png', 'tw': './assets/tw/combat/SUBMARINE_AVAILABLE_CHECK_1.png'})

View File

@@ -177,6 +177,15 @@ class Combat(Level, HPBalancer, Retirement, SubmarineCall, CombatAuto, CombatMan
return True return True
return False return False
def handle_combat_quit_reconfirm(self, interval=2):
# QUIT_RECONFIRM interval should shorter than QUIT,
# so multiple retries can be made during the interval of QUIT
if self.appear_then_click(QUIT_RECONFIRM, offset=(20, 20), interval=interval):
# reset QUIT timer to avoid duplicate QUIT clicks canceling QUIT_RECONFIRM
self.interval_reset(QUIT)
return True
return False
def ensure_combat_oil_loaded(self): def ensure_combat_oil_loaded(self):
self.wait_until_stable(COMBAT_OIL_LOADING) self.wait_until_stable(COMBAT_OIL_LOADING)

View File

@@ -1634,8 +1634,8 @@
"type": "select", "type": "select",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"display": "hide", "display": "hide",
"option_cn": [ "option_cn": [
@@ -1648,11 +1648,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -1915,8 +1915,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -1928,11 +1928,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -2310,8 +2310,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -2323,11 +2323,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -3121,22 +3121,24 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"coalition_20251120" "coalition_20251120",
"coalition_20260122"
], ],
"option_cn": [ "option_cn": [
"coalition_20251120" "coalition_20260122"
], ],
"option_en": [ "option_en": [
"coalition_20251120" "coalition_20260122"
], ],
"option_jp": [ "option_jp": [
"coalition_20251120" "coalition_20260122"
], ],
"option_tw": [ "option_tw": [
"coalition_20251120" "coalition_20251120"
], ],
"option_bold": [ "option_bold": [
"coalition_20251120" "coalition_20251120",
"coalition_20260122"
] ]
}, },
"Mode": { "Mode": {
@@ -3177,20 +3179,12 @@
"Coalition": { "Coalition": {
"Mode": { "Mode": {
"type": "select", "type": "select",
"value": "area1-normal", "value": "hard",
"option": [ "option": [
"area1-normal", "easy",
"area1-hard", "normal",
"area2-normal", "hard",
"area2-hard", "sp"
"area3-normal",
"area3-hard",
"area4-normal",
"area4-hard",
"area5-normal",
"area5-hard",
"area6-normal",
"area6-hard"
] ]
}, },
"Fleet": { "Fleet": {
@@ -4036,8 +4030,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -4049,11 +4043,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -4448,8 +4442,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -4461,11 +4455,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -4860,8 +4854,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -4873,11 +4867,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -5272,8 +5266,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -5285,11 +5279,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -5674,8 +5668,8 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
], ],
"option_cn": [ "option_cn": [
"event_20231221_cn" "event_20231221_cn"
@@ -5687,11 +5681,11 @@
"event_20231221_cn" "event_20231221_cn"
], ],
"option_tw": [ "option_tw": [
"event_20251218_cn" "event_20220526_cn"
], ],
"option_bold": [ "option_bold": [
"event_20231221_cn", "event_20220526_cn",
"event_20251218_cn" "event_20231221_cn"
] ]
}, },
"Mode": { "Mode": {
@@ -6310,22 +6304,24 @@
"type": "state", "type": "state",
"value": "campaign_main", "value": "campaign_main",
"option": [ "option": [
"coalition_20251120" "coalition_20251120",
"coalition_20260122"
], ],
"option_cn": [ "option_cn": [
"coalition_20251120" "coalition_20260122"
], ],
"option_en": [ "option_en": [
"coalition_20251120" "coalition_20260122"
], ],
"option_jp": [ "option_jp": [
"coalition_20251120" "coalition_20260122"
], ],
"option_tw": [ "option_tw": [
"coalition_20251120" "coalition_20251120"
], ],
"option_bold": [ "option_bold": [
"coalition_20251120" "coalition_20251120",
"coalition_20260122"
] ]
}, },
"Mode": { "Mode": {
@@ -6366,21 +6362,14 @@
"Coalition": { "Coalition": {
"Mode": { "Mode": {
"type": "select", "type": "select",
"value": "area1-normal", "value": "sp",
"option": [ "option": [
"area1-normal", "easy",
"area1-hard", "normal",
"area2-normal", "hard",
"area2-hard", "sp"
"area3-normal", ],
"area3-hard", "display": "hide"
"area4-normal",
"area4-hard",
"area5-normal",
"area5-hard",
"area6-normal",
"area6-hard"
]
}, },
"Fleet": { "Fleet": {
"type": "select", "type": "select",

View File

@@ -305,8 +305,8 @@ MaritimeEscort:
Enable: true Enable: true
Coalition: Coalition:
Mode: Mode:
value: area1-normal value: hard
option: [ area1-normal, area1-hard, area2-normal, area2-hard, area3-normal, area3-hard, area4-normal, area4-hard, area5-normal, area5-hard, area6-normal, area6-hard ] option: [ easy, normal, hard, sp ]
Fleet: Fleet:
value: single value: single
option: [ single, multi ] option: [ single, multi ]

View File

@@ -23,11 +23,11 @@
"page": "setting", "page": "setting",
"tasks": [ "tasks": [
"EventGeneral", "EventGeneral",
"Coalition",
"Event", "Event",
"Event2", "Event2",
"Raid", "Raid",
"Hospital", "Hospital",
"Coalition",
"MaritimeEscort", "MaritimeEscort",
"WarArchives" "WarArchives"
] ]
@@ -36,13 +36,13 @@
"menu": "collapse", "menu": "collapse",
"page": "setting", "page": "setting",
"tasks": [ "tasks": [
"CoalitionSp",
"EventA", "EventA",
"EventB", "EventB",
"EventC", "EventC",
"EventD", "EventD",
"EventSp", "EventSp",
"RaidDaily", "RaidDaily"
"CoalitionSp"
] ]
}, },
"Reward": { "Reward": {

View File

@@ -71,6 +71,12 @@ Event:
EventGeneral: EventGeneral:
- EventGeneral - EventGeneral
- TaskBalancer - TaskBalancer
Coalition:
- Scheduler
- Campaign
- Coalition
- StopCondition
- Emotion
Event: Event:
- Scheduler - Scheduler
- Campaign - Campaign
@@ -100,12 +106,6 @@ Event:
- Hospital - Hospital
- StopCondition - StopCondition
- Emotion - Emotion
Coalition:
- Scheduler
- Campaign
- Coalition
- StopCondition
- Emotion
MaritimeEscort: MaritimeEscort:
- Scheduler - Scheduler
- MaritimeEscort - MaritimeEscort
@@ -126,6 +126,12 @@ EventDaily:
menu: 'collapse' menu: 'collapse'
page: 'setting' page: 'setting'
tasks: tasks:
CoalitionSp:
- Scheduler
- Campaign
- Coalition
- StopCondition
- Emotion
EventA: EventA:
- Scheduler - Scheduler
- EventDaily - EventDaily
@@ -181,12 +187,6 @@ EventDaily:
- Campaign - Campaign
- StopCondition - StopCondition
- Emotion - Emotion
CoalitionSp:
- Scheduler
- Campaign
- Coalition
- StopCondition
- Emotion
# ==================== Reward ==================== # ==================== Reward ====================

View File

@@ -180,7 +180,7 @@ class GeneratedConfig:
MaritimeEscort_Enable = True MaritimeEscort_Enable = True
# Group `Coalition` # Group `Coalition`
Coalition_Mode = 'area1-normal' # area1-normal, area1-hard, area2-normal, area2-hard, area3-normal, area3-hard, area4-normal, area4-hard, area5-normal, area5-hard, area6-normal, area6-hard Coalition_Mode = 'hard' # easy, normal, hard, sp
Coalition_Fleet = 'single' # single, multi Coalition_Fleet = 'single' # single, multi
# Group `Commission` # Group `Commission`

View File

@@ -640,6 +640,8 @@ class ConfigUpdater:
deep_set(new, 'Alas.DropRecord.AzurStatsID', None) deep_set(new, 'Alas.DropRecord.AzurStatsID', None)
else: else:
deep_default(new, 'Alas.DropRecord.AzurStatsID', random_id()) deep_default(new, 'Alas.DropRecord.AzurStatsID', random_id())
if deep_get(new, keys='OpsiHazard1Leveling.Scheduler.Enable'):
deep_set(new, keys='OpsiMeowfficerFarming.Scheduler.Enable', value=True)
# Update to latest event # Update to latest event
server = to_server(deep_get(new, 'Alas.Emulator.PackageName', 'cn')) server = to_server(deep_get(new, 'Alas.Emulator.PackageName', 'cn'))
if not is_template: if not is_template:

View File

@@ -66,6 +66,10 @@
"name": "Event General", "name": "Event General",
"help": "" "help": ""
}, },
"Coalition": {
"name": "Light & Shadow Fashion Shoot",
"help": ""
},
"Event": { "Event": {
"name": "Event", "name": "Event",
"help": "" "help": ""
@@ -82,10 +86,6 @@
"name": "Valley Hospital", "name": "Valley Hospital",
"help": "" "help": ""
}, },
"Coalition": {
"name": "DATE A LANE",
"help": ""
},
"MaritimeEscort": { "MaritimeEscort": {
"name": "Maritime Escort", "name": "Maritime Escort",
"help": "" "help": ""
@@ -94,6 +94,10 @@
"name": "War Archives", "name": "War Archives",
"help": "Due to the lack of maintenance of war archives, continuous clear may not work normally, if Alas runs abnormally, Please manually finish clearing and use auto search" "help": "Due to the lack of maintenance of war archives, continuous clear may not work normally, if Alas runs abnormally, Please manually finish clearing and use auto search"
}, },
"CoalitionSp": {
"name": "Light & Shadow Fashion Shoot SP",
"help": ""
},
"EventA": { "EventA": {
"name": "Event Daily A", "name": "Event Daily A",
"help": "" "help": ""
@@ -118,10 +122,6 @@
"name": "Raid Daily", "name": "Raid Daily",
"help": "" "help": ""
}, },
"CoalitionSp": {
"name": "Neon City Investigator SP",
"help": ""
},
"Commission": { "Commission": {
"name": "Commission", "name": "Commission",
"help": "" "help": ""
@@ -684,6 +684,7 @@
"coalition_20240627": "Welcome to Little Academy", "coalition_20240627": "Welcome to Little Academy",
"coalition_20250626": "The Neon City Investigator", "coalition_20250626": "The Neon City Investigator",
"coalition_20251120": "DATE A LANE", "coalition_20251120": "DATE A LANE",
"coalition_20260122": "Light & Shadow Fashion Shoot!",
"event_20200227_cn": "Northern Overture", "event_20200227_cn": "Northern Overture",
"event_20200312_cn": "The Solomon Ranger Rerun", "event_20200312_cn": "The Solomon Ranger Rerun",
"event_20200326_cn": "Microlayer Medley", "event_20200326_cn": "Microlayer Medley",
@@ -1316,18 +1317,10 @@
"Mode": { "Mode": {
"name": "Mode", "name": "Mode",
"help": "SP needs to use event daily SP to run", "help": "SP needs to use event daily SP to run",
"area1-normal": "area1-normal", "easy": "easy",
"area1-hard": "area1-hard", "normal": "normal",
"area2-normal": "area2-normal", "hard": "hard",
"area2-hard": "area2-hard", "sp": "sp"
"area3-normal": "area3-normal",
"area3-hard": "area3-hard",
"area4-normal": "area4-normal",
"area4-hard": "area4-hard",
"area5-normal": "area5-normal",
"area5-hard": "area5-hard",
"area6-normal": "area6-normal",
"area6-hard": "area6-hard"
}, },
"Fleet": { "Fleet": {
"name": "Fleet", "name": "Fleet",

View File

@@ -66,6 +66,10 @@
"name": "イベント共通設定", "name": "イベント共通設定",
"help": "" "help": ""
}, },
"Coalition": {
"name": "特集写真-撮影進行中",
"help": ""
},
"Event": { "Event": {
"name": "イベント海域", "name": "イベント海域",
"help": "" "help": ""
@@ -82,10 +86,6 @@
"name": "病院探訪", "name": "病院探訪",
"help": "" "help": ""
}, },
"Coalition": {
"name": "ネオンシティの探索者",
"help": ""
},
"MaritimeEscort": { "MaritimeEscort": {
"name": "Maritime Escort", "name": "Maritime Escort",
"help": "" "help": ""
@@ -94,6 +94,10 @@
"name": "作戦履歴", "name": "作戦履歴",
"help": "" "help": ""
}, },
"CoalitionSp": {
"name": "特集写真-撮影進行中SP",
"help": ""
},
"EventA": { "EventA": {
"name": "毎日イベント海域A", "name": "毎日イベント海域A",
"help": "" "help": ""
@@ -118,10 +122,6 @@
"name": "Raid Daily", "name": "Raid Daily",
"help": "" "help": ""
}, },
"CoalitionSp": {
"name": "ネオンシティの探索者SP",
"help": ""
},
"Commission": { "Commission": {
"name": "委託", "name": "委託",
"help": "" "help": ""
@@ -684,6 +684,7 @@
"coalition_20240627": "リトル学園へようこそ", "coalition_20240627": "リトル学園へようこそ",
"coalition_20250626": "ネオンシティの探索者", "coalition_20250626": "ネオンシティの探索者",
"coalition_20251120": "DATE A LANE", "coalition_20251120": "DATE A LANE",
"coalition_20260122": "特集写真-撮影進行中",
"event_20200227_cn": "凍絶の北海", "event_20200227_cn": "凍絶の北海",
"event_20200312_cn": "南洋に靡く硝煙(復刻)", "event_20200312_cn": "南洋に靡く硝煙(復刻)",
"event_20200326_cn": "闇靄払う銀翼", "event_20200326_cn": "闇靄払う銀翼",
@@ -1316,18 +1317,10 @@
"Mode": { "Mode": {
"name": "Coalition.Mode.name", "name": "Coalition.Mode.name",
"help": "Coalition.Mode.help", "help": "Coalition.Mode.help",
"area1-normal": "area1-normal", "easy": "easy",
"area1-hard": "area1-hard", "normal": "normal",
"area2-normal": "area2-normal", "hard": "hard",
"area2-hard": "area2-hard", "sp": "sp"
"area3-normal": "area3-normal",
"area3-hard": "area3-hard",
"area4-normal": "area4-normal",
"area4-hard": "area4-hard",
"area5-normal": "area5-normal",
"area5-hard": "area5-hard",
"area6-normal": "area6-normal",
"area6-hard": "area6-hard"
}, },
"Fleet": { "Fleet": {
"name": "Coalition.Fleet.name", "name": "Coalition.Fleet.name",

View File

@@ -66,6 +66,10 @@
"name": "活动通用设置", "name": "活动通用设置",
"help": "" "help": ""
}, },
"Coalition": {
"name": "光影风尚-拍摄进行时",
"help": ""
},
"Event": { "Event": {
"name": "活动图", "name": "活动图",
"help": "" "help": ""
@@ -82,10 +86,6 @@
"name": "深谷来信", "name": "深谷来信",
"help": "" "help": ""
}, },
"Coalition": {
"name": "DATE A LANE",
"help": ""
},
"MaritimeEscort": { "MaritimeEscort": {
"name": "商船护航", "name": "商船护航",
"help": "" "help": ""
@@ -94,6 +94,10 @@
"name": "作战档案", "name": "作战档案",
"help": "由于作战档案缺少维护开荒功能不一定能正常使用如果发现Alas运行异常请手动完成开荒后使用自律寻敌功能" "help": "由于作战档案缺少维护开荒功能不一定能正常使用如果发现Alas运行异常请手动完成开荒后使用自律寻敌功能"
}, },
"CoalitionSp": {
"name": "光影风尚-拍摄进行时SP",
"help": ""
},
"EventA": { "EventA": {
"name": "活动每日A图", "name": "活动每日A图",
"help": "" "help": ""
@@ -118,10 +122,6 @@
"name": "共斗活动每日", "name": "共斗活动每日",
"help": "" "help": ""
}, },
"CoalitionSp": {
"name": "迷彩都市的寻踪者SP",
"help": ""
},
"Commission": { "Commission": {
"name": "委托", "name": "委托",
"help": "" "help": ""
@@ -684,6 +684,7 @@
"coalition_20240627": "欢迎来到童心学院", "coalition_20240627": "欢迎来到童心学院",
"coalition_20250626": "迷彩都市的寻踪者", "coalition_20250626": "迷彩都市的寻踪者",
"coalition_20251120": "DATE A LANE", "coalition_20251120": "DATE A LANE",
"coalition_20260122": "光影风尚-拍摄进行时",
"event_20200227_cn": "北境序曲", "event_20200227_cn": "北境序曲",
"event_20200312_cn": "复刻斯图尔特的硝烟", "event_20200312_cn": "复刻斯图尔特的硝烟",
"event_20200326_cn": "微层混合", "event_20200326_cn": "微层混合",
@@ -1316,18 +1317,10 @@
"Mode": { "Mode": {
"name": "难度", "name": "难度",
"help": "SP图需要使用活动每日SP运行", "help": "SP图需要使用活动每日SP运行",
"area1-normal": "area1-normal", "easy": "easy",
"area1-hard": "area1-hard", "normal": "normal",
"area2-normal": "area2-normal", "hard": "hard",
"area2-hard": "area2-hard", "sp": "sp"
"area3-normal": "area3-normal",
"area3-hard": "area3-hard",
"area4-normal": "area4-normal",
"area4-hard": "area4-hard",
"area5-normal": "area5-normal",
"area5-hard": "area5-hard",
"area6-normal": "area6-normal",
"area6-hard": "area6-hard"
}, },
"Fleet": { "Fleet": {
"name": "出击队伍", "name": "出击队伍",

View File

@@ -66,6 +66,10 @@
"name": "活動通用", "name": "活動通用",
"help": "" "help": ""
}, },
"Coalition": {
"name": "光影風尚-拍攝進行時",
"help": ""
},
"Event": { "Event": {
"name": "活動圖", "name": "活動圖",
"help": "" "help": ""
@@ -82,10 +86,6 @@
"name": "深谷来信", "name": "深谷来信",
"help": "" "help": ""
}, },
"Coalition": {
"name": "極地風暴",
"help": ""
},
"MaritimeEscort": { "MaritimeEscort": {
"name": "商船護航", "name": "商船護航",
"help": "" "help": ""
@@ -94,6 +94,10 @@
"name": "作戰檔案", "name": "作戰檔案",
"help": "由於作戰檔案缺少維護開荒功能不一定能正常使用如果發現Alas運行異常請手動完成開荒後使用自律尋敵功能" "help": "由於作戰檔案缺少維護開荒功能不一定能正常使用如果發現Alas運行異常請手動完成開荒後使用自律尋敵功能"
}, },
"CoalitionSp": {
"name": "光影風尚-拍攝進行時SP",
"help": ""
},
"EventA": { "EventA": {
"name": "活動每日A圖", "name": "活動每日A圖",
"help": "" "help": ""
@@ -118,10 +122,6 @@
"name": "共鬥活動每日", "name": "共鬥活動每日",
"help": "" "help": ""
}, },
"CoalitionSp": {
"name": "極地風暴每日SP",
"help": ""
},
"Commission": { "Commission": {
"name": "委託", "name": "委託",
"help": "" "help": ""
@@ -684,6 +684,7 @@
"coalition_20240627": "歡迎來到童心學院", "coalition_20240627": "歡迎來到童心學院",
"coalition_20250626": "迷彩都市的尋蹤者", "coalition_20250626": "迷彩都市的尋蹤者",
"coalition_20251120": "DATE A LANE", "coalition_20251120": "DATE A LANE",
"coalition_20260122": "Light & Shadow Fashion Shoot!",
"event_20200227_cn": "Northern Overture", "event_20200227_cn": "Northern Overture",
"event_20200312_cn": "斯圖爾特的硝煙", "event_20200312_cn": "斯圖爾特的硝煙",
"event_20200326_cn": "Microlayer Medley", "event_20200326_cn": "Microlayer Medley",
@@ -1316,18 +1317,10 @@
"Mode": { "Mode": {
"name": "難度", "name": "難度",
"help": "SP圖需要使用活動每日SP運行", "help": "SP圖需要使用活動每日SP運行",
"area1-normal": "area1-normal", "easy": "easy",
"area1-hard": "area1-hard", "normal": "normal",
"area2-normal": "area2-normal", "hard": "hard",
"area2-hard": "area2-hard", "sp": "sp"
"area3-normal": "area3-normal",
"area3-hard": "area3-hard",
"area4-normal": "area4-normal",
"area4-hard": "area4-hard",
"area5-normal": "area5-normal",
"area5-hard": "area5-hard",
"area6-normal": "area6-normal",
"area6-hard": "area6-hard"
}, },
"Fleet": { "Fleet": {
"name": "出擊隊伍", "name": "出擊隊伍",

View File

@@ -20,4 +20,3 @@ OPPONENT_1 = Button(area={'cn': (104, 77, 316, 381), 'en': (102, 76, 318, 381),
OPPONENT_2 = Button(area={'cn': (348, 77, 560, 381), 'en': (348, 77, 562, 381), 'jp': (348, 77, 560, 381), 'tw': (348, 77, 560, 381)}, color={'cn': (105, 123, 149), 'en': (105, 122, 150), 'jp': (105, 123, 149), 'tw': (105, 123, 149)}, button={'cn': (348, 77, 560, 381), 'en': (348, 77, 562, 381), 'jp': (348, 77, 560, 381), 'tw': (348, 77, 560, 381)}, file={'cn': './assets/cn/exercise/OPPONENT_2.png', 'en': './assets/en/exercise/OPPONENT_2.png', 'jp': './assets/jp/exercise/OPPONENT_2.png', 'tw': './assets/tw/exercise/OPPONENT_2.png'}) OPPONENT_2 = Button(area={'cn': (348, 77, 560, 381), 'en': (348, 77, 562, 381), 'jp': (348, 77, 560, 381), 'tw': (348, 77, 560, 381)}, color={'cn': (105, 123, 149), 'en': (105, 122, 150), 'jp': (105, 123, 149), 'tw': (105, 123, 149)}, button={'cn': (348, 77, 560, 381), 'en': (348, 77, 562, 381), 'jp': (348, 77, 560, 381), 'tw': (348, 77, 560, 381)}, file={'cn': './assets/cn/exercise/OPPONENT_2.png', 'en': './assets/en/exercise/OPPONENT_2.png', 'jp': './assets/jp/exercise/OPPONENT_2.png', 'tw': './assets/tw/exercise/OPPONENT_2.png'})
OPPONENT_3 = Button(area={'cn': (592, 77, 804, 381), 'en': (592, 77, 806, 381), 'jp': (592, 77, 804, 381), 'tw': (592, 77, 804, 381)}, color={'cn': (106, 131, 158), 'en': (105, 129, 156), 'jp': (106, 131, 158), 'tw': (106, 131, 158)}, button={'cn': (592, 77, 804, 381), 'en': (592, 77, 806, 381), 'jp': (592, 77, 804, 381), 'tw': (592, 77, 804, 381)}, file={'cn': './assets/cn/exercise/OPPONENT_3.png', 'en': './assets/en/exercise/OPPONENT_3.png', 'jp': './assets/jp/exercise/OPPONENT_3.png', 'tw': './assets/tw/exercise/OPPONENT_3.png'}) OPPONENT_3 = Button(area={'cn': (592, 77, 804, 381), 'en': (592, 77, 806, 381), 'jp': (592, 77, 804, 381), 'tw': (592, 77, 804, 381)}, color={'cn': (106, 131, 158), 'en': (105, 129, 156), 'jp': (106, 131, 158), 'tw': (106, 131, 158)}, button={'cn': (592, 77, 804, 381), 'en': (592, 77, 806, 381), 'jp': (592, 77, 804, 381), 'tw': (592, 77, 804, 381)}, file={'cn': './assets/cn/exercise/OPPONENT_3.png', 'en': './assets/en/exercise/OPPONENT_3.png', 'jp': './assets/jp/exercise/OPPONENT_3.png', 'tw': './assets/tw/exercise/OPPONENT_3.png'})
OPPONENT_4 = Button(area={'cn': (836, 77, 1048, 381), 'en': (836, 77, 1050, 381), 'jp': (836, 77, 1048, 381), 'tw': (836, 77, 1048, 381)}, color={'cn': (103, 118, 141), 'en': (112, 127, 152), 'jp': (103, 118, 141), 'tw': (103, 118, 141)}, button={'cn': (836, 77, 1048, 381), 'en': (836, 77, 1050, 381), 'jp': (836, 77, 1048, 381), 'tw': (836, 77, 1048, 381)}, file={'cn': './assets/cn/exercise/OPPONENT_4.png', 'en': './assets/en/exercise/OPPONENT_4.png', 'jp': './assets/jp/exercise/OPPONENT_4.png', 'tw': './assets/tw/exercise/OPPONENT_4.png'}) OPPONENT_4 = Button(area={'cn': (836, 77, 1048, 381), 'en': (836, 77, 1050, 381), 'jp': (836, 77, 1048, 381), 'tw': (836, 77, 1048, 381)}, color={'cn': (103, 118, 141), 'en': (112, 127, 152), 'jp': (103, 118, 141), 'tw': (103, 118, 141)}, button={'cn': (836, 77, 1048, 381), 'en': (836, 77, 1050, 381), 'jp': (836, 77, 1048, 381), 'tw': (836, 77, 1048, 381)}, file={'cn': './assets/cn/exercise/OPPONENT_4.png', 'en': './assets/en/exercise/OPPONENT_4.png', 'jp': './assets/jp/exercise/OPPONENT_4.png', 'tw': './assets/tw/exercise/OPPONENT_4.png'})
QUIT_RECONFIRM = Button(area={'cn': (703, 492, 877, 550), 'en': (731, 488, 846, 533), 'jp': (703, 482, 877, 539), 'tw': (754, 491, 825, 522)}, color={'cn': (195, 111, 102), 'en': (195, 112, 105), 'jp': (193, 112, 104), 'tw': (211, 158, 152)}, button={'cn': (703, 492, 877, 550), 'en': (731, 488, 846, 533), 'jp': (703, 482, 877, 539), 'tw': (703, 502, 876, 559)}, file={'cn': './assets/cn/exercise/QUIT_RECONFIRM.png', 'en': './assets/en/exercise/QUIT_RECONFIRM.png', 'jp': './assets/jp/exercise/QUIT_RECONFIRM.png', 'tw': './assets/tw/exercise/QUIT_RECONFIRM.png'})

View File

@@ -1,5 +1,4 @@
from module.combat.combat import * from module.combat.combat import *
from module.combat.combat import QUIT
from module.exercise.assets import * from module.exercise.assets import *
from module.exercise.equipment import ExerciseEquipment from module.exercise.equipment import ExerciseEquipment
from module.exercise.hp_daemon import HpDaemon from module.exercise.hp_daemon import HpDaemon
@@ -108,8 +107,7 @@ class ExerciseCombat(HpDaemon, OpponentChoose, ExerciseEquipment, Combat):
success = False success = False
end = True end = True
continue continue
if self.appear_then_click(QUIT_RECONFIRM, offset=(20, 20), interval=5): if self.handle_combat_quit_reconfirm():
self.interval_reset(QUIT)
pause_interval.reset() pause_interval.reset()
continue continue
if not end: if not end:

View File

@@ -9,7 +9,6 @@ from module.base.timer import Timer
from module.base.utils import point_limit from module.base.utils import point_limit
from module.config.utils import dict_to_kv from module.config.utils import dict_to_kv
from module.exception import MapWalkError from module.exception import MapWalkError
from module.exercise.assets import QUIT_RECONFIRM
from module.handler.assets import MAINTENANCE_ANNOUNCE from module.handler.assets import MAINTENANCE_ANNOUNCE
from module.logger import logger from module.logger import logger
from module.map.fleet import Fleet from module.map.fleet import Fleet
@@ -238,12 +237,7 @@ class OSFleet(OSCamera, Combat, Fleet, OSAsh):
logger.hr('Wait until camera stable') logger.hr('Wait until camera stable')
record = None record = None
confirm_timer = Timer(0.6, count=2).start() confirm_timer = Timer(0.6, count=2).start()
while 1: for _ in self.loop(skip_first=skip_first_screenshot):
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
self.update_os() self.update_os()
current = self.view.backend.homo_loca current = self.view.backend.homo_loca
logger.attr('homo_loca', current) logger.attr('homo_loca', current)
@@ -289,12 +283,7 @@ class OSFleet(OSCamera, Combat, Fleet, OSAsh):
clicked_story = False clicked_story = False
stuck_timer = Timer(20, count=5).start() stuck_timer = Timer(20, count=5).start()
confirm_timer.reset() confirm_timer.reset()
while 1: for _ in self.loop(skip_first=skip_first_screenshot):
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# Map event # Map event
event = self.handle_map_event(drop=drop) event = self.handle_map_event(drop=drop)
if event: if event:
@@ -702,7 +691,7 @@ class OSFleet(OSCamera, Combat, Fleet, OSAsh):
button = Button(area=area, color=(), button=area, name='BOSS_LEAVE') button = Button(area=area, color=(), button=area, name='BOSS_LEAVE')
return button return button
def boss_leave(self, skip_first_screenshot=True): def boss_leave(self):
""" """
Pages: Pages:
in: is_in_map(), or combat_appear() in: is_in_map(), or combat_appear()
@@ -714,12 +703,7 @@ class OSFleet(OSCamera, Combat, Fleet, OSAsh):
click_timer = Timer(3) click_timer = Timer(3)
pause_interval = Timer(0.5, count=1) pause_interval = Timer(0.5, count=1)
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_map(): if self.is_in_map():
self.predict_radar() self.predict_radar()
@@ -744,7 +728,7 @@ class OSFleet(OSCamera, Combat, Fleet, OSAsh):
self.interval_reset(MAINTENANCE_ANNOUNCE) self.interval_reset(MAINTENANCE_ANNOUNCE)
pause_interval.reset() pause_interval.reset()
continue continue
if self.appear_then_click(QUIT_RECONFIRM, offset=True, interval=5): if self.handle_combat_quit_reconfirm():
self.interval_reset(MAINTENANCE_ANNOUNCE) self.interval_reset(MAINTENANCE_ANNOUNCE)
pause_interval.reset() pause_interval.reset()
continue continue

View File

@@ -89,14 +89,9 @@ class GlobeOperation(ActionPointHandler):
return False return False
def ensure_no_zone_pinned(self, skip_first_screenshot=True): def ensure_no_zone_pinned(self):
confirm_timer = Timer(1, count=2).start() confirm_timer = Timer(1, count=2).start()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.handle_zone_pinned(): if self.handle_zone_pinned():
confirm_timer.reset() confirm_timer.reset()
else: else:
@@ -189,12 +184,14 @@ class GlobeOperation(ActionPointHandler):
in: is_in_zone_select in: is_in_zone_select
out: is_zone_pinned out: is_zone_pinned
""" """
logger.info(f'Zone select: {button}')
def appear(): for _ in self.loop():
return self.appear(button, offset=self._zone_select_offset, threshold=self._zone_select_similarity) # End
if self.is_zone_pinned():
self.ui_click(button, appear_button=appear, check_button=self.is_zone_pinned, break
skip_first_screenshot=True) if self.appear_then_click(
button, offset=self._zone_select_offset, threshold=self._zone_select_similarity, interval=5):
continue
def zone_type_select(self, types=('SAFE', 'DANGEROUS')): def zone_type_select(self, types=('SAFE', 'DANGEROUS')):
""" """
@@ -282,23 +279,17 @@ class GlobeOperation(ActionPointHandler):
return self.ui_click(GLOBE_GOTO_MAP, check_button=self.is_in_map, offset=(20, 20), return self.ui_click(GLOBE_GOTO_MAP, check_button=self.is_in_map, offset=(20, 20),
retry_wait=3, skip_first_screenshot=skip_first_screenshot) retry_wait=3, skip_first_screenshot=skip_first_screenshot)
def os_map_goto_globe(self, unpin=True, skip_first_screenshot=True): def os_map_goto_globe(self, unpin=True):
""" """
Args: Args:
unpin (bool): unpin (bool):
skip_first_screenshot (bool):
Pages: Pages:
in: is_in_map in: is_in_map
out: is_in_globe out: is_in_globe
""" """
click_count = 0 click_count = 0
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_globe(): if self.is_in_globe():
break break
@@ -335,15 +326,9 @@ class GlobeOperation(ActionPointHandler):
if self.handle_popup_confirm('GOTO_GLOBE'): if self.handle_popup_confirm('GOTO_GLOBE'):
continue continue
skip_first_screenshot = True
confirm_timer = Timer(1, count=2).start() confirm_timer = Timer(1, count=2).start()
unpinned = 0 unpinned = 0
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if unpin: if unpin:
if self.handle_zone_pinned(): if self.handle_zone_pinned():
unpinned += 1 unpinned += 1
@@ -355,11 +340,10 @@ class GlobeOperation(ActionPointHandler):
if self.is_zone_pinned(): if self.is_zone_pinned():
break break
def globe_enter(self, zone, skip_first_screenshot=True): def globe_enter(self, zone):
""" """
Args: Args:
zone (Zone): Zone to enter. zone (Zone): Zone to enter.
skip_first_screenshot (bool):
Raises: Raises:
OSExploreError: If zone locked. OSExploreError: If zone locked.
@@ -371,11 +355,7 @@ class GlobeOperation(ActionPointHandler):
click_timer = Timer(10) click_timer = Timer(10)
click_count = 0 click_count = 0
pinned = None pinned = None
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if pinned is None: if pinned is None:
pinned = self.get_zone_pinned_name() pinned = self.get_zone_pinned_name()

View File

@@ -5,7 +5,6 @@ import inflection
from module.base.timer import Timer from module.base.timer import Timer
from module.config.utils import get_os_reset_remain from module.config.utils import get_os_reset_remain
from module.exception import CampaignEnd, GameTooManyClickError, MapWalkError, RequestHumanTakeover, ScriptError from module.exception import CampaignEnd, GameTooManyClickError, MapWalkError, RequestHumanTakeover, ScriptError
from module.exercise.assets import QUIT_RECONFIRM
from module.handler.login import LoginHandler, MAINTENANCE_ANNOUNCE from module.handler.login import LoginHandler, MAINTENANCE_ANNOUNCE
from module.logger import logger from module.logger import logger
from module.map.map import Map from module.map.map import Map
@@ -458,12 +457,11 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
logger.attr('CL1 time cost', f'{cost}s/round') logger.attr('CL1 time cost', f'{cost}s/round')
self._auto_search_round_timer = time.time() self._auto_search_round_timer = time.time()
def os_auto_search_daemon(self, drop=None, strategic=False, skip_first_screenshot=True): def os_auto_search_daemon(self, drop=None, strategic=False):
""" """
Args: Args:
drop (DropRecord): drop (DropRecord):
strategic (bool): True if running in strategic search strategic (bool): True if running in strategic search
skip_first_screenshot:
Returns: Returns:
int: Number of finished battle int: Number of finished battle
@@ -487,12 +485,7 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
finished_combat = 0 finished_combat = 0
died_timer = Timer(1.5, count=3) died_timer = Timer(1.5, count=3)
self.hp_reset() self.hp_reset()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if not unlock_checked and unlock_check_timer.reached(): if not unlock_checked and unlock_check_timer.reached():
logger.critical('Unable to use auto search in current zone') logger.critical('Unable to use auto search in current zone')
@@ -547,7 +540,7 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
return finished_combat return finished_combat
def interrupt_auto_search(self, skip_first_screenshot=True): def interrupt_auto_search(self):
""" """
Raises: Raises:
TaskEnd: If auto search interrupted TaskEnd: If auto search interrupted
@@ -560,12 +553,7 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
is_loading = False is_loading = False
pause_interval = Timer(0.5, count=1) pause_interval = Timer(0.5, count=1)
in_main_timer = Timer(3, count=6) in_main_timer = Timer(3, count=6)
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_main(): if self.is_in_main():
logger.info('Auto search interrupted') logger.info('Auto search interrupted')
@@ -589,7 +577,7 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
pause_interval.reset() pause_interval.reset()
in_main_timer.reset() in_main_timer.reset()
continue continue
if self.appear_then_click(QUIT_RECONFIRM, offset=True, interval=5): if self.handle_combat_quit_reconfirm():
self.interval_reset(MAINTENANCE_ANNOUNCE) self.interval_reset(MAINTENANCE_ANNOUNCE)
pause_interval.reset() pause_interval.reset()
in_main_timer.reset() in_main_timer.reset()
@@ -634,7 +622,7 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
backup = self.config.temporary(Campaign_UseAutoSearch=True) backup = self.config.temporary(Campaign_UseAutoSearch=True)
try: try:
if strategic: if strategic:
self.strategic_search_start(skip_first_screenshot=True) self.strategic_search_start()
combat = self.os_auto_search_daemon(drop=drop, strategic=strategic) combat = self.os_auto_search_daemon(drop=drop, strategic=strategic)
finished_combat += combat finished_combat += combat
except CampaignEnd: except CampaignEnd:
@@ -927,6 +915,8 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler):
if self.zone.is_port: if self.zone.is_port:
logger.info('Current zone is a port, do not need rescan') logger.info('Current zone is a port, do not need rescan')
return False return False
if self.is_cl1_enabled and not self.config.is_task_enabled('OpsiMeowfficerFarming'):
return False
for _ in range(5): for _ in range(5):
if not self._solved_fleet_mechanism: if not self._solved_fleet_mechanism:

View File

@@ -91,18 +91,13 @@ class FleetSelector:
index = 5 - index index = 5 - index
return Button(area=(), color=(), button=area, name='%s_INDEX_%s' % (str(self._bar), str(index))) return Button(area=(), color=(), button=area, name='%s_INDEX_%s' % (str(self._bar), str(index)))
def open(self, skip_first_screenshot=True): def open(self):
""" """
Activate dropdown menu for fleet selection. Activate dropdown menu for fleet selection.
""" """
main = self.main main = self.main
click_timer = Timer(3, count=6) click_timer = Timer(3, count=6)
while 1: for _ in main.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
if main.handle_map_event(): if main.handle_map_event():
click_timer.reset() click_timer.reset()
continue continue
@@ -116,18 +111,13 @@ class FleetSelector:
main.device.click(self._choose) main.device.click(self._choose)
click_timer.reset() click_timer.reset()
def close(self, skip_first_screenshot=True): def close(self):
""" """
Deactivate dropdown menu for fleet selection. Deactivate dropdown menu for fleet selection.
""" """
main = self.main main = self.main
click_timer = Timer(3, count=6) click_timer = Timer(3, count=6)
while 1: for _ in main.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
# End # End
if not self.bar_opened(): if not self.bar_opened():
break break
@@ -137,23 +127,17 @@ class FleetSelector:
main.device.click(self._choose) main.device.click(self._choose)
click_timer.reset() click_timer.reset()
def click(self, index, skip_first_screenshot=True): def click(self, index):
""" """
Choose a fleet on dropdown menu, and dropdown deactivated. Choose a fleet on dropdown menu, and dropdown deactivated.
Args: Args:
index (int): Fleet index, 1-6. index (int): Fleet index, 1-6.
skip_first_screenshot (bool):
""" """
main = self.main main = self.main
button = self.get_button(index) button = self.get_button(index)
click_timer = Timer(3, count=6) click_timer = Timer(3, count=6)
while 1: for _ in main.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
if main.handle_map_event(): if main.handle_map_event():
click_timer.reset() click_timer.reset()
continue continue
@@ -171,25 +155,19 @@ class FleetSelector:
main.device.click(button) main.device.click(button)
click_timer.reset() click_timer.reset()
def ensure_to_be(self, index, skip_first_screenshot=True): def ensure_to_be(self, index):
""" """
Set to a specific fleet. Set to a specific fleet.
Args: Args:
index (int): Fleet index, 1-4. index (int): Fleet index, 1-4.
skip_first_screenshot (bool):
Returns: Returns:
bool: If fleet switched. bool: If fleet switched.
""" """
confirm_timer = Timer(1.5, count=5).start() confirm_timer = Timer(1.5, count=5).start()
main = self.main main = self.main
while 1: for _ in main.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
if confirm_timer.reached(): if confirm_timer.reached():
break break

View File

@@ -158,7 +158,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
self.config.HOMO_EDGE_COLOR_RANGE = (0, 33) self.config.HOMO_EDGE_COLOR_RANGE = (0, 33)
self.config.MAP_ENSURE_EDGE_INSIGHT_CORNER = '' self.config.MAP_ENSURE_EDGE_INSIGHT_CORNER = ''
def zone_init(self, fallback_init=True, skip_first_screenshot=True): def zone_init(self, fallback_init=True):
""" """
Wrap get_current_zone(), set self.zone to the current zone. Wrap get_current_zone(), set self.zone to the current zone.
This method must be called after entering a new zone. This method must be called after entering a new zone.
@@ -166,7 +166,6 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
Args: Args:
fallback_init (bool): Whether to get zone from globe map when unable to parse zone name. fallback_init (bool): Whether to get zone from globe map when unable to parse zone name.
skip_first_screenshot (bool):
Returns: Returns:
Zone: Current zone. Zone: Current zone.
@@ -178,12 +177,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
self.wait_os_map_buttons() self.wait_os_map_buttons()
logger.info('Get zone name') logger.info('Get zone name')
timeout = Timer(1.5, count=5).start() timeout = Timer(1.5, count=5).start()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# Handle popups # Handle popups
if self.handle_map_event(): if self.handle_map_event():
timeout.reset() timeout.reset()
@@ -236,13 +230,10 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
""" """
return self.appear(MAP_EXIT, offset=(20, 20)) return self.appear(MAP_EXIT, offset=(20, 20))
def map_exit(self, skip_first_screenshot=True): def map_exit(self):
""" """
Exit from an obscure zone, abyssal zone, or stronghold. Exit from an obscure zone, abyssal zone, or stronghold.
Args:
skip_first_screenshot:
Pages: Pages:
in: is_in_map in: is_in_map
out: is_in_map, zone that you came from out: is_in_map, zone that you came from
@@ -250,12 +241,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
logger.hr('Map exit') logger.hr('Map exit')
confirm_timer = Timer(1, count=2) confirm_timer = Timer(1, count=2)
changed = False changed = False
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if changed and self.is_in_map(): if changed and self.is_in_map():
if confirm_timer.reached(): if confirm_timer.reached():

View File

@@ -35,7 +35,7 @@ class OperationSiren(
if __name__ == '__main__': if __name__ == '__main__':
self = OperationSiren('month_test', task='OpsiMonthBoss') self = OperationSiren('alas', task='OpsiMonthBoss')
self.config = self.config.merge(OSConfig()) self.config = self.config.merge(OSConfig())

View File

@@ -108,14 +108,10 @@ class ActionPointHandler(UI, MapEventHandler):
def is_current_ap_visible(self): def is_current_ap_visible(self):
return self.match_template_color(CURRENT_AP_CHECK, offset=(40, 5), threshold=15) return self.match_template_color(CURRENT_AP_CHECK, offset=(40, 5), threshold=15)
def action_point_use(self, skip_first_screenshot=True): def action_point_use(self):
prev = self._action_point_current prev = self._action_point_current
self.interval_clear(ACTION_POINT_USE) self.interval_clear(ACTION_POINT_USE)
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear_then_click(ACTION_POINT_USE, offset=(20, 20), interval=3): if self.appear_then_click(ACTION_POINT_USE, offset=(20, 20), interval=3):
self.device.sleep(0.3) self.device.sleep(0.3)
@@ -145,15 +141,13 @@ class ActionPointHandler(UI, MapEventHandler):
self._action_point_current = current self._action_point_current = current
self._action_point_box = box self._action_point_box = box
self._action_point_total = total self._action_point_total = total
# handle exceeds
if total > 3000:
self.config.override(OpsiGeneral_DoRandomMapEvent=False)
def action_point_safe_get(self, skip_first_screenshot=True): def action_point_safe_get(self):
timeout = Timer(3, count=6).start() timeout = Timer(3, count=6).start()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_current_ap_visible(): if self.is_current_ap_visible():
break break
@@ -246,52 +240,34 @@ class ActionPointHandler(UI, MapEventHandler):
logger.warning('Unable to find an active action point box button') logger.warning('Unable to find an active action point box button')
return 1 return 1
def action_point_set_button(self, index, skip_first_screenshot=True): def action_point_set_button(self, index):
""" """
Args: Args:
index (int): 0 to 3. 0 for oil, 1 for 20 ap box, 2 for 50 ap box, 3 for 100 ap box. index (int): 0 to 3. 0 for oil, 1 for 20 ap box, 2 for 50 ap box, 3 for 100 ap box.
skip_first_screenshot (bool):
Returns: Returns:
bool: If success. bool: If success.
""" """
for _ in range(3): for _ in self.loop(timeout=2):
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.action_point_get_active_button() == index: if self.action_point_get_active_button() == index:
return True return True
else: else:
self.device.click(ACTION_POINT_GRID[index, 0]) self.device.click(ACTION_POINT_GRID[index, 0])
self.device.sleep(0.3) self.device.sleep(0.3)
else:
logger.warning('FSet action point button timeout')
return False
logger.warning('Failed to set action point button after 3 trial') def action_point_get_buy_remain(self):
return False
def action_point_get_buy_remain(self, skip_first_screenshot=True):
""" """
Args:
skip_first_screenshot:
Returns: Returns:
int: Remaining number of purchases of action points int: Remaining number of purchases of action points
Pages: Pages:
in: ACTION_POINT_USE in: ACTION_POINT_USE
""" """
timeout = Timer(1, count=2).start()
current = 0 current = 0
while 1: for _ in self.loop(timeout=1):
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if timeout.reached():
logger.warning('Get action points buy remain timeout')
break
current, _, total = OCR_ACTION_POINT_BUY_REMAIN.ocr(self.device.image) current, _, total = OCR_ACTION_POINT_BUY_REMAIN.ocr(self.device.image)
@@ -300,6 +276,8 @@ class ActionPointHandler(UI, MapEventHandler):
continue continue
break break
else:
logger.warning('Get action points buy remain timeout')
return current return current
@@ -334,18 +312,13 @@ class ActionPointHandler(UI, MapEventHandler):
logger.info('Not enough oil to buy') logger.info('Not enough oil to buy')
return False return False
def action_point_quit(self, skip_first_screenshot=True): def action_point_quit(self):
""" """
Pages: Pages:
in: ACTION_POINT_USE in: ACTION_POINT_USE
out: page_os out: page_os
""" """
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
# sometimes you have action point popup without black-blurred background # sometimes you have action point popup without black-blurred background
# ACTION_POINT_CANCEL and OS_CHECK both appears # ACTION_POINT_CANCEL and OS_CHECK both appears
@@ -454,18 +427,13 @@ class ActionPointHandler(UI, MapEventHandler):
logger.warning('Failed to get action points after 12 trial') logger.warning('Failed to get action points after 12 trial')
return False return False
def action_point_enter(self, skip_first_screenshot=True): def action_point_enter(self):
""" """
Pages: Pages:
in: OS_CHECK in: OS_CHECK
out: ACTION_POINT_USE out: ACTION_POINT_USE
""" """
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(ACTION_POINT_USE, offset=(20, 20)): if self.appear(ACTION_POINT_USE, offset=(20, 20)):
break break
@@ -500,10 +468,10 @@ class ActionPointHandler(UI, MapEventHandler):
if not self.handle_action_point(zone, pinned, cost, keep_current_ap, check_rest_ap): if not self.handle_action_point(zone, pinned, cost, keep_current_ap, check_rest_ap):
return False return False
while 1: # wait until AP popup closed
for _ in self.loop():
if self.appear(IN_MAP, offset=(200, 5)): if self.appear(IN_MAP, offset=(200, 5)):
break break
self.device.screenshot()
return True return True
@@ -525,9 +493,8 @@ class ActionPointHandler(UI, MapEventHandler):
logger.info(f'Not having {amount} action points') logger.info(f'Not having {amount} action points')
self.action_point_quit() self.action_point_quit()
while 1: for _ in self.loop():
if self.appear(IN_MAP, offset=(200, 5)): if self.appear(IN_MAP, offset=(200, 5)):
break break
self.device.screenshot()
return enough return enough

View File

@@ -1,6 +1,4 @@
from module.base.timer import Timer from module.handler.enemy_searching import EnemySearchingHandler as EnemySearchingHandler_
from module.handler.enemy_searching import \
EnemySearchingHandler as EnemySearchingHandler_
from module.logger import logger from module.logger import logger
from module.os.assets import MAP_GOTO_GLOBE_FOG from module.os.assets import MAP_GOTO_GLOBE_FOG
from module.os_handler.assets import AUTO_SEARCH_REWARD, IN_MAP, ORDER_ENTER from module.os_handler.assets import AUTO_SEARCH_REWARD, IN_MAP, ORDER_ENTER
@@ -15,25 +13,16 @@ class EnemySearchingHandler(EnemySearchingHandler_):
return False return False
def wait_os_map_buttons(self, skip_first_screenshot=True): def wait_os_map_buttons(self):
""" """
When entering a os map, radar and buttons slide out from the right. When entering a os map, radar and buttons slide out from the right.
Wait until they slide to the final position. Wait until they slide to the final position.
""" """
timeout = Timer(1, count=2).start() for _ in self.loop(timeout=1):
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
if timeout.reached():
logger.warning('wait_os_map_buttons timeout, assume waited')
break
if self.appear(ORDER_ENTER, offset=(20, 20)): if self.appear(ORDER_ENTER, offset=(20, 20)):
break break
# A game bug that AUTO_SEARCH_REWARD from the last cleared zone popups # A game bug that AUTO_SEARCH_REWARD from the last cleared zone popups
if self.appear_then_click(AUTO_SEARCH_REWARD, offset=(50, 50), interval=3): if self.appear_then_click(AUTO_SEARCH_REWARD, offset=(50, 50), interval=3):
continue continue
else:
logger.warning('wait_os_map_buttons timeout, assume waited')

View File

@@ -104,46 +104,6 @@ class MapEventHandler(EnemySearchingHandler):
else: else:
return False return False
def handle_siren_platform(self):
"""
Handle siren platform notice after entering map
Returns:
bool: If handled
"""
if not self.handle_story_skip():
return False
logger.info('Handle siren platform')
timeout = Timer(self.MAP_ENEMY_SEARCHING_TIMEOUT_SECOND).start()
appeared = False
while 1:
self.device.screenshot()
if self.is_in_map():
timeout.start()
else:
timeout.reset()
if self.handle_story_skip():
timeout.reset()
continue
# End
if self.enemy_searching_appear():
appeared = True
else:
if appeared:
self.handle_enemy_flashing()
self.device.sleep(1)
logger.info('Enemy searching appeared.')
break
self.enemy_searching_color_initial()
if timeout.reached():
logger.info('Enemy searching timeout.')
break
return True
def handle_map_event(self, drop=None): def handle_map_event(self, drop=None):
""" """
Args: Args:
@@ -185,39 +145,27 @@ class MapEventHandler(EnemySearchingHandler):
self._os_in_map_confirm_timer.reset() self._os_in_map_confirm_timer.reset()
return False return False
def ensure_no_map_event(self, skip_first_screenshot=True): def ensure_no_map_event(self):
self._os_in_map_confirm_timer.reset() self._os_in_map_confirm_timer.reset()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.handle_map_event(): if self.handle_map_event():
continue continue
# End # End
if self.handle_os_in_map(): if self.handle_os_in_map():
break break
def os_auto_search_quit(self, drop=None, skip_first_screenshot=True): def os_auto_search_quit(self, drop=None):
""" """
Args: Args:
drop (DropImage): drop (DropImage):
skip_first_screenshot (bool):
Returns: Returns:
bool: True if current map cleared bool: True if current map cleared
""" """
confirm_timer = Timer(1.2, count=3).start() confirm_timer = Timer(1.2, count=3).start()
cleared = False cleared = False
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(AUTO_SEARCH_REWARD, offset=(50, 50), interval=2): if self.appear(AUTO_SEARCH_REWARD, offset=(50, 50), interval=2):
if self.ensure_no_info_bar(): if self.ensure_no_info_bar():
cleared = True cleared = True

View File

@@ -15,19 +15,14 @@ class MapOrderHandler(MapOperation, ActionPointHandler, MapEventHandler, ZoneMan
def is_in_map_order(self): def is_in_map_order(self):
return self.appear(ORDER_CHECK, offset=(20, 20)) return self.appear(ORDER_CHECK, offset=(20, 20))
def order_enter(self, skip_first_screenshot=True): def order_enter(self):
""" """
Pages: Pages:
in: is_in_map in: is_in_map
out: is_in_map_order out: is_in_map_order
""" """
logger.info('Order enter') logger.info('Order enter')
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_map_order(): if self.is_in_map_order():
break break
@@ -52,11 +47,10 @@ class MapOrderHandler(MapOperation, ActionPointHandler, MapEventHandler, ZoneMan
self.ui_click(ORDER_CHECK, appear_button=self.is_in_map_order, check_button=self.is_in_map, self.ui_click(ORDER_CHECK, appear_button=self.is_in_map_order, check_button=self.is_in_map,
skip_first_screenshot=True) skip_first_screenshot=True)
def order_execute(self, button, skip_first_screenshot=True): def order_execute(self, button):
""" """
Args: Args:
button (Button): A button in navigational order page. button (Button): A button in navigational order page.
skip_first_screenshot (bool):
Returns: Returns:
bool: If success bool: If success
@@ -69,15 +63,10 @@ class MapOrderHandler(MapOperation, ActionPointHandler, MapEventHandler, ZoneMan
self.order_enter() self.order_enter()
missing_timer = Timer(1, count=3).start() missing_timer = Timer(1, count=3).start()
confirm_timer = Timer(1.2, count=4) confirm_timer = Timer(1.2, count=4).start()
assume_zone = self.name_to_zone(11) assume_zone = self.name_to_zone(11)
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_map(): if self.is_in_map():
if confirm_timer.reached(): if confirm_timer.reached():
@@ -109,13 +98,9 @@ class MapOrderHandler(MapOperation, ActionPointHandler, MapEventHandler, ZoneMan
missing_timer.reset() missing_timer.reset()
continue continue
def wait_until_order_finished(self, skip_first_screenshot=True): def wait_until_order_finished(self):
while 1: for _ in self.loop():
if skip_first_screenshot: # End
skip_first_screenshot = False
else:
self.device.screenshot()
if self.is_in_map() and self.appear(ORDER_ENTER, offset=(20, 20)): if self.is_in_map() and self.appear(ORDER_ENTER, offset=(20, 20)):
break break

View File

@@ -2,7 +2,7 @@ from datetime import timedelta
from module.base.timer import Timer from module.base.timer import Timer
from module.base.utils import * from module.base.utils import *
from module.config.utils import get_os_next_reset, DEFAULT_TIME from module.config.utils import DEFAULT_TIME, get_os_next_reset
from module.logger import logger from module.logger import logger
from module.map_detection.utils import fit_points from module.map_detection.utils import fit_points
from module.os.assets import GLOBE_GOTO_MAP from module.os.assets import GLOBE_GOTO_MAP
@@ -42,7 +42,7 @@ class MissionHandler(GlobeOperation, ZoneManager):
def is_in_os_mission(self): def is_in_os_mission(self):
return self.appear(MISSION_CHECK, offset=(20, 20)) return self.appear(MISSION_CHECK, offset=(20, 20))
def os_mission_enter(self, skip_first_screenshot=True): def os_mission_enter(self):
""" """
Enter mission list and claim mission reward. Enter mission list and claim mission reward.
@@ -52,12 +52,7 @@ class MissionHandler(GlobeOperation, ZoneManager):
""" """
logger.info('OS mission enter') logger.info('OS mission enter')
confirm_timer = Timer(2, count=6).start() confirm_timer = Timer(2, count=6).start()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_os_mission() \ if self.is_in_os_mission() \
and not self.appear(MISSION_FINISH, offset=(20, 20)) \ and not self.appear(MISSION_FINISH, offset=(20, 20)) \
@@ -95,14 +90,9 @@ class MissionHandler(GlobeOperation, ZoneManager):
confirm_timer.reset() confirm_timer.reset()
continue continue
def os_mission_quit(self, skip_first_screenshot=True): def os_mission_quit(self):
logger.info('OS mission quit') logger.info('OS mission quit')
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
# sometimes you have os mission popup without black-blurred background # sometimes you have os mission popup without black-blurred background
# MISSION_QUIT and is_in_map appears # MISSION_QUIT and is_in_map appears
@@ -145,13 +135,7 @@ class MissionHandler(GlobeOperation, ZoneManager):
return False return False
logger.info('Checkout os mission') logger.info('Checkout os mission')
skip_first_screenshot = True for _ in self.loop():
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_zone_pinned(): if self.is_zone_pinned():
if self.get_zone_pinned_name() == 'ARCHIVE': if self.get_zone_pinned_name() == 'ARCHIVE':
@@ -194,14 +178,8 @@ class MissionHandler(GlobeOperation, ZoneManager):
# MISSION_OVERVIEW_CHECK # MISSION_OVERVIEW_CHECK
confirm_timer = Timer(1, count=3).start() confirm_timer = Timer(1, count=3).start()
skip_first_screenshot = True
success = True success = True
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.handle_manjuu(): if self.handle_manjuu():
confirm_timer.reset() confirm_timer.reset()
continue continue

View File

@@ -62,14 +62,10 @@ class OSStatus(UI):
tasks = SelectedGrids(self.config.pending_task + self.config.waiting_task).filter(func).sort('next_run') tasks = SelectedGrids(self.config.pending_task + self.config.waiting_task).filter(func).sort('next_run')
return tasks.first_or_none() return tasks.first_or_none()
def get_yellow_coins(self, skip_first_screenshot=True) -> int: def get_yellow_coins(self) -> int:
timeout = Timer(2, count=3).start() timeout = Timer(2, count=3).start()
while True: for _ in self.loop():
if skip_first_screenshot: # End
skip_first_screenshot = False
else:
self.device.screenshot()
yellow_coins = OCR_SHOP_YELLOW_COINS.ocr(self.device.image) yellow_coins = OCR_SHOP_YELLOW_COINS.ocr(self.device.image)
if timeout.reached(): if timeout.reached():
logger.warning('Get yellow coins timeout') logger.warning('Get yellow coins timeout')

View File

@@ -54,14 +54,8 @@ class PortHandler(OSShop):
skip_first_screenshot=True) skip_first_screenshot=True)
confirm_timer = Timer(1.5, count=3).start() confirm_timer = Timer(1.5, count=3).start()
skip_first_screenshot = True
success = True success = True
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear_then_click(PORT_MISSION_ACCEPT, offset=(20, 20), interval=0.2): if self.appear_then_click(PORT_MISSION_ACCEPT, offset=(20, 20), interval=0.2):
confirm_timer.reset() confirm_timer.reset()
continue continue
@@ -110,14 +104,8 @@ class PortHandler(OSShop):
self.ui_click(PORT_GOTO_DOCK, appear_button=PORT_CHECK, check_button=PORT_DOCK_CHECK, self.ui_click(PORT_GOTO_DOCK, appear_button=PORT_CHECK, check_button=PORT_DOCK_CHECK,
skip_first_screenshot=True) skip_first_screenshot=True)
skip_first_screenshot = True
repaired = False repaired = False
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.info_bar_count(): if self.info_bar_count():
break break

View File

@@ -16,19 +16,14 @@ class StorageHandler(GlobeOperation, ZoneManager):
def is_in_storage(self): def is_in_storage(self):
return self.appear(STORAGE_CHECK, offset=(20, 20)) return self.appear(STORAGE_CHECK, offset=(20, 20))
def storage_enter(self, skip_first_screenshot=True): def storage_enter(self):
""" """
Pages: Pages:
in: is_in_map, STORAGE_ENTER in: is_in_map, STORAGE_ENTER
out: STORAGE_CHECK out: STORAGE_CHECK
""" """
logger.info('Storage enter') logger.info('Storage enter')
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End # End
if self.is_in_storage(): if self.is_in_storage():
break break
@@ -52,11 +47,10 @@ class StorageHandler(GlobeOperation, ZoneManager):
logger.info('Storage quit') logger.info('Storage quit')
self.ui_back(STORAGE_ENTER, offset=(200, 5), skip_first_screenshot=True) self.ui_back(STORAGE_ENTER, offset=(200, 5), skip_first_screenshot=True)
def _storage_item_use(self, button, skip_first_screenshot=True): def _storage_item_use(self, button):
""" """
Args: Args:
button (Button): Item button (Button): Item
skip_first_screenshot (bool):
Pages: Pages:
in: STORAGE_CHECK in: STORAGE_CHECK
@@ -71,12 +65,7 @@ class StorageHandler(GlobeOperation, ZoneManager):
self.interval_clear(GET_ADAPTABILITY) self.interval_clear(GET_ADAPTABILITY)
self.interval_clear(GET_MISSION) self.interval_clear(GET_MISSION)
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# Accidentally clicked on an item, having popups for its info # Accidentally clicked on an item, having popups for its info
if self.appear(GET_MISSION, offset=True, interval=2): if self.appear(GET_MISSION, offset=True, interval=2):
logger.info(f'_storage_item_use item info -> {GET_MISSION}') logger.info(f'_storage_item_use item info -> {GET_MISSION}')
@@ -112,22 +101,14 @@ class StorageHandler(GlobeOperation, ZoneManager):
if success and self.appear(STORAGE_CHECK, offset=(20, 20)): if success and self.appear(STORAGE_CHECK, offset=(20, 20)):
break break
def storage_logger_use_all(self, skip_first_screenshot=True): def storage_logger_use_all(self):
""" """
Args:
skip_first_screenshot:
Pages: Pages:
in: STORAGE_CHECK in: STORAGE_CHECK
out: STORAGE_CHECK, scroll to bottom out: STORAGE_CHECK, scroll to bottom
""" """
logger.hr('Storage logger use all') logger.hr('Storage logger use all')
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if SCROLL_STORAGE.appear(main=self): if SCROLL_STORAGE.appear(main=self):
SCROLL_STORAGE.set_bottom(main=self, skip_first_screenshot=True) SCROLL_STORAGE.set_bottom(main=self, skip_first_screenshot=True)
@@ -142,11 +123,8 @@ class StorageHandler(GlobeOperation, ZoneManager):
logger.info('All loggers in storage have been used') logger.info('All loggers in storage have been used')
break break
def storage_sample_use_all(self, skip_first_screenshot=True): def storage_sample_use_all(self):
""" """
Args:
skip_first_screenshot:
Pages: Pages:
in: STORAGE_CHECK in: STORAGE_CHECK
out: STORAGE_CHECK, scroll to bottom out: STORAGE_CHECK, scroll to bottom
@@ -156,12 +134,7 @@ class StorageHandler(GlobeOperation, ZoneManager):
TEMPLATE_STORAGE_QUALITY_OFFENSE, TEMPLATE_STORAGE_QUALITY_SURVIVAL, TEMPLATE_STORAGE_QUALITY_COMBAT TEMPLATE_STORAGE_QUALITY_OFFENSE, TEMPLATE_STORAGE_QUALITY_SURVIVAL, TEMPLATE_STORAGE_QUALITY_COMBAT
] ]
for sample_type in sample_types: for sample_type in sample_types:
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
image = rgb2gray(self.device.image) image = rgb2gray(self.device.image)
items = sample_type.match_multi(image, similarity=0.75) items = sample_type.match_multi(image, similarity=0.75)
logger.attr('Storage_sample', len(items)) logger.attr('Storage_sample', len(items))
@@ -178,12 +151,11 @@ class StorageHandler(GlobeOperation, ZoneManager):
self.storage_sample_use_all() self.storage_sample_use_all()
self.storage_quit() self.storage_quit()
def _storage_coordinate_checkout(self, button, types=('OBSCURE',), skip_first_screenshot=True): def _storage_coordinate_checkout(self, button, types=('OBSCURE',)):
""" """
Args: Args:
button (Button): Item button (Button): Item
types (tuple[str]): types (tuple[str]):
skip_first_screenshot (bool):
Pages: Pages:
in: STORAGE_CHECK in: STORAGE_CHECK
@@ -194,12 +166,7 @@ class StorageHandler(GlobeOperation, ZoneManager):
STORAGE_COORDINATE_CHECKOUT STORAGE_COORDINATE_CHECKOUT
]) ])
self.popup_interval_clear() self.popup_interval_clear()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(STORAGE_CHECK, offset=(30, 30), interval=5): if self.appear(STORAGE_CHECK, offset=(30, 30), interval=5):
self.device.click(button) self.device.click(button)
continue continue
@@ -233,11 +200,10 @@ class StorageHandler(GlobeOperation, ZoneManager):
else: else:
raise ScriptError(f'Unknown storage item: {item}') raise ScriptError(f'Unknown storage item: {item}')
def storage_checkout_item(self, item, skip_first_screenshot=True): def storage_checkout_item(self, item):
""" """
Args: Args:
item (str): 'OBSCURE' or 'ABYSSAL'. item (str): 'OBSCURE' or 'ABYSSAL'.
skip_first_screenshot:
Returns: Returns:
bool: If checkout bool: If checkout
@@ -252,12 +218,7 @@ class StorageHandler(GlobeOperation, ZoneManager):
SCROLL_STORAGE.set_top(main=self, skip_first_screenshot=skip_first_screenshot) SCROLL_STORAGE.set_top(main=self, skip_first_screenshot=skip_first_screenshot)
confirm_timer = Timer(0.6, count=2).start() confirm_timer = Timer(0.6, count=2).start()
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
image = rgb2gray(self.device.image) image = rgb2gray(self.device.image)
items = self._storage_item_to_template(item).match_multi(image, similarity=0.75) items = self._storage_item_to_template(item).match_multi(image, similarity=0.75)
logger.attr(f'Storage_{item}', len(items)) logger.attr(f'Storage_{item}', len(items))

View File

@@ -1,4 +1,3 @@
from module.base.timer import Timer
from module.base.utils import get_color from module.base.utils import get_color
from module.logger import logger from module.logger import logger
from module.os_handler.assets import * from module.os_handler.assets import *
@@ -9,15 +8,11 @@ STRATEGIC_SEARCH_SCROLL = Scroll(STRATEGIC_SEARCH_SCROLL_AREA, color=(247, 211,
class StrategicSearchHandler(MapEventHandler): class StrategicSearchHandler(MapEventHandler):
def strategy_search_enter(self, skip_first_screenshot=False): def strategy_search_enter(self):
logger.info('Strategic search enter') logger.info('Strategic search enter')
self.interval_clear(STRATEGIC_SEARCH_MAP_OPTION_OFF) self.interval_clear(STRATEGIC_SEARCH_MAP_OPTION_OFF)
while 1: for _ in self.loop():
if skip_first_screenshot: # End
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(STRATEGIC_SEARCH_POPUP_CHECK, offset=(20, 20)): if self.appear(STRATEGIC_SEARCH_POPUP_CHECK, offset=(20, 20)):
return True return True
@@ -29,39 +24,28 @@ class StrategicSearchHandler(MapEventHandler):
self.device.click(STRATEGIC_SEARCH_MAP_OPTION_OFF) self.device.click(STRATEGIC_SEARCH_MAP_OPTION_OFF)
continue continue
def strategic_search_set_tab(self, skip_first_screenshot=False): def strategic_search_set_tab(self):
logger.info('Strategic search set tab') logger.info('Strategic search set tab')
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if get_color(self.device.image, STRATEGIC_SEARCH_TAB_SECURED.area)[2] <= 150: if get_color(self.device.image, STRATEGIC_SEARCH_TAB_SECURED.area)[2] <= 150:
self.device.click(STRATEGIC_SEARCH_TAB_SECURED) self.device.click(STRATEGIC_SEARCH_TAB_SECURED)
continue continue
if get_color(self.device.image, STRATEGIC_SEARCH_TAB_SECURED.area)[2] > 150: if get_color(self.device.image, STRATEGIC_SEARCH_TAB_SECURED.area)[2] > 150:
break break
def _strategy_search_scroll_appear(self, skip_first_screenshot=True): def _strategy_search_scroll_appear(self):
""" """
Returns: Returns:
bool: If it still exists bool: If it still exists
""" """
timeout = Timer(2, count=4).start() for _ in self.loop(timeout=2):
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if STRATEGIC_SEARCH_SCROLL.appear(main=self): if STRATEGIC_SEARCH_SCROLL.appear(main=self):
return True return True
else: else:
logger.warning('STRATEGIC_SEARCH_SCROLL disappeared') logger.warning('STRATEGIC_SEARCH_SCROLL disappeared')
if timeout.reached(): else:
logger.warning('STRATEGIC_SEARCH_SCROLL disappeared confirm') logger.warning('STRATEGIC_SEARCH_SCROLL disappeared confirm')
return False return False
def _strategy_option_selected(self, button): def _strategy_option_selected(self, button):
""" """
@@ -69,21 +53,18 @@ class StrategicSearchHandler(MapEventHandler):
""" """
return self.image_color_count(button.button, color=(156, 255, 82), count=30) return self.image_color_count(button.button, color=(156, 255, 82), count=30)
def strategic_search_set_option(self, skip_first_screenshot=True): def strategic_search_set_option(self):
""" """
Args:
skip_first_screenshot:
Returns: Returns:
If success. False if strategic settings closed for unknown reason. If success. False if strategic settings closed for unknown reason.
""" """
logger.info('Strategic search set option') logger.info('Strategic search set option')
while 1: for _ in self.loop():
if skip_first_screenshot: if self._strategy_option_selected(STRATEGIC_SEARCH_ZONEMODE_REPEAT) \
skip_first_screenshot = False and self._strategy_option_selected(STRATEGIC_SEARCH_MERCHANT_STOP):
else: logger.attr('zone_mode', 'repeat')
self.device.screenshot() logger.attr('encounter_merchant', 'stop')
break
if self._strategy_option_selected(STRATEGIC_SEARCH_ZONEMODE_RANDOM): if self._strategy_option_selected(STRATEGIC_SEARCH_ZONEMODE_RANDOM):
logger.attr('zone_mode', 'random') logger.attr('zone_mode', 'random')
self.device.click(STRATEGIC_SEARCH_ZONEMODE_REPEAT) self.device.click(STRATEGIC_SEARCH_ZONEMODE_REPEAT)
@@ -92,36 +73,24 @@ class StrategicSearchHandler(MapEventHandler):
logger.attr('encounter_merchant', 'continue') logger.attr('encounter_merchant', 'continue')
self.device.click(STRATEGIC_SEARCH_MERCHANT_STOP) self.device.click(STRATEGIC_SEARCH_MERCHANT_STOP)
continue continue
if self._strategy_option_selected(STRATEGIC_SEARCH_ZONEMODE_REPEAT) \
and self._strategy_option_selected(STRATEGIC_SEARCH_MERCHANT_STOP):
logger.attr('zone_mode', 'repeat')
logger.attr('encounter_merchant', 'stop')
skip_first_screenshot = True
break
STRATEGIC_SEARCH_SCROLL.drag_threshold = 0.1 STRATEGIC_SEARCH_SCROLL.drag_threshold = 0.1
STRATEGIC_SEARCH_SCROLL.set(0.5, main=self) STRATEGIC_SEARCH_SCROLL.set(0.5, main=self)
if not self._strategy_search_scroll_appear(): if not self._strategy_search_scroll_appear():
return False return False
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
self.appear(STRATEGIC_SEARCH_DEVICE_CHECK, offset=(20, 200), similarity=0.7) self.appear(STRATEGIC_SEARCH_DEVICE_CHECK, offset=(20, 200), similarity=0.7)
STRATEGIC_SEARCH_DEVICE_STOP.load_offset(STRATEGIC_SEARCH_DEVICE_CHECK) STRATEGIC_SEARCH_DEVICE_STOP.load_offset(STRATEGIC_SEARCH_DEVICE_CHECK)
STRATEGIC_SEARCH_DEVICE_CONTINUE.load_offset(STRATEGIC_SEARCH_DEVICE_CHECK) STRATEGIC_SEARCH_DEVICE_CONTINUE.load_offset(STRATEGIC_SEARCH_DEVICE_CHECK)
if self._strategy_option_selected(STRATEGIC_SEARCH_DEVICE_STOP):
logger.attr('encounter_device', 'stop')
break
if self._strategy_option_selected(STRATEGIC_SEARCH_DEVICE_CONTINUE): if self._strategy_option_selected(STRATEGIC_SEARCH_DEVICE_CONTINUE):
logger.attr('encounter_device', 'continue') logger.attr('encounter_device', 'continue')
self.device.click(STRATEGIC_SEARCH_DEVICE_STOP) self.device.click(STRATEGIC_SEARCH_DEVICE_STOP)
continue continue
if self._strategy_option_selected(STRATEGIC_SEARCH_DEVICE_STOP):
logger.attr('encounter_device', 'stop')
skip_first_screenshot = True
break
STRATEGIC_SEARCH_SCROLL.drag_threshold = 0.05 STRATEGIC_SEARCH_SCROLL.drag_threshold = 0.05
STRATEGIC_SEARCH_SCROLL.edge_add = (0.5, 0.8) STRATEGIC_SEARCH_SCROLL.edge_add = (0.5, 0.8)
@@ -129,42 +98,31 @@ class StrategicSearchHandler(MapEventHandler):
if not self._strategy_search_scroll_appear(): if not self._strategy_search_scroll_appear():
return False return False
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
self.appear(STRATEGIC_SEARCH_SUBMIT_CHECK, offset=(20, 20), similarity=0.7) self.appear(STRATEGIC_SEARCH_SUBMIT_CHECK, offset=(20, 20), similarity=0.7)
STRATEGIC_SEARCH_SUBMIT_OFF.load_offset(STRATEGIC_SEARCH_SUBMIT_CHECK) STRATEGIC_SEARCH_SUBMIT_OFF.load_offset(STRATEGIC_SEARCH_SUBMIT_CHECK)
STRATEGIC_SEARCH_SUBMIT_ON.load_offset(STRATEGIC_SEARCH_SUBMIT_CHECK) STRATEGIC_SEARCH_SUBMIT_ON.load_offset(STRATEGIC_SEARCH_SUBMIT_CHECK)
if self._strategy_option_selected(STRATEGIC_SEARCH_SUBMIT_ON):
logger.attr('auto_submit', 'on')
break
if self._strategy_option_selected(STRATEGIC_SEARCH_SUBMIT_OFF): if self._strategy_option_selected(STRATEGIC_SEARCH_SUBMIT_OFF):
logger.attr('auto_submit', 'off') logger.attr('auto_submit', 'off')
self.device.click(STRATEGIC_SEARCH_SUBMIT_ON) self.device.click(STRATEGIC_SEARCH_SUBMIT_ON)
continue continue
if self._strategy_option_selected(STRATEGIC_SEARCH_SUBMIT_ON):
logger.attr('auto_submit', 'on')
break
return True return True
def strategic_search_confirm(self, skip_first_screenshot=False): def strategic_search_confirm(self):
logger.info('Strategic search confirm') logger.info('Strategic search confirm')
while 1: for _ in self.loop():
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(STRATEGIC_SEARCH_POPUP_CHECK, offset=(20, 20)) \ if self.appear(STRATEGIC_SEARCH_POPUP_CHECK, offset=(20, 20)) \
and self.handle_popup_confirm(offset=(30, 30), name='STRATEGIC_SEARCH'): and self.handle_popup_confirm(offset=(30, 30), name='STRATEGIC_SEARCH'):
continue continue
if self.is_in_map(): if self.is_in_map():
return True return True
def strategic_search_start(self, skip_first_screenshot=False): def strategic_search_start(self):
""" """
Returns: Returns:
If success. If success.
@@ -175,12 +133,12 @@ class StrategicSearchHandler(MapEventHandler):
""" """
logger.hr('Strategic search start') logger.hr('Strategic search start')
for _ in range(3): for _ in range(3):
self.strategy_search_enter(skip_first_screenshot=skip_first_screenshot) self.strategy_search_enter()
self.strategic_search_set_tab(skip_first_screenshot=True) self.strategic_search_set_tab()
success = self.strategic_search_set_option(skip_first_screenshot=True) success = self.strategic_search_set_option()
if not success: if not success:
continue continue
self.strategic_search_confirm(skip_first_screenshot=True) self.strategic_search_confirm()
return True return True
logger.warning('Failed to start strategic search') logger.warning('Failed to start strategic search')

View File

@@ -8,7 +8,7 @@ ADD_NEW_STUDENT = Button(area={'cn': (417, 375, 438, 398), 'en': (417, 375, 438,
BOOK_EMPTY_POPUP = Button(area={'cn': (880, 180, 908, 209), 'en': (880, 180, 908, 209), 'jp': (880, 180, 908, 209), 'tw': (880, 180, 908, 209)}, color={'cn': (211, 109, 105), 'en': (211, 109, 105), 'jp': (211, 109, 105), 'tw': (211, 109, 105)}, button={'cn': (880, 180, 908, 209), 'en': (880, 180, 908, 209), 'jp': (880, 180, 908, 209), 'tw': (880, 180, 908, 209)}, file={'cn': './assets/cn/tactical/BOOK_EMPTY_POPUP.png', 'en': './assets/en/tactical/BOOK_EMPTY_POPUP.png', 'jp': './assets/jp/tactical/BOOK_EMPTY_POPUP.png', 'tw': './assets/tw/tactical/BOOK_EMPTY_POPUP.png'}) BOOK_EMPTY_POPUP = Button(area={'cn': (880, 180, 908, 209), 'en': (880, 180, 908, 209), 'jp': (880, 180, 908, 209), 'tw': (880, 180, 908, 209)}, color={'cn': (211, 109, 105), 'en': (211, 109, 105), 'jp': (211, 109, 105), 'tw': (211, 109, 105)}, button={'cn': (880, 180, 908, 209), 'en': (880, 180, 908, 209), 'jp': (880, 180, 908, 209), 'tw': (880, 180, 908, 209)}, file={'cn': './assets/cn/tactical/BOOK_EMPTY_POPUP.png', 'en': './assets/en/tactical/BOOK_EMPTY_POPUP.png', 'jp': './assets/jp/tactical/BOOK_EMPTY_POPUP.png', 'tw': './assets/tw/tactical/BOOK_EMPTY_POPUP.png'})
OCR_SKILL_EXP = Button(area={'cn': (771, 191, 951, 209), 'en': (771, 191, 951, 209), 'jp': (728, 189, 950, 211), 'tw': (771, 191, 951, 209)}, color={'cn': (72, 82, 83), 'en': (72, 82, 83), 'jp': (69, 78, 82), 'tw': (72, 82, 83)}, button={'cn': (771, 191, 951, 209), 'en': (771, 191, 951, 209), 'jp': (728, 189, 950, 211), 'tw': (771, 191, 951, 209)}, file={'cn': './assets/cn/tactical/OCR_SKILL_EXP.png', 'en': './assets/en/tactical/OCR_SKILL_EXP.png', 'jp': './assets/jp/tactical/OCR_SKILL_EXP.png', 'tw': './assets/tw/tactical/OCR_SKILL_EXP.png'}) OCR_SKILL_EXP = Button(area={'cn': (771, 191, 951, 209), 'en': (771, 191, 951, 209), 'jp': (728, 189, 950, 211), 'tw': (771, 191, 951, 209)}, color={'cn': (72, 82, 83), 'en': (72, 82, 83), 'jp': (69, 78, 82), 'tw': (72, 82, 83)}, button={'cn': (771, 191, 951, 209), 'en': (771, 191, 951, 209), 'jp': (728, 189, 950, 211), 'tw': (771, 191, 951, 209)}, file={'cn': './assets/cn/tactical/OCR_SKILL_EXP.png', 'en': './assets/en/tactical/OCR_SKILL_EXP.png', 'jp': './assets/jp/tactical/OCR_SKILL_EXP.png', 'tw': './assets/tw/tactical/OCR_SKILL_EXP.png'})
RAPID_TRAINING = Button(area={'cn': (518, 566, 583, 582), 'en': (518, 568, 585, 580), 'jp': (518, 566, 584, 583), 'tw': (518, 566, 583, 582)}, color={'cn': (233, 212, 171), 'en': (229, 205, 156), 'jp': (232, 209, 165), 'tw': (233, 212, 171)}, button={'cn': (518, 566, 583, 582), 'en': (518, 568, 585, 580), 'jp': (518, 566, 584, 583), 'tw': (518, 566, 583, 582)}, file={'cn': './assets/cn/tactical/RAPID_TRAINING.png', 'en': './assets/en/tactical/RAPID_TRAINING.png', 'jp': './assets/jp/tactical/RAPID_TRAINING.png', 'tw': './assets/cn/tactical/RAPID_TRAINING.png'}) RAPID_TRAINING = Button(area={'cn': (518, 566, 583, 582), 'en': (518, 568, 585, 580), 'jp': (518, 566, 584, 583), 'tw': (518, 566, 583, 582)}, color={'cn': (233, 212, 171), 'en': (229, 205, 156), 'jp': (232, 209, 165), 'tw': (233, 212, 171)}, button={'cn': (518, 566, 583, 582), 'en': (518, 568, 585, 580), 'jp': (518, 566, 584, 583), 'tw': (518, 566, 583, 582)}, file={'cn': './assets/cn/tactical/RAPID_TRAINING.png', 'en': './assets/en/tactical/RAPID_TRAINING.png', 'jp': './assets/jp/tactical/RAPID_TRAINING.png', 'tw': './assets/cn/tactical/RAPID_TRAINING.png'})
REWARD_2 = Button(area={'cn': (418, 413, 468, 434), 'en': (403, 416, 504, 432), 'jp': (432, 415, 476, 436), 'tw': (418, 413, 468, 434)}, color={'cn': (240, 191, 120), 'en': (240, 201, 145), 'jp': (240, 191, 121), 'tw': (240, 191, 120)}, button={'cn': (383, 404, 503, 444), 'en': (392, 404, 515, 445), 'jp': (383, 404, 503, 444), 'tw': (383, 404, 503, 444)}, file={'cn': './assets/cn/tactical/REWARD_2.png', 'en': './assets/en/tactical/REWARD_2.png', 'jp': './assets/jp/tactical/REWARD_2.png', 'tw': './assets/tw/tactical/REWARD_2.png'}) REWARD_2 = Button(area={'cn': (418, 413, 468, 434), 'en': (403, 416, 504, 432), 'jp': (432, 415, 476, 436), 'tw': (418, 413, 468, 434)}, color={'cn': (240, 191, 120), 'en': (240, 201, 145), 'jp': (240, 191, 121), 'tw': (240, 191, 120)}, button={'cn': (383, 404, 503, 444), 'en': (392, 404, 515, 445), 'jp': (399, 415, 520, 450), 'tw': (383, 404, 503, 444)}, file={'cn': './assets/cn/tactical/REWARD_2.png', 'en': './assets/en/tactical/REWARD_2.png', 'jp': './assets/jp/tactical/REWARD_2.png', 'tw': './assets/tw/tactical/REWARD_2.png'})
SKILL_CONFIRM = Button(area={'cn': (575, 563, 705, 594), 'en': (600, 558, 681, 581), 'jp': (576, 563, 705, 594), 'tw': (577, 563, 704, 593)}, color={'cn': (147, 177, 216), 'en': (167, 191, 223), 'jp': (136, 170, 213), 'tw': (161, 187, 220)}, button={'cn': (575, 563, 705, 594), 'en': (600, 558, 681, 581), 'jp': (576, 563, 705, 594), 'tw': (577, 563, 704, 593)}, file={'cn': './assets/cn/tactical/SKILL_CONFIRM.png', 'en': './assets/en/tactical/SKILL_CONFIRM.png', 'jp': './assets/jp/tactical/SKILL_CONFIRM.png', 'tw': './assets/tw/tactical/SKILL_CONFIRM.png'}) SKILL_CONFIRM = Button(area={'cn': (575, 563, 705, 594), 'en': (600, 558, 681, 581), 'jp': (576, 563, 705, 594), 'tw': (577, 563, 704, 593)}, color={'cn': (147, 177, 216), 'en': (167, 191, 223), 'jp': (136, 170, 213), 'tw': (161, 187, 220)}, button={'cn': (575, 563, 705, 594), 'en': (600, 558, 681, 581), 'jp': (576, 563, 705, 594), 'tw': (577, 563, 704, 593)}, file={'cn': './assets/cn/tactical/SKILL_CONFIRM.png', 'en': './assets/en/tactical/SKILL_CONFIRM.png', 'jp': './assets/jp/tactical/SKILL_CONFIRM.png', 'tw': './assets/tw/tactical/SKILL_CONFIRM.png'})
TACTICAL_CLASS_CANCEL = Button(area={'cn': (818, 591, 990, 647), 'en': (836, 591, 973, 639), 'jp': (840, 606, 969, 637), 'tw': (819, 590, 989, 647)}, color={'cn': (153, 154, 154), 'en': (163, 164, 164), 'jp': (175, 176, 176), 'tw': (152, 153, 154)}, button={'cn': (818, 591, 990, 647), 'en': (836, 591, 973, 639), 'jp': (840, 606, 969, 637), 'tw': (819, 590, 989, 647)}, file={'cn': './assets/cn/tactical/TACTICAL_CLASS_CANCEL.png', 'en': './assets/en/tactical/TACTICAL_CLASS_CANCEL.png', 'jp': './assets/jp/tactical/TACTICAL_CLASS_CANCEL.png', 'tw': './assets/tw/tactical/TACTICAL_CLASS_CANCEL.png'}) TACTICAL_CLASS_CANCEL = Button(area={'cn': (818, 591, 990, 647), 'en': (836, 591, 973, 639), 'jp': (840, 606, 969, 637), 'tw': (819, 590, 989, 647)}, color={'cn': (153, 154, 154), 'en': (163, 164, 164), 'jp': (175, 176, 176), 'tw': (152, 153, 154)}, button={'cn': (818, 591, 990, 647), 'en': (836, 591, 973, 639), 'jp': (840, 606, 969, 637), 'tw': (819, 590, 989, 647)}, file={'cn': './assets/cn/tactical/TACTICAL_CLASS_CANCEL.png', 'en': './assets/en/tactical/TACTICAL_CLASS_CANCEL.png', 'jp': './assets/jp/tactical/TACTICAL_CLASS_CANCEL.png', 'tw': './assets/tw/tactical/TACTICAL_CLASS_CANCEL.png'})
TACTICAL_CLASS_START = Button(area={'cn': (1024, 590, 1197, 648), 'en': (1045, 592, 1176, 640), 'jp': (1046, 606, 1176, 637), 'tw': (1026, 590, 1196, 647)}, color={'cn': (96, 139, 194), 'en': (95, 137, 190), 'jp': (132, 165, 208), 'tw': (101, 143, 196)}, button={'cn': (1024, 590, 1197, 648), 'en': (1045, 592, 1176, 640), 'jp': (1046, 606, 1176, 637), 'tw': (1026, 590, 1196, 647)}, file={'cn': './assets/cn/tactical/TACTICAL_CLASS_START.png', 'en': './assets/en/tactical/TACTICAL_CLASS_START.png', 'jp': './assets/jp/tactical/TACTICAL_CLASS_START.png', 'tw': './assets/tw/tactical/TACTICAL_CLASS_START.png'}) TACTICAL_CLASS_START = Button(area={'cn': (1024, 590, 1197, 648), 'en': (1045, 592, 1176, 640), 'jp': (1046, 606, 1176, 637), 'tw': (1026, 590, 1196, 647)}, color={'cn': (96, 139, 194), 'en': (95, 137, 190), 'jp': (132, 165, 208), 'tw': (101, 143, 196)}, button={'cn': (1024, 590, 1197, 648), 'en': (1045, 592, 1176, 640), 'jp': (1046, 606, 1176, 637), 'tw': (1026, 590, 1196, 647)}, file={'cn': './assets/cn/tactical/TACTICAL_CLASS_START.png', 'en': './assets/en/tactical/TACTICAL_CLASS_START.png', 'jp': './assets/jp/tactical/TACTICAL_CLASS_START.png', 'tw': './assets/tw/tactical/TACTICAL_CLASS_START.png'})

View File

@@ -134,7 +134,7 @@ page_campaign.link(button=CAMPAIGN_GOTO_EVENT, destination=page_sp)
# FROSTFALL # FROSTFALL
# page_coalition = Page(FROSTFALL_COALITION_CHECK) # page_coalition = Page(FROSTFALL_COALITION_CHECK)
# page_coalition.link(button=GOTO_MAIN, destination=page_main) # page_coalition.link(button=GOTO_MAIN, destination=page_main)
# page_coalition.link(button=BACK_ARROW, destination=page_campaign) # page_coalition.link(button=BACK_ARROW, destination=page_campaign_menu)
# page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition) # page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition)
# ACADEMY # ACADEMY
# page_coalition_menu = Page(COALITION_ACADEMY_MAIN_CHECK) # page_coalition_menu = Page(COALITION_ACADEMY_MAIN_CHECK)
@@ -147,12 +147,17 @@ page_campaign.link(button=CAMPAIGN_GOTO_EVENT, destination=page_sp)
# NEONCITY # NEONCITY
# page_coalition = Page(NEONCITY_COALITION_CHECK) # page_coalition = Page(NEONCITY_COALITION_CHECK)
# page_coalition.link(button=NEONCITY_UI_HOME, destination=page_main) # page_coalition.link(button=NEONCITY_UI_HOME, destination=page_main)
# page_coalition.link(button=NEONCITY_UI_BACK, destination=page_campaign) # page_coalition.link(button=NEONCITY_UI_BACK, destination=page_campaign_menu)
# page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition) # page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition)
# DAL # DAL
page_coalition = Page(FROSTFALL_COALITION_CHECK) # page_coalition = Page(FROSTFALL_COALITION_CHECK)
# page_coalition.link(button=GOTO_MAIN, destination=page_main)
# page_coalition.link(button=BACK_ARROW, destination=page_campaign_menu)
# page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition)
# FASHION
page_coalition = Page(FASHION_COALITION_CHECK)
page_coalition.link(button=GOTO_MAIN, destination=page_main) page_coalition.link(button=GOTO_MAIN, destination=page_main)
page_coalition.link(button=BACK_ARROW, destination=page_campaign) page_coalition.link(button=BACK_ARROW, destination=page_campaign_menu)
page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition) page_campaign_menu.link(button=CAMPAIGN_MENU_GOTO_EVENT, destination=page_coalition)
# Operation Siren # Operation Siren