revert: 恢复萨米肉鸽使用密文板
Revert "Revert "feat: 萨米肉鸽使用密文板 (#6949)" (#7054)"
This reverts commit c109acd709.
406
resource/roguelike/Sami/ciphertext_board.json
Normal file
@@ -0,0 +1,406 @@
|
||||
{
|
||||
"theme": "Sami",
|
||||
"groups": [
|
||||
{
|
||||
"usage": "SkipBattle",
|
||||
"doc": "跳过战斗,刷钱和烧开水模式",
|
||||
"pairs": [
|
||||
{
|
||||
"up": [
|
||||
"伤痕"
|
||||
],
|
||||
"down": [
|
||||
"空无"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"黜人",
|
||||
"猎手",
|
||||
"战士",
|
||||
"萨满",
|
||||
"英雄",
|
||||
"源石",
|
||||
"灌木",
|
||||
"兽类",
|
||||
"人类",
|
||||
"眼睛",
|
||||
"雪祀"
|
||||
],
|
||||
"down": [
|
||||
"惊讶",
|
||||
"疑惑",
|
||||
"爱恋",
|
||||
"繁衍"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"usage": "Boss",
|
||||
"doc": "有的用全用了",
|
||||
"pairs": [
|
||||
{
|
||||
"up": [
|
||||
"黜人",
|
||||
"猎手",
|
||||
"战士",
|
||||
"萨满",
|
||||
"英雄",
|
||||
"雪祀",
|
||||
"源石",
|
||||
"灌木",
|
||||
"兽类",
|
||||
"人类",
|
||||
"眼睛"
|
||||
],
|
||||
"down": [
|
||||
"歌唱",
|
||||
"沉默",
|
||||
"朗诵",
|
||||
"辩论",
|
||||
"慰藉",
|
||||
"告解",
|
||||
"喜悦",
|
||||
"惊讶",
|
||||
"愤怒",
|
||||
"疑惑",
|
||||
"憧憬",
|
||||
"爱恋",
|
||||
"巡视",
|
||||
"筑巢",
|
||||
"捕猎",
|
||||
"掠夺",
|
||||
"繁衍",
|
||||
"迁徙"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"usage": "Battle",
|
||||
"pairs": [
|
||||
{
|
||||
"up": [
|
||||
"人类",
|
||||
"兽类",
|
||||
"灌木",
|
||||
"砂石"
|
||||
],
|
||||
"down": [
|
||||
"迁徙",
|
||||
"掠夺",
|
||||
"筑巢"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"英雄",
|
||||
"萨满",
|
||||
"战士",
|
||||
"雪祀",
|
||||
"猎手",
|
||||
"黜人"
|
||||
],
|
||||
"down": [
|
||||
"慰藉",
|
||||
"告解",
|
||||
"朗诵"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"usage": "Trader",
|
||||
"pairs": [
|
||||
{
|
||||
"up": [
|
||||
"人类",
|
||||
"兽类",
|
||||
"灌木",
|
||||
"砂石"
|
||||
],
|
||||
"down": [
|
||||
"迁徙",
|
||||
"掠夺",
|
||||
"筑巢"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"大地",
|
||||
"光芒",
|
||||
"拱门",
|
||||
"眼睛",
|
||||
"水面"
|
||||
],
|
||||
"down": [
|
||||
"喜悦",
|
||||
"愤怒"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"眼睛"
|
||||
],
|
||||
"down": [
|
||||
"憧憬"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"usage": "Encounter",
|
||||
"pairs": [
|
||||
{
|
||||
"up": [
|
||||
"人类",
|
||||
"兽类",
|
||||
"灌木",
|
||||
"砂石"
|
||||
],
|
||||
"down": [
|
||||
"迁徙",
|
||||
"掠夺",
|
||||
"筑巢"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"树冠",
|
||||
"大地",
|
||||
"光芒",
|
||||
"拱门",
|
||||
"眼睛",
|
||||
"水面"
|
||||
],
|
||||
"down": [
|
||||
"惊讶",
|
||||
"爱恋",
|
||||
"喜悦",
|
||||
"憧憬",
|
||||
"朗诵"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"usage": "Gambling",
|
||||
"doc": "其他不期而遇节点",
|
||||
"pairs": [
|
||||
{
|
||||
"up": [
|
||||
"人类",
|
||||
"兽类",
|
||||
"灌木",
|
||||
"砂石"
|
||||
],
|
||||
"down": [
|
||||
"迁徙",
|
||||
"掠夺",
|
||||
"筑巢"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"大地",
|
||||
"光芒",
|
||||
"拱门",
|
||||
"眼睛",
|
||||
"水面"
|
||||
],
|
||||
"down": [
|
||||
"惊讶",
|
||||
"爱恋",
|
||||
"喜悦",
|
||||
"憧憬",
|
||||
"朗诵"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"乔木",
|
||||
"源石"
|
||||
],
|
||||
"down": [
|
||||
"捕猎",
|
||||
"繁衍",
|
||||
"朗诵"
|
||||
]
|
||||
},
|
||||
{
|
||||
"up": [
|
||||
"树冠"
|
||||
],
|
||||
"down": [
|
||||
"疑惑"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"ciphertextBoard": [
|
||||
{
|
||||
"name": "布局",
|
||||
"ciphertextBoard": [
|
||||
{
|
||||
"name": "黜人",
|
||||
"effect": "选择所有右侧邻近的战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "猎手",
|
||||
"effect": "选择1处战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "战士",
|
||||
"effect": "选择1处战斗节点,再随机指定1处战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "萨满",
|
||||
"effect": "选择1处战斗节点,再随机指定2处战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "雪祀",
|
||||
"effect": "随机指定3处战斗节点,在深埋迷境中改为3处任意节点"
|
||||
},
|
||||
{
|
||||
"name": "英雄",
|
||||
"effect": "选择所有战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "树冠",
|
||||
"effect": "选择1处不期而遇"
|
||||
},
|
||||
{
|
||||
"name": "水面",
|
||||
"effect": "选择1处非战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "眼睛",
|
||||
"effect": "选择1处右侧邻近的节点"
|
||||
},
|
||||
{
|
||||
"name": "拱门",
|
||||
"effect": "选择1处非战斗节点,再随机指定2处非战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "光芒",
|
||||
"effect": "随机指定3处非战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "大地",
|
||||
"effect": "选择所有非战斗节点"
|
||||
},
|
||||
{
|
||||
"name": "源石",
|
||||
"effect": "选择1处任意节点"
|
||||
},
|
||||
{
|
||||
"name": "乔木",
|
||||
"effect": "选择1处有纵向通路的节点"
|
||||
},
|
||||
{
|
||||
"name": "砂石",
|
||||
"effect": "随机指定2处有纵向通路的节点"
|
||||
},
|
||||
{
|
||||
"name": "灌木",
|
||||
"effect": "选择所有右侧1列内的节点"
|
||||
},
|
||||
{
|
||||
"name": "兽类",
|
||||
"effect": "选择1处任意节点,再随机指定2处任意节点"
|
||||
},
|
||||
{
|
||||
"name": "人类",
|
||||
"effect": "选择1处节点和它前后相连的所有节点"
|
||||
},
|
||||
{
|
||||
"name": "伤痕",
|
||||
"effect": "选择1处右侧邻近的节点,只能和“空无”组合"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "本因",
|
||||
"ciphertextBoard": [
|
||||
{
|
||||
"name": "歌唱",
|
||||
"effect": "我方在此战斗时攻击速度+50 。协语:场上出现斗志昂扬无人机"
|
||||
},
|
||||
{
|
||||
"name": "沉默",
|
||||
"effect": "我方在此战斗时最大生命+50% 。协语:场上出现友方盾卫"
|
||||
},
|
||||
{
|
||||
"name": "朗诵",
|
||||
"effect": "经过后回复4目标生命 。协语:立即提升2目标生命上限"
|
||||
},
|
||||
{
|
||||
"name": "辩论",
|
||||
"effect": "在此战斗时再部署时间-30% 。协语:1名精英干员临时加入编队"
|
||||
},
|
||||
{
|
||||
"name": "慰藉",
|
||||
"effect": "经过此处后获得2希望 。协语:额外获得2希望"
|
||||
},
|
||||
{
|
||||
"name": "告解",
|
||||
"effect": "经过此处后回复1目标生命 。协语:获得1个战斗类收藏品"
|
||||
},
|
||||
{
|
||||
"name": "喜悦",
|
||||
"effect": "经过后获得8源石锭 。协语:获得2希望"
|
||||
},
|
||||
{
|
||||
"name": "惊讶",
|
||||
"effect": "变为诡意行商 。协语:商品售价-50%"
|
||||
},
|
||||
{
|
||||
"name": "愤怒",
|
||||
"effect": "此处招募时必出现4或5星临时招募 。协语:出现6星临时招募"
|
||||
},
|
||||
{
|
||||
"name": "疑惑",
|
||||
"effect": "变为失与得 。协语:降低的坍缩值变为2点"
|
||||
},
|
||||
{
|
||||
"name": "憧憬",
|
||||
"effect": "此处获得的源石锭变为2倍 。协语:目标生命、希望也变为2倍"
|
||||
},
|
||||
{
|
||||
"name": "爱恋",
|
||||
"effect": "变为不期而遇 。协语:变为得偿所愿"
|
||||
},
|
||||
{
|
||||
"name": "巡视",
|
||||
"effect": "接近时对其全面勘察,降低的坍缩值变为2点 。协语:降低的坍缩值变为3点"
|
||||
},
|
||||
{
|
||||
"name": "筑巢",
|
||||
"effect": "经过后获得2护盾值 。协语:立即提升2目标生命上限"
|
||||
},
|
||||
{
|
||||
"name": "捕猎",
|
||||
"effect": "变为紧急作战 。协语:经过后回复2目标生命"
|
||||
},
|
||||
{
|
||||
"name": "掠夺",
|
||||
"effect": "经过后获得1源石锭、希望、护盾值 。协语:获得1抗干扰指数"
|
||||
},
|
||||
{
|
||||
"name": "繁衍",
|
||||
"effect": "变为先行一步 。协语:经过后获得2希望"
|
||||
},
|
||||
{
|
||||
"name": "迁徙",
|
||||
"effect": "经过后获得1抗干扰指数 。协语:变为树篱之途,且抗干扰指数升至上限"
|
||||
},
|
||||
{
|
||||
"name": "空无",
|
||||
"effect": "变为木裂前兆,只能和“伤痕”组合"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -61,6 +61,60 @@
|
||||
],
|
||||
"maxTimes": 50
|
||||
},
|
||||
"SlowlySwipeToTheUp": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "Swipe",
|
||||
"postDelay": 200,
|
||||
"specificRect": [
|
||||
600,
|
||||
510,
|
||||
100,
|
||||
100
|
||||
],
|
||||
"rectMove": [
|
||||
600,
|
||||
0,
|
||||
100,
|
||||
100
|
||||
],
|
||||
"specialParams": [
|
||||
200,
|
||||
1,
|
||||
2,
|
||||
0
|
||||
],
|
||||
"next": [
|
||||
"#next"
|
||||
],
|
||||
"maxTimes": 50
|
||||
},
|
||||
"SlowlySwipeToTheDown": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "Swipe",
|
||||
"postDelay": 200,
|
||||
"specificRect": [
|
||||
600,
|
||||
145,
|
||||
100,
|
||||
100
|
||||
],
|
||||
"rectMove": [
|
||||
600,
|
||||
610,
|
||||
100,
|
||||
100
|
||||
],
|
||||
"specialParams": [
|
||||
200,
|
||||
1,
|
||||
2,
|
||||
0
|
||||
],
|
||||
"next": [
|
||||
"#next"
|
||||
],
|
||||
"maxTimes": 50
|
||||
},
|
||||
"SwipeToTheLeft": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "Swipe",
|
||||
@@ -9881,6 +9935,43 @@
|
||||
47
|
||||
]
|
||||
},
|
||||
"RoguelikeCiphertextBoardSlowlySwipeToTheUp": {
|
||||
"baseTask": "SlowlySwipeToTheUp",
|
||||
"specificRect": [
|
||||
180,
|
||||
580,
|
||||
20,
|
||||
20
|
||||
],
|
||||
"rectMove": [
|
||||
180,
|
||||
110,
|
||||
20,
|
||||
20
|
||||
],
|
||||
"specialParams": [
|
||||
200,
|
||||
1,
|
||||
2,
|
||||
0
|
||||
],
|
||||
"postDelay": 500
|
||||
},
|
||||
"RoguelikeCiphertextBoardSwipeToTheDown": {
|
||||
"baseTask": "SwipeToTheDown",
|
||||
"specificRect": [
|
||||
180,
|
||||
110,
|
||||
20,
|
||||
20
|
||||
],
|
||||
"rectMove": [
|
||||
180,
|
||||
570,
|
||||
20,
|
||||
20
|
||||
]
|
||||
},
|
||||
"RoguelikeControlTaskPlugin-ExitThenStop": {
|
||||
"Doc": "本任务注册了插件 RoguelikeControlTaskPlugin",
|
||||
"algorithm": "JustReturn"
|
||||
@@ -13291,6 +13382,195 @@
|
||||
"Sami@Roguelike@ChooseOperConfirm#next"
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoard": {
|
||||
"cache": false,
|
||||
"action": "ClickSelf",
|
||||
"roi": [
|
||||
639,
|
||||
599,
|
||||
299,
|
||||
121
|
||||
],
|
||||
"postDelay": 2000
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardBack": {
|
||||
"action": "ClickSelf",
|
||||
"roi": [
|
||||
0,
|
||||
0,
|
||||
146,
|
||||
144
|
||||
],
|
||||
"postDelay": 2000
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardGain": {
|
||||
"doc": "本任务注册插件RoguelikeCiphertextBoardGain",
|
||||
"template": "Sami@Roguelike@CiphertextBoardGain",
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
611,
|
||||
496,
|
||||
60,
|
||||
51
|
||||
],
|
||||
"postDelay": 500,
|
||||
"roi": [
|
||||
333,
|
||||
201,
|
||||
676,
|
||||
307
|
||||
],
|
||||
"maskRange": [
|
||||
1,
|
||||
255
|
||||
],
|
||||
"next": [
|
||||
"Sami@Roguelike@CiphertextBoardGain",
|
||||
"Sami@Roguelike@SquadConfirm#next"
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardGainOcr": {
|
||||
"algorithm": "OcrDetect",
|
||||
"action": "DoNothing",
|
||||
"cache": false,
|
||||
"roi": [
|
||||
584,
|
||||
261,
|
||||
315,
|
||||
46
|
||||
],
|
||||
"text": [
|
||||
"黜人",
|
||||
"猎手",
|
||||
"战士",
|
||||
"萨满",
|
||||
"雪祀",
|
||||
"英雄",
|
||||
"树冠",
|
||||
"水面",
|
||||
"眼睛",
|
||||
"拱门",
|
||||
"光芒",
|
||||
"大地",
|
||||
"源石",
|
||||
"乔木",
|
||||
"砂石",
|
||||
"灌木",
|
||||
"兽类",
|
||||
"人类",
|
||||
"伤痕",
|
||||
"歌唱",
|
||||
"沉默",
|
||||
"朗诵",
|
||||
"辩论",
|
||||
"慰藉",
|
||||
"告解",
|
||||
"喜悦",
|
||||
"惊讶",
|
||||
"愤怒",
|
||||
"疑惑",
|
||||
"憧憬",
|
||||
"爱恋",
|
||||
"巡视",
|
||||
"筑巢",
|
||||
"捕猎",
|
||||
"繁衍",
|
||||
"掠夺",
|
||||
"迁徙",
|
||||
"空无"
|
||||
],
|
||||
"ocrReplace": [
|
||||
[
|
||||
"黜",
|
||||
"黜人"
|
||||
]
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardGainOcrAfterCombat": {
|
||||
"baseTask": "Sami@Roguelike@CiphertextBoardGainOcr",
|
||||
"roi": [
|
||||
44,
|
||||
309,
|
||||
1195,
|
||||
124
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardUseConfirm": {
|
||||
"algorithm": "OcrDetect",
|
||||
"action": "ClickSelf",
|
||||
"text": [
|
||||
"开始宣告"
|
||||
],
|
||||
"roi": [
|
||||
953,
|
||||
597,
|
||||
302,
|
||||
113
|
||||
],
|
||||
"postDelay": 2000
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardUseOcr": {
|
||||
"algorithm": "OcrDetect",
|
||||
"action": "DoNothing",
|
||||
"cache": false,
|
||||
"text": [
|
||||
"布局"
|
||||
],
|
||||
"roi": [
|
||||
38,
|
||||
64,
|
||||
85,
|
||||
518
|
||||
],
|
||||
"rectMove": [
|
||||
150,
|
||||
-50,
|
||||
50,
|
||||
5
|
||||
],
|
||||
"specificRect_Doc": "x拿来当文字灰度二值化下限用",
|
||||
"specificRect": [
|
||||
170,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@CiphertextBoardUseOnStage": {
|
||||
"cache": false,
|
||||
"doc": "缺紧急战斗和先行一步",
|
||||
"action": "ClickSelf",
|
||||
"template": [
|
||||
"Sami@Roguelike@CiphertextBoardUseOnGambling.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnWindAndRain.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnEmergencyTransportation.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnCombatDps.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnMysteriousPresage.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnEmergencyDps.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnDreadfulFoe-5.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnFerociousPresage.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnEncounter.png",
|
||||
"Sami@Roguelike@CiphertextBoardUseOnTrader.png"
|
||||
],
|
||||
"templThreshold": [
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7
|
||||
],
|
||||
"roi": [
|
||||
429,
|
||||
111,
|
||||
844,
|
||||
477
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@CloseCollection": {
|
||||
"next": [
|
||||
"Sami@Roguelike@LastReward",
|
||||
@@ -13429,31 +13709,6 @@
|
||||
},
|
||||
"Sami@Roguelike@GamePassSkip2": {},
|
||||
"Sami@Roguelike@GamePassTheEndConfirm": {},
|
||||
"Sami@Roguelike@GetCiphertextBoard": {
|
||||
"template": "Sami@Roguelike@GetCiphertextBoard",
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
611,
|
||||
496,
|
||||
60,
|
||||
51
|
||||
],
|
||||
"postDelay": 500,
|
||||
"roi": [
|
||||
333,
|
||||
201,
|
||||
676,
|
||||
307
|
||||
],
|
||||
"maskRange": [
|
||||
1,
|
||||
255
|
||||
],
|
||||
"next": [
|
||||
"Sami@Roguelike@GetCiphertextBoard",
|
||||
"Sami@Roguelike@SquadConfirm#next"
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@GetDrop1": {},
|
||||
"Sami@Roguelike@GetDrop2": {},
|
||||
"Sami@Roguelike@GetDrop3": {},
|
||||
@@ -13487,14 +13742,14 @@
|
||||
"Doc": "密文板三选一",
|
||||
"template": "Sami@Roguelike@GetDropSelectReward2.png",
|
||||
"cache": false,
|
||||
"action": "ClickSelf",
|
||||
"action": "DoNothing",
|
||||
"roi": [
|
||||
0,
|
||||
420,
|
||||
1280,
|
||||
175
|
||||
],
|
||||
"postDelay": 1000,
|
||||
"postDelay": 800,
|
||||
"next": [
|
||||
"Sami@Roguelike@GetDropSelectReward2",
|
||||
"Sami@Roguelike@ChooseOperFlag",
|
||||
@@ -13599,7 +13854,7 @@
|
||||
"Sami@Roguelike@DialogSkip",
|
||||
"Sami@Roguelike@Stages#next",
|
||||
"Sami@Roguelike@MapObject",
|
||||
"Sami@Roguelike@GetCiphertextBoard"
|
||||
"Sami@Roguelike@CiphertextBoardGain"
|
||||
]
|
||||
},
|
||||
"Sami@Roguelike@SquadDefault": {},
|
||||
@@ -14135,18 +14390,18 @@
|
||||
"Sami@Roguelike@StageVerticalSafeHouseAI6",
|
||||
"Sami@Roguelike@StageVerticalBoons",
|
||||
"Sami@Roguelike@StageVerticalBoonsAI6",
|
||||
"Sami@Roguelike@StageVerticalEncounter",
|
||||
"Sami@Roguelike@StageVerticalEncounterAI6",
|
||||
"Sami@Roguelike@StageVerticalTrader",
|
||||
"Sami@Roguelike@StageVerticalTraderAI6",
|
||||
"Sami@Roguelike@StageSafeHouse",
|
||||
"Sami@Roguelike@StageSafeHouseAI6",
|
||||
"Sami@Roguelike@StageBoons",
|
||||
"Sami@Roguelike@StageBoonsAI6",
|
||||
"Sami@Roguelike@StageEncounter",
|
||||
"Sami@Roguelike@StageEncounterAI6",
|
||||
"Sami@Roguelike@StageTrader",
|
||||
"Sami@Roguelike@StageTraderAI6",
|
||||
"Sami@Roguelike@StageEncounter",
|
||||
"Sami@Roguelike@StageEncounterAI6",
|
||||
"Sami@Roguelike@StageVerticalEncounter",
|
||||
"Sami@Roguelike@StageVerticalEncounterAI6",
|
||||
"Sami@Roguelike@StageVerticalProphecy",
|
||||
"Sami@Roguelike@StageVerticalProphecyAI6",
|
||||
"Sami@Roguelike@StageWindAndRain",
|
||||
|
||||
BIN
resource/template/Sami@Roguelike@CiphertextBoard.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
resource/template/Sami@Roguelike@CiphertextBoardBack.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
BIN
resource/template/Sami@Roguelike@CiphertextBoardUseOnTrader.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 7.2 KiB |
@@ -15,6 +15,7 @@
|
||||
#include "Miscellaneous/StageDropsConfig.h"
|
||||
#include "Miscellaneous/TilePack.h"
|
||||
#include "OnnxSessions.h"
|
||||
#include "Roguelike/RoguelikeCiphertextBoardConfig.h"
|
||||
#include "Roguelike/RoguelikeCopilotConfig.h"
|
||||
#include "Roguelike/RoguelikeRecruitConfig.h"
|
||||
#include "Roguelike/RoguelikeShoppingConfig.h"
|
||||
@@ -184,6 +185,8 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path)
|
||||
LoadResourceAndCheckRet(RoguelikeStageEncounterConfig, "roguelike"_p / "Mizuki"_p / "encounter_for_deposit.json"_p);
|
||||
LoadResourceAndCheckRet(RoguelikeStageEncounterConfig, "roguelike"_p / "Sami"_p / "encounter_for_deposit.json"_p);
|
||||
|
||||
LoadResourceAndCheckRet(RoguelikeCiphertextBoardConfig, "roguelike"_p / "Sami"_p / "ciphertext_board.json"_p);
|
||||
|
||||
#undef LoadTemplByConfigAndCheckRet
|
||||
#undef LoadResourceAndCheckRet
|
||||
#undef LoadCacheWithoutRet
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "RoguelikeCiphertextBoardConfig.h"
|
||||
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardConfig::parse(const json::value& json)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
const std::string theme = json.at("theme").as_string();
|
||||
m_ciphertext_board_combination.erase(theme);
|
||||
|
||||
for (const auto& combination_json : json.at("groups").as_array()) {
|
||||
|
||||
RoguelikeCiphertextBoardCombination combination;
|
||||
combination.usage = combination_json.get("usage", "none");
|
||||
|
||||
for (const auto& pairs : combination_json.at("pairs").as_array()) {
|
||||
CiphertextBoardPair pair;
|
||||
const json::array& up_boards = pairs.at("up").as_array();
|
||||
for (const auto& board : up_boards) {
|
||||
pair.up_board.emplace_back(board.as_string());
|
||||
}
|
||||
const json::array& down_boards = pairs.at("down").as_array();
|
||||
for (const auto& board : down_boards) {
|
||||
pair.down_board.emplace_back(board.as_string());
|
||||
}
|
||||
combination.pairs.emplace_back(pair);
|
||||
}
|
||||
m_ciphertext_board_combination[theme].emplace_back(std::move(combination));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "Config/AbstractConfig.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common/AsstBattleDef.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
// 板子组合
|
||||
struct CiphertextBoardPair
|
||||
{
|
||||
std::vector<std::string> up_board; // 上板子
|
||||
std::vector<std::string> down_board; // 下板子
|
||||
};
|
||||
struct RoguelikeCiphertextBoardCombination
|
||||
{
|
||||
std::string usage; // 适用的节点类型和用法
|
||||
std::vector<CiphertextBoardPair> pairs; // 适用的板子组合
|
||||
};
|
||||
|
||||
class RoguelikeCiphertextBoardConfig final : public SingletonHolder<RoguelikeCiphertextBoardConfig>,
|
||||
public AbstractConfig
|
||||
{
|
||||
public:
|
||||
virtual ~RoguelikeCiphertextBoardConfig() override = default;
|
||||
|
||||
const auto& get_combination(const std::string& theme) const noexcept
|
||||
{
|
||||
return m_ciphertext_board_combination.at(theme);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool parse(const json::value& json) override;
|
||||
|
||||
std::unordered_map<std::string, std::vector<RoguelikeCiphertextBoardCombination>>
|
||||
m_ciphertext_board_combination;
|
||||
};
|
||||
|
||||
inline static auto& RoguelikeCiphertextBoard = RoguelikeCiphertextBoardConfig::get_instance();
|
||||
}
|
||||
@@ -48,12 +48,14 @@
|
||||
<ClInclude Include="Config\Miscellaneous\OcrConfig.h" />
|
||||
<ClInclude Include="Config\Miscellaneous\SSSCopilotConfig.h" />
|
||||
<ClInclude Include="Config\OnnxSessions.h" />
|
||||
<ClInclude Include="Config\Roguelike\RoguelikeCiphertextBoardConfig.h" />
|
||||
<ClInclude Include="Controller\adb-lite\client.hpp" />
|
||||
<ClInclude Include="Controller\adb-lite\protocol.hpp" />
|
||||
<ClInclude Include="Controller\Controller.h" />
|
||||
<ClInclude Include="Controller\ControllerAPI.h" />
|
||||
<ClInclude Include="Controller\ControllerFactory.h" />
|
||||
<ClInclude Include="Controller\ControlScaleProxy.h" />
|
||||
<ClCompile Include="Config\Roguelike\RoguelikeCiphertextBoardConfig.cpp" />
|
||||
<ClCompile Include="Controller\MaaThriftController.h" />
|
||||
<ClInclude Include="Controller\MaatouchController.h" />
|
||||
<ClInclude Include="Controller\MinitouchController.h" />
|
||||
@@ -86,6 +88,8 @@
|
||||
<ClInclude Include="Task\BattleHelper.h" />
|
||||
<ClInclude Include="Task\Interface\SingleStepTask.h" />
|
||||
<ClInclude Include="Task\Interface\SSSCopilotTask.h" />
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeCiphertextBoardGainTaskPlugin.h" />
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeCiphertextBoardUseTaskPlugin.h" />
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeConfig.h" />
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeDifficultySelectionTaskPlugin.h" />
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeLastRewardTaskPlugin.h" />
|
||||
@@ -254,6 +258,8 @@
|
||||
<ClCompile Include="Task\BattleHelper.cpp" />
|
||||
<ClCompile Include="Task\Interface\SingleStepTask.cpp" />
|
||||
<ClCompile Include="Task\Interface\SSSCopilotTask.cpp" />
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeCiphertextBoardGainTaskPlugin.cpp" />
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeCiphertextBoardUseTaskPlugin.cpp" />
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeConfig.cpp" />
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeDifficultySelectionTaskPlugin.cpp" />
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeLastRewardTaskPlugin.cpp" />
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
<ClInclude Include="Config\TemplResource.h">
|
||||
<Filter>Source\Resource</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Roguelike\RoguelikeCiphertextBoardConfig.h">
|
||||
<Filter>Source\Resource\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Roguelike\RoguelikeCopilotConfig.h">
|
||||
<Filter>Source\Resource\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
@@ -441,6 +444,12 @@
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeBattleTaskPlugin.h">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeCiphertextBoardGainTaskPlugin.h">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeCiphertextBoardUseTaskPlugin.h">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Task\Roguelike\RoguelikeConfig.h">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClInclude>
|
||||
@@ -731,6 +740,9 @@
|
||||
<ClCompile Include="Config\TemplResource.cpp">
|
||||
<Filter>Source\Resource</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Roguelike\RoguelikeCiphertextBoardConfig.cpp">
|
||||
<Filter>Source\Resource\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Roguelike\RoguelikeCopilotConfig.cpp">
|
||||
<Filter>Source\Resource\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
@@ -905,6 +917,12 @@
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeBattleTaskPlugin.cpp">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeCiphertextBoardGainTaskPlugin.cpp">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeCiphertextBoardUseTaskPlugin.cpp">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Task\Roguelike\RoguelikeConfig.cpp">
|
||||
<Filter>Source\Task\Roguelike</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace asst
|
||||
static inline const std::string RoguelikeMode = "RoguelikeMode";
|
||||
static inline const std::string RoguelikeDifficulty = "RoguelikeDifficulty";
|
||||
|
||||
static inline const std::string RoguelikeCiphertextBoardOverview = "RoguelikeCiphertextBoardOverview";
|
||||
|
||||
static inline const std::string ProcessTaskLastTimePrefix = "#LastTime#";
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include "Task/Roguelike/RoguelikeSkillSelectionTaskPlugin.h"
|
||||
#include "Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h"
|
||||
#include "Task/Roguelike/RoguelikeStrategyChangeTaskPlugin.h"
|
||||
|
||||
#include "Task/Roguelike/RoguelikeCiphertextBoardGainTaskPlugin.h"
|
||||
#include "Task/Roguelike/RoguelikeCiphertextBoardUseTaskPlugin.h"
|
||||
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, Assistant* inst)
|
||||
@@ -49,6 +53,10 @@ asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, Assistant* inst
|
||||
m_difficulty_selection_plugin_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeDifficultySelectionTaskPlugin>();
|
||||
m_strategy_change_plugin_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeStrategyChangeTaskPlugin>();
|
||||
|
||||
m_ciphertext_board_gain_plugin_ptr =
|
||||
m_roguelike_task_ptr->register_plugin<RoguelikeCiphertextBoardGainTaskPlugin>();
|
||||
m_ciphertext_board_use_plugin_ptr = m_roguelike_task_ptr->register_plugin<RoguelikeCiphertextBoardUseTaskPlugin>();
|
||||
|
||||
// 这个任务如果卡住会放弃当前的肉鸽并重新开始,所以多添加一点。先这样凑合用
|
||||
for (int i = 0; i != 100; ++i) {
|
||||
m_subtasks.emplace_back(m_roguelike_task_ptr);
|
||||
@@ -77,6 +85,9 @@ bool asst::RoguelikeTask::set_params(const json::value& params)
|
||||
}
|
||||
}
|
||||
|
||||
m_ciphertext_board_gain_plugin_ptr->set_roguelike_theme(theme);
|
||||
m_ciphertext_board_use_plugin_ptr->set_roguelike_theme(theme);
|
||||
|
||||
m_roguelike_task_ptr->set_tasks({ theme + "@Roguelike@Begin" });
|
||||
|
||||
// 0 - 刷经验,尽可能稳定地打更多层数,不期而遇采用激进策略
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace asst
|
||||
class RoguelikeStageEncounterTaskPlugin;
|
||||
class RoguelikeStrategyChangeTaskPlugin;
|
||||
|
||||
class RoguelikeCiphertextBoardGainTaskPlugin;
|
||||
class RoguelikeCiphertextBoardUseTaskPlugin;
|
||||
|
||||
class RoguelikeTask : public InterfaceTask
|
||||
{
|
||||
public:
|
||||
@@ -45,5 +48,8 @@ namespace asst
|
||||
std::shared_ptr<RoguelikeShoppingTaskPlugin> m_shopping_plugin_ptr = nullptr;
|
||||
std::shared_ptr<RoguelikeStageEncounterTaskPlugin> m_stage_encounter_plugin_ptr = nullptr;
|
||||
std::shared_ptr<RoguelikeStrategyChangeTaskPlugin> m_strategy_change_plugin_ptr = nullptr;
|
||||
|
||||
std::shared_ptr<RoguelikeCiphertextBoardGainTaskPlugin> m_ciphertext_board_gain_plugin_ptr = nullptr;
|
||||
std::shared_ptr<RoguelikeCiphertextBoardUseTaskPlugin> m_ciphertext_board_use_plugin_ptr = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "RoguelikeCiphertextBoardGainTaskPlugin.h"
|
||||
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/OCRer.h"
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardGainTaskPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_roguelike_theme.empty()) {
|
||||
Log.error("Roguelike name doesn't exist!");
|
||||
return false;
|
||||
}
|
||||
if (m_roguelike_theme != "Sami") {
|
||||
return false;
|
||||
}
|
||||
const std::string roguelike_name = m_roguelike_theme + "@";
|
||||
const std::string& task = details.get("details", "task", "");
|
||||
std::string_view task_view = task;
|
||||
|
||||
if (task_view.starts_with(roguelike_name)) {
|
||||
task_view.remove_prefix(roguelike_name.length());
|
||||
}
|
||||
if (task_view == "Roguelike@CiphertextBoardGain") {
|
||||
m_ocr_after_combat = false;
|
||||
return true;
|
||||
}
|
||||
if (task_view == "Roguelike@StageEncounterSpecialClose") {
|
||||
m_ocr_after_combat = false;
|
||||
return true;
|
||||
}
|
||||
if (task_view == "Roguelike@GetDropSelectReward2") {
|
||||
m_ocr_after_combat = true;
|
||||
return true;
|
||||
}
|
||||
/* 可能是没点科技树会单独掉一个密文板,很快能点出来,暂时不做识别
|
||||
if (task_view == "Roguelike@GetDrop2") {
|
||||
m_ocr_after_combat = true;
|
||||
return true;
|
||||
}*/
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardGainTaskPlugin::_run()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::string theme = m_roguelike_theme;
|
||||
std::string mode = status()->get_properties(Status::RoguelikeMode).value();
|
||||
|
||||
auto image = ctrler()->get_image();
|
||||
|
||||
OCRer analyzer(image);
|
||||
std::string task_name = m_ocr_after_combat ? theme + "@Roguelike@CiphertextBoardGainOcrAfterCombat"
|
||||
: theme + "@Roguelike@CiphertextBoardGainOcr";
|
||||
analyzer.set_task_info(task_name);
|
||||
|
||||
if (!analyzer.analyze()) {
|
||||
return false;
|
||||
}
|
||||
std::string ciphertext_board = analyzer.get_result().front().text;
|
||||
|
||||
std::string overview_str =
|
||||
status()->get_str(Status::RoguelikeCiphertextBoardOverview).value_or(json::value().to_string());
|
||||
json::value overview_json = json::parse(overview_str).value_or(json::value());
|
||||
auto& overview = overview_json.as_array();
|
||||
// 把ciphertext_board存到overview里
|
||||
overview.emplace_back(ciphertext_board);
|
||||
status()->set_str(Status::RoguelikeCiphertextBoardOverview, overview.to_string());
|
||||
|
||||
if (m_ocr_after_combat) {
|
||||
ctrler()->click(analyzer.get_result().front().rect);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "RoguelikeConfig.h"
|
||||
#include "Task/AbstractTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class RoguelikeCiphertextBoardGainTaskPlugin : public AbstractTaskPlugin, public RoguelikeConfig
|
||||
{
|
||||
public:
|
||||
using AbstractTaskPlugin::AbstractTaskPlugin;
|
||||
virtual ~RoguelikeCiphertextBoardGainTaskPlugin() override = default;
|
||||
|
||||
public:
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
private:
|
||||
// 战斗后识别密文板
|
||||
mutable bool m_ocr_after_combat = false;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
#include "RoguelikeCiphertextBoardUseTaskPlugin.h"
|
||||
|
||||
#include "Config/Roguelike/RoguelikeCiphertextBoardConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Vision/OCRer.h"
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardUseTaskPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_roguelike_theme.empty()) {
|
||||
Log.error("Roguelike name doesn't exist!");
|
||||
return false;
|
||||
}
|
||||
if (m_roguelike_theme != "Sami") {
|
||||
return false;
|
||||
}
|
||||
std::string mode = status()->get_properties(Status::RoguelikeMode).value();
|
||||
std::string task_name_pre = m_roguelike_theme + "@Roguelike@Stage";
|
||||
const std::string& task = details.get("details", "task", "");
|
||||
std::string_view task_view = task;
|
||||
|
||||
if (task_view.starts_with(task_name_pre)) {
|
||||
task_view.remove_prefix(task_name_pre.length());
|
||||
}
|
||||
// 不知道是不是不对纵向节点用比较好,先写上
|
||||
task_name_pre = "task_name_pre";
|
||||
if (task_view.starts_with("Vertical")) {
|
||||
task_view.remove_prefix(task_name_pre.length());
|
||||
}
|
||||
std::string task_name_suf = "AI6";
|
||||
if (task_view.ends_with(task_name_suf)) {
|
||||
task_view.remove_suffix(task_name_suf.length());
|
||||
}
|
||||
if (task_view == "CombatDps" || task_view == "EmergencyDps" || task_view == "FerociousPresage") {
|
||||
if (mode == "1" || mode == "4") {
|
||||
m_stage = "SkipBattle";
|
||||
}
|
||||
else if (mode == "0") {
|
||||
m_stage = "Battle";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (task_view == "DreadfulFoe-5" && mode == "0") {
|
||||
m_stage = "Boss";
|
||||
return true;
|
||||
}
|
||||
if (task_view == "Trader" && mode == "0") {
|
||||
m_stage = "Trader";
|
||||
return true;
|
||||
}
|
||||
if (task_view == "Encounter" && mode == "0") {
|
||||
m_stage = "Encounter";
|
||||
return true;
|
||||
}
|
||||
if ((task_view == "Gambling" || task_view == "EmergencyTransportation" || task_view == "WindAndRain") &&
|
||||
mode == "0") {
|
||||
m_stage = "Gambling";
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardUseTaskPlugin::_run()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::string theme = m_roguelike_theme;
|
||||
|
||||
std::vector<RoguelikeCiphertextBoardCombination> combination =
|
||||
RoguelikeCiphertextBoard.get_combination(m_roguelike_theme);
|
||||
|
||||
std::string overview_str =
|
||||
status()->get_str(Status::RoguelikeCiphertextBoardOverview).value_or(json::value().to_string());
|
||||
json::value overview_json = json::parse(overview_str).value_or(json::value());
|
||||
m_all_boards = overview_json.as_array();
|
||||
Log.debug(m_all_boards);
|
||||
for (const auto& usage : combination) {
|
||||
if (need_exit()) {
|
||||
return false;
|
||||
}
|
||||
if (m_stage == usage.usage) {
|
||||
// 用到没得用为止
|
||||
while (search_enable_pair(usage) && !need_exit()) {
|
||||
Log.info("Use board pairs");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardUseTaskPlugin::search_enable_pair(const auto& usage)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
for (const auto& pair : usage.pairs) {
|
||||
// 遍历上板子
|
||||
for (const auto& up_board : pair.up_board) {
|
||||
// 遍历下板子
|
||||
for (const auto& down_board : pair.down_board) {
|
||||
if (board_pair(up_board, down_board)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardUseTaskPlugin::board_pair(const std::string& up_board, const std::string& down_board)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
auto iter_up = std::find(m_all_boards.begin(), m_all_boards.end(), up_board);
|
||||
auto iter_down = std::find(m_all_boards.begin(), m_all_boards.end(), down_board);
|
||||
// 如果两个板子同时存在m_all_boards中
|
||||
if (iter_up != m_all_boards.end() && iter_down != m_all_boards.end()) {
|
||||
if (use_board(up_board, down_board)) {
|
||||
// 用完删除上板子和下板子
|
||||
m_all_boards.erase(iter_up);
|
||||
iter_down = std::find(m_all_boards.begin(), m_all_boards.end(), down_board);
|
||||
m_all_boards.erase(iter_down);
|
||||
status()->set_str(Status::RoguelikeCiphertextBoardOverview, m_all_boards.to_string());
|
||||
Log.debug("Use board pairs");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardUseTaskPlugin::use_board(const std::string& up_board, const std::string& down_board)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
if (ProcessTask(*this, { m_roguelike_theme + "@Roguelike@CiphertextBoard" }).run()) {
|
||||
swipe_to_top();
|
||||
// todo:插入一个更新密文板overview
|
||||
if (search_and_click_board(up_board)) {
|
||||
search_and_click_board(down_board);
|
||||
// 点击节点位置,todo:根据坐标换算位置
|
||||
if (m_stage == "Boss") {
|
||||
// 滑到最右边,可能这里的逻辑需要扩充为找不到点就往右划,暂时先这么糊着,出现这种情况再写
|
||||
ProcessTask(*this, { "SwipeToTheLeft" }).run();
|
||||
}
|
||||
ProcessTask(*this, { m_roguelike_theme + "@Roguelike@CiphertextBoardUseOnStage" }).run();
|
||||
if (ProcessTask(*this, { m_roguelike_theme + "@Roguelike@CiphertextBoardUseConfirm" }).run()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ProcessTask(*this, { m_roguelike_theme + "@Roguelike@CiphertextBoardBack" }).run();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asst::RoguelikeCiphertextBoardUseTaskPlugin::search_and_click_board(const std::string& board)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
while (!need_exit()) {
|
||||
OCRer analyzer(ctrler()->get_image());
|
||||
std::string task_name = m_roguelike_theme + "@Roguelike@CiphertextBoardUseOcr";
|
||||
analyzer.set_task_info(task_name);
|
||||
analyzer.set_required({ board });
|
||||
if (!analyzer.analyze()) {
|
||||
// 往上滑
|
||||
slowly_swipe(true);
|
||||
}
|
||||
else {
|
||||
ctrler()->click(analyzer.get_result().front().rect.move(Task.get(task_name)->rect_move));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void asst::RoguelikeCiphertextBoardUseTaskPlugin::swipe_to_top()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
// 找到布局"就到了最上面
|
||||
while (!need_exit()) {
|
||||
OCRer analyzer(ctrler()->get_image());
|
||||
analyzer.set_task_info(m_roguelike_theme + "@Roguelike@CiphertextBoardUseOcr");
|
||||
if (analyzer.analyze()) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// 往下滑
|
||||
ProcessTask(*this, { "RoguelikeCiphertextBoardSwipeToTheDown" }).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void asst::RoguelikeCiphertextBoardUseTaskPlugin::slowly_swipe(bool to_up, int swipe_dist)
|
||||
{
|
||||
std::string swipe_task_name =
|
||||
to_up ? "RoguelikeCiphertextBoardSlowlySwipeToTheUp" : "RoguelikeCiphertextBoardSwipeToTheDown";
|
||||
if (!ControlFeat::support(ctrler()->support_features(),
|
||||
ControlFeat::PRECISE_SWIPE)) { // 不能精准滑动时不使用 swipe_dist 参数
|
||||
ProcessTask(*this, { swipe_task_name }).run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!to_up) swipe_dist = -swipe_dist;
|
||||
auto swipe_task = Task.get(swipe_task_name);
|
||||
const Rect& StartPoint = swipe_task->specific_rect;
|
||||
ctrler()->swipe(StartPoint,
|
||||
{ StartPoint.x + swipe_dist - StartPoint.width, StartPoint.y, StartPoint.width, StartPoint.height },
|
||||
swipe_task->special_params.empty() ? 0 : swipe_task->special_params.at(0),
|
||||
(swipe_task->special_params.size() < 2) ? false : swipe_task->special_params.at(1),
|
||||
(swipe_task->special_params.size() < 3) ? 1 : swipe_task->special_params.at(2),
|
||||
(swipe_task->special_params.size() < 4) ? 1 : swipe_task->special_params.at(3));
|
||||
sleep(swipe_task->post_delay);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "RoguelikeConfig.h"
|
||||
#include "Task/AbstractTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class RoguelikeCiphertextBoardUseTaskPlugin : public AbstractTaskPlugin, public RoguelikeConfig
|
||||
{
|
||||
public:
|
||||
using AbstractTaskPlugin::AbstractTaskPlugin;
|
||||
virtual ~RoguelikeCiphertextBoardUseTaskPlugin() override = default;
|
||||
|
||||
public:
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
protected:
|
||||
virtual bool _run() override;
|
||||
|
||||
private:
|
||||
// 遍历配置里的组合
|
||||
bool search_enable_pair(const auto& usage);
|
||||
// 查询是否有能使用的板子对
|
||||
bool board_pair(const std::string& up_board, const std::string& down_board);
|
||||
// 使用板子对
|
||||
bool use_board(const std::string& up_board, const std::string& down_board);
|
||||
// 找到并点击指定板子
|
||||
bool search_and_click_board(const std::string& board);
|
||||
// 滑到最上面
|
||||
void swipe_to_top();
|
||||
// 往下滑
|
||||
void slowly_swipe(bool to_down, int swipe_dist = 200);
|
||||
// 节点类型
|
||||
mutable std::string m_stage;
|
||||
mutable json::array m_all_boards;
|
||||
};
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Config/Miscellaneous/BattleDataConfig.h"
|
||||
#include "Config/Roguelike/RoguelikeShoppingConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Controller/Controller.h"
|
||||
#include "Status.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
@@ -104,6 +105,9 @@ bool asst::RoguelikeShoppingTaskPlugin::_run()
|
||||
|
||||
bool bought = false;
|
||||
auto& all_goods = RoguelikeShopping.get_goods(m_roguelike_theme);
|
||||
std::vector<std::string> all_ciphertext_board =
|
||||
m_roguelike_theme == "Sami" ? Task.get<OcrTaskInfo>("Sami@Roguelike@CiphertextBoardGainOcr")->text
|
||||
: std::vector<std::string>();
|
||||
for (const auto& goods : all_goods) {
|
||||
if (need_exit()) {
|
||||
return false;
|
||||
@@ -166,6 +170,19 @@ bool asst::RoguelikeShoppingTaskPlugin::_run()
|
||||
Log.info("Ready to buy", goods.name);
|
||||
ctrler()->click(find_it->rect);
|
||||
bought = true;
|
||||
if (m_roguelike_theme == "Sami") {
|
||||
|
||||
auto iter = std::find(all_ciphertext_board.begin(), all_ciphertext_board.end(), goods.name);
|
||||
if (iter != all_ciphertext_board.end()) {
|
||||
std::string overview_str =
|
||||
status()->get_str(Status::RoguelikeCiphertextBoardOverview).value_or(json::value().to_string());
|
||||
|
||||
auto& overview = json::parse(overview_str).value_or(json::value()).as_array();
|
||||
// 把ciphertext_board存到overview里
|
||||
overview.push_back(goods.name);
|
||||
status()->set_str(Status::RoguelikeCiphertextBoardOverview, overview.to_string());
|
||||
}
|
||||
}
|
||||
if (goods.no_longer_buy) {
|
||||
status()->set_number(Status::RoguelikeTraderNoLongerBuy, 1);
|
||||
}
|
||||
|
||||