diff --git a/resource/global/YoStarEN/resource/template/Phantom@Roguelike@Unknown@StageEncounterOption.png b/resource/global/YoStarEN/resource/template/Phantom@Roguelike@StageEncounterOptionUnknown.png similarity index 100% rename from resource/global/YoStarEN/resource/template/Phantom@Roguelike@Unknown@StageEncounterOption.png rename to resource/global/YoStarEN/resource/template/Phantom@Roguelike@StageEncounterOptionUnknown.png diff --git a/resource/global/YoStarJP/resource/template/Phantom@Roguelike@Unknown@StageEncounterOption.png b/resource/global/YoStarJP/resource/template/Phantom@Roguelike@StageEncounterOptionUnknown.png similarity index 100% rename from resource/global/YoStarJP/resource/template/Phantom@Roguelike@Unknown@StageEncounterOption.png rename to resource/global/YoStarJP/resource/template/Phantom@Roguelike@StageEncounterOptionUnknown.png diff --git a/resource/tasks.json b/resource/tasks.json index 6ed9553a16..d5d5723577 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -2988,7 +2988,7 @@ "RecruitBegin" ] }, - "RecruitBeginLoading": { + "Loading": { "algorithm": "OcrDetect", "action": "DoNothing", "text": [ @@ -3000,7 +3000,10 @@ 600, 300, 120 - ], + ] + }, + "RecruitBeginLoading": { + "baseTask": "Loading", "next": [ "RecruitBeginLoading", "Recruit@Main", @@ -3025,18 +3028,7 @@ ] }, "RecruitFinishLoading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "next": [ "RecruitFinishLoading", "RecruitFinish", @@ -3726,18 +3718,7 @@ ] }, "CreditShop-BuyIt-Loading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "next": [ "CreditShop-Bought", "CreditShop-BuyIt-Loading" @@ -3873,18 +3854,7 @@ ] }, "RecruitLoading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "next": [ "RecruitLoading", "SleepThenStop" @@ -3948,18 +3918,7 @@ ] }, "RecruitConfirmLoading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "next": [ "RecruitConfirmLoading", "RecruitFlag" @@ -3980,14 +3939,6 @@ }, "Infrast@ReturnTo": { "template": "Return.png", - "templThreshold": 0.7, - "roi": [ - 0, - 0, - 180, - 80 - ], - "action": "ClickSelf", "next": [ "Infrast@Main", "InfrastNotification", @@ -4001,13 +3952,6 @@ }, "Infrast@ReturnToConfirm": { "template": "PopupConfirm.png", - "action": "ClickSelf", - "roi": [ - 630, - 400, - 650, - 160 - ], "next": [ "Infrast@Main", "InfrastNotification", @@ -4021,14 +3965,6 @@ }, "Infrast@CloseAnno": { "template": "CloseAnno.png", - "action": "ClickSelf", - "cache": false, - "roi": [ - 1100, - 0, - 180, - 200 - ], "next": [ "Infrast@Main", "InfrastNotification", @@ -4195,18 +4131,7 @@ ] }, "DroneConfirmLoading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "next": [ "DroneConfirmLoading", "DeliverableOrder", @@ -4262,18 +4187,7 @@ ] }, "ReplenishToMaxLoading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "rearDelay": 1000, "next": [ "ReplenishToMaxLoading", @@ -4744,7 +4658,6 @@ }, "InfrastSortByTrustButton": { "action": "ClickSelf", - "template": "InfrastSortByTrustButton.png", "cache": false, "roi": [ 1000, @@ -4756,7 +4669,6 @@ }, "InfrastFilterMenuNotStationed": { "action": "ClickSelf", - "template": "InfrastFilterMenu.png", "cache": false, "roi": [ 1050, @@ -4772,7 +4684,6 @@ }, "InfrastFilterMenuNotStationedButton": { "action": "ClickSelf", - "template": "InfrastFilterMenuNotStationedButton.png", "templThreshold": 0.85, "cache": false, "roi": [ @@ -4788,7 +4699,6 @@ }, "InfrastFilterMenuNotStationedButtonAlreadyClicked": { "action": "DoNothing", - "template": "InfrastFilterMenuNotStationedButtonAlreadyClicked.png", "cache": false, "roi": [ 300, @@ -4848,7 +4758,6 @@ }, "InfrastFilterMenuConfirmButton": { "action": "ClickSelf", - "template": "InfrastFilterMenuConfirmButton.png", "cache": false, "roi": [ 870, @@ -5557,18 +5466,7 @@ ] }, "ClueGiveLoading": { - "algorithm": "OcrDetect", - "action": "DoNothing", - "text": [ - "正在提交", - "反馈至神经" - ], - "roi": [ - 700, - 600, - 300, - 120 - ], + "baseTask": "Loading", "next": [ "ClueGiveLoading", "SelectClue", @@ -5881,7 +5779,9 @@ ], "rearDelay": 500 }, - "BattleQuickFormationRole-All": { + "BattleQuickFormationRole": { + "Doc": "base_task", + "template": "empty.png", "action": "ClickSelf", "roi": [ 1163, @@ -5896,125 +5796,32 @@ ], "rearDelay": 500 }, + "BattleQuickFormationRole-All": { + "baseTask": "BattleQuickFormationRole" + }, "BattleQuickFormationRole-Pioneer": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Warrior": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Tank": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Caster": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Medic": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Sniper": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Special": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormationRole-Support": { - "action": "ClickSelf", - "roi": [ - 1155, - 41, - 125, - 679 - ], - "templThreshold": 0.7, - "maskRange": [ - 100, - 255 - ], - "rearDelay": 500 + "baseTask": "BattleQuickFormationRole" }, "BattleQuickFormation-OperNameFlag": { "templThreshold": 0.95, @@ -6106,7 +5913,9 @@ "action": "ClickSelf", "rearDelay": 1000 }, - "BattleStartNormal": { + "BattleStart": { + "Doc": "base_task", + "template": "empty.png", "action": "ClickSelf", "roi": [ 989, @@ -6116,25 +5925,14 @@ ], "rearDelay": 2000 }, + "BattleStartNormal": { + "baseTask": "BattleStart" + }, "BattleStartRaid": { - "action": "ClickSelf", - "roi": [ - 989, - 318, - 232, - 374 - ], - "rearDelay": 2000 + "baseTask": "BattleStart" }, "BattleStartExercise": { - "action": "ClickSelf", - "roi": [ - 989, - 318, - 232, - 374 - ], - "rearDelay": 2000 + "baseTask": "BattleStart" }, "BattleStartSimulation": { "action": "ClickSelf", @@ -7059,18 +6857,6 @@ "Roguelike@StartExplore" ] }, - "Roguelike@NextLevel": { - "algorithm": "OcrDetect", - "action": "ClickSelf", - "cache": false, - "text": [], - "roi": [ - 522, - 431, - 245, - 144 - ] - }, "Roguelike@ChooseDifficulty": { "Doc": "base_task", "template": "empty.png", @@ -7643,6 +7429,18 @@ "Roguelike@ClickToStartPoint" ] }, + "Roguelike@NextLevel": { + "algorithm": "OcrDetect", + "action": "ClickSelf", + "cache": false, + "text": [], + "roi": [ + 522, + 431, + 245, + 144 + ] + }, "Roguelike@QuickFormation": { "Doc": "本任务注册了插件 RoguelikeFormationTaskPlugin", "action": "ClickSelf", @@ -7657,21 +7455,6 @@ ], "rearDelay": 2000 }, - "Roguelike@SquadDefault": { - "Doc": "base_task", - "template": "empty.png", - "action": "ClickSelf", - "cache": false, - "roi": [ - 0, - 153, - 1280, - 532 - ], - "next": [ - "Roguelike@SquadConfirm" - ] - }, "Roguelike@RecruitCloseGuide": { "action": "ClickSelf", "roi": [ @@ -7684,18 +7467,6 @@ "Roguelike@ChooseOperFlag" ] }, - "Roguelike@SquadConfirm": { - "Doc": "base_task", - "template": "empty.png", - "action": "ClickSelf", - "cache": false, - "roi": [ - 0, - 483, - 1280, - 200 - ] - }, "Roguelike@RecruitMain": { "Doc": "base_task", "template": "empty.png", @@ -7784,6 +7555,63 @@ "Roguelike@FromStageSN" ] }, + "Roguelike@RolesConfirm": { + "Doc": "base_task", + "template": "empty.png", + "action": "ClickSelf", + "cache": false, + "roi": [ + 0, + 153, + 1280, + 529 + ], + "next": [ + "Roguelike@RecruitMain" + ] + }, + "Roguelike@RolesDefault": { + "Doc": "base_task", + "template": "empty.png", + "action": "ClickSelf", + "cache": false, + "roi": [ + 601, + 153, + 363, + 529 + ], + "next": [ + "Roguelike@RolesConfirm" + ] + }, + "Roguelike@SquadConfirm": { + "Doc": "base_task", + "template": "empty.png", + "action": "ClickSelf", + "cache": false, + "roi": [ + 0, + 483, + 1280, + 200 + ] + }, + "Roguelike@SquadDefault": { + "Doc": "base_task", + "template": "empty.png", + "action": "ClickSelf", + "cache": false, + "roi": [ + 0, + 153, + 1280, + 532 + ], + "next": [ + "Roguelike@SquadConfirm" + ] + }, "Roguelike@StageBoons": { "Doc": "base_task", "Doc2": "古堡馈赠(随机奖励)", @@ -7904,10 +7732,7 @@ 50 ], "next": [ - "Roguelike@ChooseOperFlag", - "Roguelike@Free@StageEncounterOption", - "Roguelike@Leave@StageEncounterOption", - "Roguelike@Unknown@StageEncounterOption", + "Roguelike@StageEncounterOptions#next", "Roguelike@StageEncounterClickToLeave" ] }, @@ -7923,11 +7748,7 @@ 221 ], "next": [ - "Roguelike@ChooseOperFlag", - "Roguelike@Free@StageEncounterOption", - "Roguelike@Leave@StageEncounterOption", - "Roguelike@Unknown@StageEncounterOption", - "Roguelike@StageEncounterClickToLeave" + "Roguelike@StageEncounterOptions#next" ] }, "Roguelike@StageEncounterGiveUpRecruitConfirm": { @@ -7945,19 +7766,6 @@ "Roguelike@ClickToDrops" ] }, - "StageEncounterOption": { - "Doc": "base_task", - "template": "empty.png", - "action": "ClickSelf", - "cache": false, - "roi": [ - 1100, - 0, - 180, - 700 - ], - "preDelay": 500 - }, "Roguelike@StageEncounterLeaveConfirm": { "Doc": "base_task", "template": "empty.png", @@ -7971,16 +7779,53 @@ ], "rearDelay": 1000, "next": [ - "Roguelike@ChooseOperFlag", - "Roguelike@Free@StageEncounterOption", - "Roguelike@Leave@StageEncounterOption", - "Roguelike@Unknown@StageEncounterOption", + "Roguelike@StageEncounterOptions#next", "Roguelike@StageEncounterSpecialClose", "Roguelike@StageCambatDpsEnter", "Roguelike@StageEmergencyDpsEnter", "Roguelike@ClickToDrops" ] }, + "Roguelike@StageEncounterOption": { + "Doc": "base_task", + "template": "empty.png", + "action": "ClickSelf", + "cache": false, + "roi": [ + 1100, + 0, + 180, + 700 + ], + "preDelay": 500, + "next": [ + "Roguelike@StageEncounterLeaveConfirm", + "Roguelike@StageEncounterOptions#next" + ] + }, + "Roguelike@StageEncounterOptionFree": { + "baseTask": "Roguelike@StageEncounterOption", + "Doc": "base_task", + "template": "empty.png" + }, + "Roguelike@StageEncounterOptionLeave": { + "baseTask": "Roguelike@StageEncounterOption", + "Doc": "base_task", + "template": "empty.png" + }, + "Roguelike@StageEncounterOptionUnknown": { + "baseTask": "Roguelike@StageEncounterOption", + "Doc": "base_task", + "template": "empty.png" + }, + "Roguelike@StageEncounterOptionWonderland": { + "baseTask": "Roguelike@StageEncounterOption", + "Doc": "base_task", + "template": "empty.png" + }, + "Roguelike@StageEncounterOptions": { + "algorithm": "JustReturn" + }, "Roguelike@StageEncounterSpecialClose": { "Doc": "base_task", "Doc2": "关掉“大锁”", @@ -8022,10 +7867,7 @@ 221 ], "next": [ - "Roguelike@ChooseOperFlag", - "Roguelike@Free@StageEncounterOption", - "Roguelike@Leave@StageEncounterOption", - "Roguelike@Unknown@StageEncounterOption", + "Roguelike@StageEncounterOptions#next", "Roguelike@StageEncounterClickToLeave" ] }, @@ -8195,24 +8037,6 @@ 203 ] }, - "Roguelike@StartExplore": { - "Doc": "base_task", - "template": "empty.png", - "action": "ClickSelf", - "cache": false, - "roi": [ - 1026, - 470, - 254, - 248 - ], - "rearDelay": 2000, - "next": [ - "Roguelike@SquadDefault", - "Roguelike@InitalDrop", - "Roguelike@StartExplore" - ] - }, "Roguelike@StartAction": { "Doc": "本任务注册了插件 RoguelikeSkillSelectionTaskPlugin、RoguelikeBattleTaskPlugin", "action": "ClickSelf", @@ -8233,34 +8057,22 @@ "Roguelike@GamePass" ] }, - "Roguelike@RolesDefault": { + "Roguelike@StartExplore": { "Doc": "base_task", "template": "empty.png", "action": "ClickSelf", "cache": false, "roi": [ - 601, - 153, - 363, - 529 + 1026, + 470, + 254, + 248 ], + "rearDelay": 2000, "next": [ - "Roguelike@RolesConfirm" - ] - }, - "Roguelike@RolesConfirm": { - "Doc": "base_task", - "template": "empty.png", - "action": "ClickSelf", - "cache": false, - "roi": [ - 0, - 153, - 1280, - 529 - ], - "next": [ - "Roguelike@RecruitMain" + "Roguelike@SquadDefault", + "Roguelike@InitalDrop", + "Roguelike@StartExplore" ] }, "Roguelike@TodoEnter": { @@ -8346,13 +8158,7 @@ "next": [ "Phantom@Roguelike@ChooseDifficulty", "Phantom@Roguelike@StartExplore", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe", + "Phantom@Roguelike@NextLevel#next", "Phantom@Roguelike@NextLevel", "Phantom@Roguelike@ExitThenAbandon", "Phantom@Roguelike@Abandon", @@ -8375,34 +8181,9 @@ "Phantom@Roguelike@ChooseOperConfirm" ] }, - "Phantom@Roguelike@NextLevel": { - "text": [ - "迷雾歧途", - "落阳庭院", - "故土残躯", - "噩梦之始", - "血月长廊", - "渴欲大厅" - ], - "next": [ - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" - ] - }, "Phantom@Roguelike@ClickToDrops": { "next": [ - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe", + "Phantom@Roguelike@NextLevel#next", "Phantom@Roguelike@ChooseOperFlag", "Phantom@Roguelike@StageEncounterSpecialClose", "Phantom@Roguelike@TraderRandomShopping", @@ -8420,13 +8201,7 @@ "Phantom@Roguelike@ClickToStartPoint": { "next": [ "Phantom@Roguelike@StartExplore", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe", + "Phantom@Roguelike@NextLevel#next", "Phantom@Roguelike@GamePass", "Phantom@Roguelike@TodaysSupplies", "Phantom@Roguelike@Main", @@ -8455,13 +8230,7 @@ "template": "Roguelike@DialogSkipConfirm.png", "next": [ "Phantom@Roguelike@DialogSkip", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@DropsFlag": { @@ -8474,17 +8243,8 @@ "Phantom@Roguelike@GetDropRecruit", "Phantom@Roguelike@GetDropCompleted", "Phantom@Roguelike@GetDropLeave", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe", - "Phantom@Roguelike@ChooseOperFlag", - "Phantom@Roguelike@Free@StageEncounterOption", - "Phantom@Roguelike@Leave@StageEncounterOption", - "Phantom@Roguelike@Unknown@StageEncounterOption", + "Phantom@Roguelike@NextLevel#next", + "Phantom@Roguelike@StageEncounterOptions#next", "Phantom@Roguelike@StageEncounterSpecialClose", "Phantom@Roguelike@EnterAfterRecruit", "Phantom@Roguelike@StageTraderLeave", @@ -8493,13 +8253,7 @@ }, "Phantom@Roguelike@EnterAfterRecruit": { "next": [ - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@ExitThenAbandon": { @@ -8564,28 +8318,21 @@ 267 ], "next": [ - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe", + "Phantom@Roguelike@NextLevel#next", "Phantom@Roguelike@ClickToStartPoint" ] }, "Phantom@Roguelike@MissionFailedFlag2": {}, - "Phantom@Roguelike@SquadDefault": {}, - "Phantom@Roguelike@SquadConfirm": { - "template": "Phantom@Roguelike@LastRewardConfirm.png", + "Phantom@Roguelike@NextLevel": { + "text": [ + "迷雾歧途", + "落阳庭院", + "故土残躯", + "噩梦之始", + "血月长廊", + "渴欲大厅" + ], "next": [ - "Phantom@Roguelike@LastReward", - "Phantom@Roguelike@LastReward2", - "Phantom@Roguelike@LastReward3", - "Phantom@Roguelike@LastRewardRand", - "Phantom@Roguelike@RolesDefault", - "Phantom@Roguelike@CloseCollection", - "Phantom@Roguelike@DialogSkip", "Phantom@Roguelike@StageTrader", "Phantom@Roguelike@StageSafeHouse", "Phantom@Roguelike@StageEncounter", @@ -8612,17 +8359,29 @@ "Phantom@Roguelike@RecruitWithoutButton" ] }, + "Phantom@Roguelike@RolesConfirm": { + "template": "Phantom@Roguelike@LastRewardConfirm" + }, + "Phantom@Roguelike@RolesDefault": {}, + "Phantom@Roguelike@SquadConfirm": { + "template": "Phantom@Roguelike@LastRewardConfirm.png", + "next": [ + "Phantom@Roguelike@LastReward", + "Phantom@Roguelike@LastReward2", + "Phantom@Roguelike@LastReward3", + "Phantom@Roguelike@LastRewardRand", + "Phantom@Roguelike@RolesDefault", + "Phantom@Roguelike@CloseCollection", + "Phantom@Roguelike@DialogSkip", + "Phantom@Roguelike@NextLevel#next" + ] + }, + "Phantom@Roguelike@SquadDefault": {}, "Phantom@Roguelike@StageBoons": { "templThreshold": 0.85, "next": [ "Phantom@Roguelike@StageEncounterEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageCambatDps": { @@ -8630,13 +8389,7 @@ "next": [ "Phantom@Roguelike@StageCambatDpsEnter", "Phantom@Roguelike@StageEmergencyDpsEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageCambatDpsEnter": {}, @@ -8646,13 +8399,7 @@ "Phantom@Roguelike@StageDreadfulFoeEnter", "Phantom@Roguelike@StageEmergencyDpsEnter", "Phantom@Roguelike@StageCambatDpsEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageDreadfulFoeEnter": {}, @@ -8661,13 +8408,7 @@ "next": [ "Phantom@Roguelike@StageEmergencyDpsEnter", "Phantom@Roguelike@StageCambatDpsEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageEmergencyDpsEnter": {}, @@ -8675,59 +8416,34 @@ "templThreshold": 0.85, "next": [ "Phantom@Roguelike@StageEncounterEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageEncounterEnter": {}, - "Phantom@Roguelike@Free@StageEncounterOption": { - "templThreshold": 0.99, - "next": [ - "Phantom@Roguelike@StageEncounterLeaveConfirm", - "Phantom@Roguelike@Leave@StageEncounterOption", - "Phantom@Roguelike@Unknown@StageEncounterOption", - "Phantom@Roguelike@Free@StageEncounterOption", - "Phantom@Roguelike@ChooseOperFlag" - ] - }, - "Phantom@Roguelike@Leave@StageEncounterOption": { - "templThreshold": 0.97, - "next": [ - "Phantom@Roguelike@StageEncounterLeaveConfirm", - "Phantom@Roguelike@Free@StageEncounterOption", - "Phantom@Roguelike@Unknown@StageEncounterOption", - "Phantom@Roguelike@Leave@StageEncounterOption", - "Phantom@Roguelike@ChooseOperFlag" - ] - }, "Phantom@Roguelike@StageEncounterLeaveConfirm": {}, - "Phantom@Roguelike@StageEncounterSpecialClose": {}, - "Phantom@Roguelike@Unknown@StageEncounterOption": { - "templThreshold": 0.91, + "Phantom@Roguelike@StageEncounterOptionFree": { + "templThreshold": 0.99 + }, + "Phantom@Roguelike@StageEncounterOptionLeave": { + "templThreshold": 0.97 + }, + "Phantom@Roguelike@StageEncounterOptionUnknown": { + "templThreshold": 0.91 + }, + "Phantom@Roguelike@StageEncounterOptions": { "next": [ - "Phantom@Roguelike@ChooseOperFlag", - "Phantom@Roguelike@StageEncounterLeaveConfirm", - "Phantom@Roguelike@Free@StageEncounterOption", - "Phantom@Roguelike@Leave@StageEncounterOption", - "Phantom@Roguelike@Unknown@StageEncounterOption" + "Phantom@Roguelike@StageEncounterOptionFree", + "Phantom@Roguelike@StageEncounterOptionLeave", + "Phantom@Roguelike@StageEncounterOptionUnknown", + "Phantom@Roguelike@ChooseOperFlag" ] }, + "Phantom@Roguelike@StageEncounterSpecialClose": {}, "Phantom@Roguelike@StageSafeHouse": { "templThreshold": 0.85, "next": [ "Phantom@Roguelike@StageSafeHouseEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageSafeHouseEnter": {}, @@ -8735,13 +8451,7 @@ "templThreshold": 0.85, "next": [ "Phantom@Roguelike@StageTraderEnter", - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StageTraderEnter": {}, @@ -8751,20 +8461,10 @@ "Phantom@Roguelike@ExitThenAbandon" ], "next": [ - "Phantom@Roguelike@StageTrader", - "Phantom@Roguelike@StageSafeHouse", - "Phantom@Roguelike@StageEncounter", - "Phantom@Roguelike@StageBoons", - "Phantom@Roguelike@StageCambatDps", - "Phantom@Roguelike@StageEmergencyDps", - "Phantom@Roguelike@StageDreadfulFoe" + "Phantom@Roguelike@NextLevel#next" ] }, "Phantom@Roguelike@StartExplore": {}, - "Phantom@Roguelike@RolesDefault": {}, - "Phantom@Roguelike@RolesConfirm": { - "template": "Phantom@Roguelike@LastRewardConfirm" - }, "Phantom@Roguelike@TodoEnter": {}, "Mizuki@Roguelike@Abandon": {}, "Mizuki@Roguelike@Begin": { @@ -8772,22 +8472,7 @@ "next": [ "Mizuki@Roguelike@ChooseDifficulty", "Mizuki@Roguelike@StartExplore", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@CloseEvent", "Mizuki@Roguelike@NextLevel", "Mizuki@Roguelike@ExitThenAbandon", @@ -8815,22 +8500,7 @@ }, "Mizuki@Roguelike@ClickToDrops": { "next": [ - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@ChooseOperFlag", "Mizuki@Roguelike@StageEncounterSpecialClose", "Mizuki@Roguelike@TraderRandomShopping", @@ -8848,22 +8518,7 @@ "Mizuki@Roguelike@ClickToStartPoint": { "next": [ "Mizuki@Roguelike@StartExplore", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@GamePass", "Mizuki@Roguelike@TodaysSupplies", "Mizuki@Roguelike@Main", @@ -8904,22 +8559,7 @@ ], "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@DropsFlag", "Mizuki@Roguelike@CloseEvent", "Mizuki@Roguelike@ChooseOperFlag" @@ -8941,22 +8581,7 @@ ], "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@DropsFlag", "Mizuki@Roguelike@CloseEvent", "Mizuki@Roguelike@ChooseOperFlag" @@ -8973,22 +8598,7 @@ ], "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@DropsFlag", "Mizuki@Roguelike@CloseEvent" ] @@ -9011,22 +8621,7 @@ ], "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@Continue": {}, @@ -9047,22 +8642,7 @@ "template": "Roguelike@DialogSkipConfirm.png", "next": [ "Mizuki@Roguelike@DialogSkip", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@DiceConfirm": { @@ -9079,22 +8659,7 @@ "rearDelay": 1000, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@ClickToDrops" ] }, @@ -9125,26 +8690,8 @@ "Mizuki@Roguelike@GetDropBox", "Mizuki@Roguelike@GetDropCompleted", "Mizuki@Roguelike@GetDropLeave", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", - "Mizuki@Roguelike@ChooseOperFlag", - "Mizuki@Roguelike@Free@StageEncounterOption", - "Mizuki@Roguelike@Leave@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", + "Mizuki@Roguelike@NextLevel#next", + "Mizuki@Roguelike@StageEncounterOptions#next", "Mizuki@Roguelike@StageEncounterSpecialClose", "Mizuki@Roguelike@EnterAfterRecruit", "Mizuki@Roguelike@StageTraderLeave", @@ -9154,22 +8701,7 @@ }, "Mizuki@Roguelike@EnterAfterRecruit": { "next": [ - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@ExitThenAbandon": { @@ -9301,22 +8833,7 @@ 267 ], "next": [ - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", + "Mizuki@Roguelike@NextLevel#next", "Mizuki@Roguelike@ClickToStartPoint" ] }, @@ -9350,37 +8867,6 @@ "Mizuki@Roguelike@CloseCollectionClose" ] }, - "Mizuki@Roguelike@SquadDefault": {}, - "Mizuki@Roguelike@SquadConfirm": { - "template": "Mizuki@Roguelike@LastRewardConfirm.png", - "next": [ - "Mizuki@Roguelike@LastReward", - "Mizuki@Roguelike@LastReward2", - "Mizuki@Roguelike@LastReward3", - "Mizuki@Roguelike@LastReward4", - "Mizuki@Roguelike@LastRewardRand", - "Mizuki@Roguelike@RolesDefault", - "Mizuki@Roguelike@CloseCollection", - "Mizuki@Roguelike@DialogSkip", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose", - "Mizuki@Roguelike@MapObject" - ] - }, "Mizuki@Roguelike@RecruitMain": { "template": "Mizuki@Roguelike@Recruit.png" }, @@ -9399,26 +8885,31 @@ "Mizuki@Roguelike@RecruitWithoutButton" ] }, + "Mizuki@Roguelike@RolesConfirm": { + "template": "Mizuki@Roguelike@LastRewardConfirm" + }, + "Mizuki@Roguelike@RolesDefault": {}, + "Mizuki@Roguelike@SquadConfirm": { + "template": "Mizuki@Roguelike@LastRewardConfirm.png", + "next": [ + "Mizuki@Roguelike@LastReward", + "Mizuki@Roguelike@LastReward2", + "Mizuki@Roguelike@LastReward3", + "Mizuki@Roguelike@LastReward4", + "Mizuki@Roguelike@LastRewardRand", + "Mizuki@Roguelike@RolesDefault", + "Mizuki@Roguelike@CloseCollection", + "Mizuki@Roguelike@DialogSkip", + "Mizuki@Roguelike@NextLevel#next", + "Mizuki@Roguelike@MapObject" + ] + }, + "Mizuki@Roguelike@SquadDefault": {}, "Mizuki@Roguelike@StageBoons": { "templThreshold": 0.95, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageCambatDps": { @@ -9427,22 +8918,7 @@ "next": [ "Mizuki@Roguelike@StageCambatDpsEnter", "Mizuki@Roguelike@StageEmergencyDpsEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageCambatDpsEnter": {}, @@ -9452,22 +8928,7 @@ "Mizuki@Roguelike@StageDreadfulFoeEnter", "Mizuki@Roguelike@StageEmergencyDpsEnter", "Mizuki@Roguelike@StageCambatDpsEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageDreadfulFoe-5": { @@ -9486,22 +8947,7 @@ "Mizuki@Roguelike@StageDreadfulFoeEnter", "Mizuki@Roguelike@StageEmergencyDpsEnter", "Mizuki@Roguelike@StageCambatDpsEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageDreadfulFoe-5Enter": { @@ -9524,22 +8970,7 @@ "next": [ "Mizuki@Roguelike@StageEmergencyDpsEnter", "Mizuki@Roguelike@StageCambatDpsEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageEmergencyDpsEnter": {}, @@ -9556,110 +8987,44 @@ "templThreshold": 0.95, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageEncounter": { "templThreshold": 0.96, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageEncounterEnter": {}, - "Mizuki@Roguelike@Free@StageEncounterOption": { + "Mizuki@Roguelike@StageEncounterLeaveConfirm": {}, + "Mizuki@Roguelike@StageEncounterOptionFree": { "maskRange": [ 5, 255 - ], - "next": [ - "Mizuki@Roguelike@StageEncounterLeaveConfirm", - "Mizuki@Roguelike@Leave@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", - "Mizuki@Roguelike@Free@StageEncounterOption", - "Mizuki@Roguelike@ChooseOperFlag", - "Mizuki@Roguelike@Wonderland@StageEncounterOption" ] }, - "Mizuki@Roguelike@Leave@StageEncounterOption": { + "Mizuki@Roguelike@StageEncounterOptionLeave": { "maskRange": [ 5, 255 - ], - "next": [ - "Mizuki@Roguelike@StageEncounterLeaveConfirm", - "Mizuki@Roguelike@Free@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", - "Mizuki@Roguelike@Leave@StageEncounterOption", - "Mizuki@Roguelike@ChooseOperFlag", - "Mizuki@Roguelike@Wonderland@StageEncounterOption" ] }, - "Mizuki@Roguelike@StageEncounterLeaveConfirm": { + "Mizuki@Roguelike@StageEncounterOptionUnknown": { + "templThreshold": 0.91 + }, + "Mizuki@Roguelike@StageEncounterOptionWonderland": {}, + "Mizuki@Roguelike@StageEncounterOptions": { "next": [ - "Mizuki@Roguelike@ChooseOperFlag", - "Mizuki@Roguelike@Free@StageEncounterOption", - "Mizuki@Roguelike@Leave@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", - "Mizuki@Roguelike@StageEncounterSpecialClose", - "Mizuki@Roguelike@StageCambatDpsEnter", - "Mizuki@Roguelike@StageEmergencyDpsEnter", - "Mizuki@Roguelike@ClickToDrops" + "Mizuki@Roguelike@StageEncounterOptionFree", + "Mizuki@Roguelike@StageEncounterOptionLeave", + "Mizuki@Roguelike@StageEncounterOptionUnknown", + "Mizuki@Roguelike@StageEncounterOptionWonderland", + "Mizuki@Roguelike@ChooseOperFlag" ] }, "Mizuki@Roguelike@StageEncounterSpecialClose": {}, - "Mizuki@Roguelike@Unknown@StageEncounterOption": { - "templThreshold": 0.91, - "next": [ - "Mizuki@Roguelike@ChooseOperFlag", - "Mizuki@Roguelike@StageEncounterLeaveConfirm", - "Mizuki@Roguelike@Free@StageEncounterOption", - "Mizuki@Roguelike@Leave@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", - "Mizuki@Roguelike@Wonderland@StageEncounterOption" - ] - }, - "Mizuki@Roguelike@Wonderland@StageEncounterOption": { - "next": [ - "Mizuki@Roguelike@ChooseOperFlag", - "Mizuki@Roguelike@StageEncounterLeaveConfirm", - "Mizuki@Roguelike@Free@StageEncounterOption", - "Mizuki@Roguelike@Leave@StageEncounterOption", - "Mizuki@Roguelike@Unknown@StageEncounterOption", - "Mizuki@Roguelike@Wonderland@StageEncounterOption" - ] - }, "Mizuki@Roguelike@StageGambling": { "Doc": "骰子关卡", "action": "ClickSelf", @@ -9673,22 +9038,7 @@ "templThreshold": 0.95, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageRegionalCommissioning": { @@ -9704,22 +9054,7 @@ "templThreshold": 0.95, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageSafeHouse": { @@ -9769,22 +9104,7 @@ "Mizuki@Roguelike@ExitThenAbandon" ], "next": [ - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StageWindAndRain": { @@ -9800,29 +9120,10 @@ "templThreshold": 0.95, "next": [ "Mizuki@Roguelike@StageEncounterEnter", - "Mizuki@Roguelike@StageTrader", - "Mizuki@Roguelike@StageSafeHouse", - "Mizuki@Roguelike@StageWindAndRain", - "Mizuki@Roguelike@StageEmergencyTransportation", - "Mizuki@Roguelike@StageEncounter", - "Mizuki@Roguelike@StageBoons", - "Mizuki@Roguelike@StageCambatDps", - "Mizuki@Roguelike@StageEmergencyDps", - "Mizuki@Roguelike@StageDreadfulFoe", - "Mizuki@Roguelike@StageDreadfulFoe-5", - "Mizuki@Roguelike@StageRegionalCommissioning", - "Mizuki@Roguelike@StageGambling", - "Mizuki@Roguelike@CommissionedMissionCompleted", - "Mizuki@Roguelike@DiceConfirm", - "Mizuki@Roguelike@CloseCollectionContinue", - "Mizuki@Roguelike@CloseCollectionClose" + "Mizuki@Roguelike@NextLevel#next" ] }, "Mizuki@Roguelike@StartExplore": {}, - "Mizuki@Roguelike@RolesDefault": {}, - "Mizuki@Roguelike@RolesConfirm": { - "template": "Mizuki@Roguelike@LastRewardConfirm" - }, "Mizuki@Roguelike@TodoEnter": {}, "RoguelikeBattleAbandon": { "action": "ClickSelf", diff --git a/resource/template/Mizuki@Roguelike@Free@StageEncounterOption.png b/resource/template/Mizuki@Roguelike@StageEncounterOptionFree.png similarity index 100% rename from resource/template/Mizuki@Roguelike@Free@StageEncounterOption.png rename to resource/template/Mizuki@Roguelike@StageEncounterOptionFree.png diff --git a/resource/template/Mizuki@Roguelike@Leave@StageEncounterOption.png b/resource/template/Mizuki@Roguelike@StageEncounterOptionLeave.png similarity index 100% rename from resource/template/Mizuki@Roguelike@Leave@StageEncounterOption.png rename to resource/template/Mizuki@Roguelike@StageEncounterOptionLeave.png diff --git a/resource/template/Mizuki@Roguelike@Unknown@StageEncounterOption.png b/resource/template/Mizuki@Roguelike@StageEncounterOptionUnknown.png similarity index 100% rename from resource/template/Mizuki@Roguelike@Unknown@StageEncounterOption.png rename to resource/template/Mizuki@Roguelike@StageEncounterOptionUnknown.png diff --git a/resource/template/Mizuki@Roguelike@Wonderland@StageEncounterOption.png b/resource/template/Mizuki@Roguelike@StageEncounterOptionWonderland.png similarity index 100% rename from resource/template/Mizuki@Roguelike@Wonderland@StageEncounterOption.png rename to resource/template/Mizuki@Roguelike@StageEncounterOptionWonderland.png diff --git a/resource/template/Phantom@Roguelike@Free@StageEncounterOption.png b/resource/template/Phantom@Roguelike@StageEncounterOptionFree.png similarity index 100% rename from resource/template/Phantom@Roguelike@Free@StageEncounterOption.png rename to resource/template/Phantom@Roguelike@StageEncounterOptionFree.png diff --git a/resource/template/Phantom@Roguelike@Leave@StageEncounterOption.png b/resource/template/Phantom@Roguelike@StageEncounterOptionLeave.png similarity index 100% rename from resource/template/Phantom@Roguelike@Leave@StageEncounterOption.png rename to resource/template/Phantom@Roguelike@StageEncounterOptionLeave.png diff --git a/resource/template/Phantom@Roguelike@Unknown@StageEncounterOption.png b/resource/template/Phantom@Roguelike@StageEncounterOptionUnknown.png similarity index 100% rename from resource/template/Phantom@Roguelike@Unknown@StageEncounterOption.png rename to resource/template/Phantom@Roguelike@StageEncounterOptionUnknown.png diff --git a/src/MeoAssistant/Task/Sub/ProcessTask.cpp b/src/MeoAssistant/Task/Sub/ProcessTask.cpp index 650d9cd67d..dab9e4d9b8 100644 --- a/src/MeoAssistant/Task/Sub/ProcessTask.cpp +++ b/src/MeoAssistant/Task/Sub/ProcessTask.cpp @@ -78,11 +78,65 @@ ProcessTask& asst::ProcessTask::set_rear_delay(std::string name, int delay) return *this; } +bool ProcessTask::generate_tasks(const std::vector& raw_tasks) +{ + for (const std::string& task : raw_tasks) { + size_t pos = task.find('#'); + if (pos == std::string_view::npos) { + m_cur_tasks_name.emplace_back(task); + continue; + } + std::string other_task_name = task.substr(0, pos); + std::string type = task.substr(pos + 1); + auto other_tasklist_ref = Task.get(other_task_name); + if (other_tasklist_ref == nullptr) { + Log.error(task, "not found"); + continue; + } + +#define ASST_PROCESSTASK_GENERATE_TASKS(t) \ + else if (type == #t) \ + { \ + if (!generate_tasks(other_tasklist_ref->t)) { \ + return false; \ + } \ + } + if constexpr (false) {} + ASST_PROCESSTASK_GENERATE_TASKS(next) + ASST_PROCESSTASK_GENERATE_TASKS(sub) + ASST_PROCESSTASK_GENERATE_TASKS(on_error_next) + ASST_PROCESSTASK_GENERATE_TASKS(exceeded_next) + ASST_PROCESSTASK_GENERATE_TASKS(reduce_other_times) + else { + Log.error("Unknown type", type); + return false; + } + } +#undef ASST_PROCESSTASK_GENERATE_TASKS + + return true; +} + +bool ProcessTask::generate_tasks() +{ + // std::move 后 m_cur_tasks_name 已经为空 + std::vector cur_tasks_name = std::move(m_cur_tasks_name); + if (!generate_tasks(cur_tasks_name)) [[unlikely]] { + Log.error("Generate task failed."); + m_cur_tasks_name.clear(); + return false; + } + return true; +} + bool ProcessTask::_run() { LogTraceFunction; while (!m_cur_tasks_name.empty()) { + if (!generate_tasks()) { + return false; + } if (need_exit()) { return false; } diff --git a/src/MeoAssistant/Task/Sub/ProcessTask.h b/src/MeoAssistant/Task/Sub/ProcessTask.h index 763e06ba9f..e9ef01c472 100644 --- a/src/MeoAssistant/Task/Sub/ProcessTask.h +++ b/src/MeoAssistant/Task/Sub/ProcessTask.h @@ -41,6 +41,8 @@ namespace asst virtual json::value basic_info() const override; std::pair calc_time_limit() const; + bool generate_tasks(const std::vector& raw_tasks); + bool generate_tasks(); void exec_click_task(const Rect& matched_rect); void exec_swipe_task(ProcessTaskAction action); void exec_slowly_swipe_task(ProcessTaskAction action); diff --git a/src/MeoAssistant/TaskData.cpp b/src/MeoAssistant/TaskData.cpp index 1bfc492a08..06255fd78f 100644 --- a/src/MeoAssistant/TaskData.cpp +++ b/src/MeoAssistant/TaskData.cpp @@ -19,34 +19,65 @@ bool asst::TaskData::parse(const json::value& json) { LogTraceFunction; - // <任务名, 模板任务标志位置, 任务参数ref> - std::vector>> template_task_info {}; + const auto& json_obj = json.as_object(); - for (const auto& [name, task_json] : json.as_object()) { - // 模板任务特化需要等模板任务生成后才能生成 - if (size_t p = name.find('@'); p != std::string::npos) { - template_task_info.emplace_back(name, p, task_json); - continue; + { + std::unordered_map to_be_generated; + for (const std::string& name : json_obj | views::keys) { + to_be_generated[name] = true; } - std::shared_ptr task_info_ptr = generate_task_info(name, task_json, nullptr); - if (task_info_ptr == nullptr) { - return false; - } - m_all_tasks_info[name] = task_info_ptr; - } + auto generate_task_and_its_base = [&](const std::string& name) -> bool { + auto generate_task = [&](const std::string& name, std::string_view prefix, + std::shared_ptr base_ptr, const json::value& task_json) { + auto task_info_ptr = generate_task_info(name, task_json, base_ptr, prefix); + if (task_info_ptr == nullptr) { + return false; + } + to_be_generated[name] = false; + m_all_tasks_info[name] = task_info_ptr; + return true; + }; + std::function generate_fun; + // must_true 若为真,那么 return false 了就是炸了。 + // 否则可能只是某个 B@A 的任务没定义 A(这不是少见现象,例如 Roguelike@Abandon) + generate_fun = [&](const std::string& name, bool must_true) -> bool { + if (!to_be_generated[name]) { + // 已生成(它是之前加载过的某个资源的 base) + if (m_all_tasks_info.contains(name)) { + return true; + } + // 不在 json 内且未生成(例如生成 C@B@A 时没有定义 B@A,而是定义了 A) + if (size_t p = name.find('@'); p != std::string::npos) { + return generate_fun(name.substr(p + 1), must_true); + } + // 例如 Roguelike@Abandon 在这里如果 must_true = true,会报 `Unknown task: Abandon` + if (must_true) { + Log.error("Unknown task:", name); + } + return false; + } + const json::value& task_json = json_obj.at(name); + if (auto opt = task_json.find("baseTask")) { + std::string base = opt.value(); + return generate_fun(base, must_true) && generate_task(name, "", get(base, false), task_json); + } - // 短任务在前,因为模板任务特化一定比模板任务长 - ranges::sort(template_task_info, - [](const auto& l, const auto& r) { return std::get<0>(l).length() < std::get<0>(r).length(); }); + if (size_t p = name.find('@'); p != std::string::npos) { + if (std::string base = name.substr(p + 1); generate_fun(base, false)) { + return generate_task(name, name.substr(0, p), get(base, false), task_json); + } + // 这类任务有点多,非必要不输出( + // Log.debug("Task", name, "based on unknown task, just use task_json."); + } + return generate_task(name, "", nullptr, task_json); + }; + return generate_fun(name, true); + }; - for (const auto& [name, pos, task_json] : template_task_info) { - // 可能某个名字里带@的任务不是模板任务特化,只是普通的基类任务,这里最后一个参数可能为 nullptr - auto task_info_ptr = generate_task_info(name, task_json, get(name.substr(pos + 1)), name.substr(0, pos)); - if (task_info_ptr == nullptr) { - return false; + for (const std::string& name : json_obj | views::keys) { + generate_task_and_its_base(name); } - m_all_tasks_info[name] = task_info_ptr; } #ifdef ASST_DEBUG @@ -54,18 +85,78 @@ bool asst::TaskData::parse(const json::value& json) bool validity = true; // 语法检查 - for (const auto& [name, task_json] : json.as_object()) { + for (const auto& [name, task_json] : json_obj) { validity &= syntax_check(name, task_json); } - // next 存在性检查 - // TODO: 这块感觉可以合并到 syntax_check 里 + std::unordered_map> dependency_graph; // "#" 型任务依赖关系 (有向图邻接表) + std::unordered_map checked; // 拓扑排序相关的标志 + static const std::unordered_set accepted_type = { + "next", "sub", "on_error_next", "exceeded_next", "reduce_other_times", + }; + for (const auto& [name, task] : m_all_tasks_info) { - for (const auto& next : task->next) { - if (get(next, false) == nullptr) { - Log.error(name, "'s next", next, "is null"); - validity = false; + auto check_and_link = [&](const std::vector& task_list, std::string node_name) { + for (const auto& task_name : task_list) { + size_t pos = task_name.find('#'); + // next、sub 等的存在性检查 + if (pos == std::string::npos) { + if (get(task_name, false) == nullptr) { + Log.error(node_name, task_name, "is null"); + validity = false; + } + continue; + } + + std::string other_task_name = task_name.substr(0, pos); + if (get(other_task_name, false) == nullptr) { + Log.error(node_name, task_name, "is null"); + validity = false; + } + std::string type = task_name.substr(pos + 1); + if (!accepted_type.contains(type)) { + Log.error(node_name, task_name, "has unknown type:", type); + validity = false; + } + else { + // 建立一条依赖关系 (有向边) + dependency_graph[node_name].emplace_back(task_name); + } } + }; + check_and_link(task->next, name + "#next"); + check_and_link(task->sub, name + "#sub"); + check_and_link(task->exceeded_next, name + "#exceeded_next"); + check_and_link(task->on_error_next, name + "#on_error_next"); + check_and_link(task->reduce_other_times, name + "#reduce_other_times"); + } + + // dfs 检查 "#" 型任务是否循环依赖 (有向无环图) + auto check_circle = [&](const std::string& x) { + std::function dfs; + dfs = [&](const std::string& x) { + checked[x] = -1; + for (const auto& y : dependency_graph[x]) { + if (checked[y] == 0) { + if (!dfs(y)) [[unlikely]] { + return false; + } + } + else if (checked[y] < 0) [[unlikely]] { + Log.error("Task", y, "has circular dependency."); + return false; + } + } + checked[x] = 1; + return true; + }; + return dfs(x); + }; + + for (const auto& name : dependency_graph | views::keys) { + if (!checked[name] && !check_circle(name)) { + validity = false; + break; } } @@ -78,10 +169,11 @@ bool asst::TaskData::parse(const json::value& json) std::shared_ptr asst::TaskData::generate_task_info(const std::string& name, const json::value& task_json, std::shared_ptr default_ptr, - const std::string& task_prefix) + std::string_view task_prefix) { if (default_ptr == nullptr) { default_ptr = default_task_info_ptr; + task_prefix = ""; } // 获取 algorithm 并按照 algorithm 生成 TaskInfo @@ -227,7 +319,7 @@ std::shared_ptr asst::TaskData::generate_hash_task_info([[maybe_ bool asst::TaskData::append_base_task_info(std::shared_ptr task_info_ptr, const std::string& name, const json::value& task_json, std::shared_ptr default_ptr, - std::string task_prefix) + std::string_view task_prefix) { if (default_ptr == nullptr) { default_ptr = default_task_info_ptr; @@ -330,6 +422,50 @@ bool asst::TaskData::append_base_task_info(std::shared_ptr task_info_p return true; } +std::shared_ptr asst::TaskData::_default_match_task_info() +{ + auto match_task_info_ptr = std::make_shared(); + match_task_info_ptr->templ_name = "__INVALID__"; + match_task_info_ptr->templ_threshold = TemplThresholdDefault; + match_task_info_ptr->special_threshold = 0; + + return match_task_info_ptr; +} + +std::shared_ptr asst::TaskData::_default_ocr_task_info() +{ + auto ocr_task_info_ptr = std::make_shared(); + ocr_task_info_ptr->full_match = false; + + return ocr_task_info_ptr; +} + +std::shared_ptr asst::TaskData::_default_hash_task_info() +{ + auto hash_task_info_ptr = std::make_shared(); + hash_task_info_ptr->dist_threshold = 0; + hash_task_info_ptr->bound = true; + + return hash_task_info_ptr; +} + +std::shared_ptr asst::TaskData::_default_task_info() +{ + auto task_info_ptr = std::make_shared(); + task_info_ptr->algorithm = AlgorithmType::MatchTemplate; + task_info_ptr->action = ProcessTaskAction::DoNothing; + task_info_ptr->cache = true; + task_info_ptr->max_times = INT_MAX; + task_info_ptr->pre_delay = 0; + task_info_ptr->rear_delay = 0; + task_info_ptr->roi = Rect(); + task_info_ptr->sub_error_ignored = false; + task_info_ptr->rect_move = Rect(); + task_info_ptr->specific_rect = Rect(); + + return task_info_ptr; +} + #ifdef ASST_DEBUG // 为了解决类似 beddc7c828126c678391e0b4da288db6d2c2d58a 导致的问题,加载的时候做一个语法检查 // 主要是处理是否包含未知键值的问题 @@ -339,6 +475,7 @@ bool asst::TaskData::syntax_check(const std::string& task_name, const json::valu { AlgorithmType::Invalid, { "algorithm", + "baseTask", "template", "text", "action", @@ -365,6 +502,7 @@ bool asst::TaskData::syntax_check(const std::string& task_name, const json::valu { AlgorithmType::MatchTemplate, { "algorithm", + "baseTask", "template", "action", "sub", @@ -385,6 +523,7 @@ bool asst::TaskData::syntax_check(const std::string& task_name, const json::valu { AlgorithmType::OcrDetect, { "algorithm", + "baseTask", "text", "action", "sub", @@ -405,6 +544,7 @@ bool asst::TaskData::syntax_check(const std::string& task_name, const json::valu { AlgorithmType::JustReturn, { "algorithm", + "baseTask", "action", "sub", "subErrorIgnored", @@ -419,6 +559,7 @@ bool asst::TaskData::syntax_check(const std::string& task_name, const json::valu { AlgorithmType::Hash, { "algorithm", + "baseTask", "action", "sub", "subErrorIgnored", @@ -486,8 +627,7 @@ bool asst::TaskData::syntax_check(const std::string& task_name, const json::valu allowed_key.merge(tmp); } - // TODO: 之后也许还要对 key-value 联合检查,json 先留着 - for (const auto& [name, json] : task_json.as_object()) { + for (const auto& name : task_json.as_object() | views::keys) { if (!allowed_key.contains(name) && !is_doc(name) && !has_doc(name)) { Log.error(task_name, "has unknown key:", name); validity = false; diff --git a/src/MeoAssistant/TaskData.h b/src/MeoAssistant/TaskData.h index 80f483553c..6e9a1f2c6b 100644 --- a/src/MeoAssistant/TaskData.h +++ b/src/MeoAssistant/TaskData.h @@ -18,49 +18,10 @@ namespace asst class TaskData final : public SingletonHolder, public AbstractConfigerWithTempl { private: - std::shared_ptr _default_match_task_info() - { - auto match_task_info_ptr = std::make_shared(); - match_task_info_ptr->templ_name = "__INVALID__"; - match_task_info_ptr->templ_threshold = TemplThresholdDefault; - match_task_info_ptr->special_threshold = 0; - - return match_task_info_ptr; - } - - std::shared_ptr _default_ocr_task_info() - { - auto ocr_task_info_ptr = std::make_shared(); - ocr_task_info_ptr->full_match = false; - - return ocr_task_info_ptr; - } - - std::shared_ptr _default_hash_task_info() - { - auto hash_task_info_ptr = std::make_shared(); - hash_task_info_ptr->dist_threshold = 0; - hash_task_info_ptr->bound = true; - - return hash_task_info_ptr; - } - - std::shared_ptr _default_task_info() - { - auto task_info_ptr = std::make_shared(); - task_info_ptr->algorithm = AlgorithmType::MatchTemplate; - task_info_ptr->action = ProcessTaskAction::DoNothing; - task_info_ptr->cache = true; - task_info_ptr->max_times = INT_MAX; - task_info_ptr->pre_delay = 0; - task_info_ptr->rear_delay = 0; - task_info_ptr->roi = Rect(); - task_info_ptr->sub_error_ignored = false; - task_info_ptr->rect_move = Rect(); - task_info_ptr->specific_rect = Rect(); - - return task_info_ptr; - } + std::shared_ptr _default_match_task_info(); + std::shared_ptr _default_ocr_task_info(); + std::shared_ptr _default_hash_task_info(); + std::shared_ptr _default_task_info(); // 从模板任务生成 const std::shared_ptr default_match_task_info_ptr = _default_match_task_info(); @@ -71,7 +32,7 @@ namespace asst // 这是下面几个函数的封装 std::shared_ptr generate_task_info(const std::string& name, const json::value&, std::shared_ptr default_ptr, - const std::string& task_prefix = ""); + std::string_view task_prefix = ""); std::shared_ptr generate_match_task_info(const std::string& name, const json::value&, std::shared_ptr default_ptr); @@ -82,10 +43,10 @@ namespace asst // TaskInfo 的基础成员 bool append_base_task_info(std::shared_ptr task_info_ptr, const std::string& name, const json::value& task_json, std::shared_ptr default_ptr, - std::string task_prefix = ""); + std::string_view task_prefix = ""); static std::vector append_prefix(const std::vector& base_task_list, - const std::string& task_prefix) + std::string_view task_prefix) { if (task_prefix.empty()) { return base_task_list; @@ -108,7 +69,7 @@ namespace asst task_list.emplace_back(base); } else { - task_list.emplace_back(task_prefix + "@" + base); + task_list.emplace_back(std::string(task_prefix) + "@" + base); } } return task_list;