From 1e102443d3d84d86c967d8ff9f71e34dc7f2077c Mon Sep 17 00:00:00 2001 From: guoh064 <50830808+guoh064@users.noreply.github.com> Date: Sat, 4 Apr 2026 13:56:07 +0800 Subject: [PATCH] Add: Raid Scuttle function --- alas.py | 4 + assets/cn/raid/RAID_FLEET_FLAGSHIP.png | Bin 0 -> 9632 bytes assets/cn/raid/RAID_FLEET_VANGUARD.png | Bin 0 -> 9340 bytes config/template.json | 74 +++++ module/combat/combat.py | 4 +- module/config/argument/args.json | 437 +++++++++++++++++++++++++ module/config/argument/argument.yaml | 4 + module/config/argument/menu.json | 1 + module/config/argument/override.yaml | 45 +++ module/config/argument/task.yaml | 9 + module/config/config_generated.py | 3 + module/config/config_manual.py | 2 +- module/config/config_updater.py | 2 +- module/config/i18n/en-US.json | 16 + module/config/i18n/ja-JP.json | 16 + module/config/i18n/zh-CN.json | 16 + module/config/i18n/zh-TW.json | 16 + module/raid/assets.py | 2 + module/raid/scuttle.py | 248 ++++++++++++++ 19 files changed, 895 insertions(+), 4 deletions(-) create mode 100644 assets/cn/raid/RAID_FLEET_FLAGSHIP.png create mode 100644 assets/cn/raid/RAID_FLEET_VANGUARD.png create mode 100644 module/raid/scuttle.py diff --git a/alas.py b/alas.py index bd6da18f4..55e40364f 100644 --- a/alas.py +++ b/alas.py @@ -396,6 +396,10 @@ class AzurLaneAutoScript: from module.raid.run import RaidRun RaidRun(config=self.config, device=self.device).run() + def raid_scuttle(self): + from module.raid.scuttle import RaidScuttleRun + RaidScuttleRun(config=self.config, device=self.device).run() + def hospital(self): from module.event_hospital.hospital import Hospital Hospital(config=self.config, device=self.device).run() diff --git a/assets/cn/raid/RAID_FLEET_FLAGSHIP.png b/assets/cn/raid/RAID_FLEET_FLAGSHIP.png new file mode 100644 index 0000000000000000000000000000000000000000..e52b21328618b76b4cad02591dd8d973636d47dd GIT binary patch literal 9632 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 QC6lqSw71AR;C24L0AaxIO#lD@ literal 0 HcmV?d00001 diff --git a/assets/cn/raid/RAID_FLEET_VANGUARD.png b/assets/cn/raid/RAID_FLEET_VANGUARD.png new file mode 100644 index 0000000000000000000000000000000000000000..ca40b01a3c0cc777229dd86bef6ab68987d84d8b GIT binary patch literal 9340 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 literal 0 HcmV?d00001 diff --git a/config/template.json b/config/template.json index 421a8402a..4ce994859 100644 --- a/config/template.json +++ b/config/template.json @@ -760,6 +760,80 @@ "Storage": {} } }, + "RaidScuttle": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "RaidScuttle", + "SuccessInterval": 0, + "FailureInterval": 120, + "ServerUpdate": "00:00" + }, + "RaidScuttle": { + "Sacrifice": "vanguard" + }, + "Raid": { + "Mode": "hard", + "UseTicket": false + }, + "Campaign": { + "Name": "dynamic", + "Event": "campaign_main", + "Mode": "normal", + "UseClearMode": true, + "UseFleetLock": true, + "UseAutoSearch": false, + "Use2xBook": false, + "AmbushEvade": true, + "ClearAfterSinking": false + }, + "StopCondition": { + "OilLimit": 1000, + "RunCount": 0, + "MapAchievement": "non_stop", + "StageIncrease": false, + "GetNewShip": false, + "ReachLevel": 0 + }, + "Fleet": { + "Fleet1": 1, + "Fleet1Formation": "double_line", + "Fleet1Mode": "combat_auto", + "Fleet1Step": 3, + "Fleet2": 2, + "Fleet2Formation": "double_line", + "Fleet2Mode": "combat_auto", + "Fleet2Step": 3, + "FleetOrder": "fleet1_all_fleet2_standby" + }, + "Submarine": { + "Fleet": 0, + "AutoRecommend": false, + "AutoSearchMode": "sub_standby", + "HuntMode": "do_not_use", + "CallMode": "do_not_use", + "Timing": "default", + "DistanceToBoss": "2_grid_to_boss" + }, + "Emotion": { + "Mode": "calculate_ignore", + "Fleet1Value": 119, + "Fleet1Record": "2020-01-01 00:00:00", + "Fleet1Control": "prevent_yellow_face", + "Fleet1Recover": "not_in_dormitory", + "Fleet1Oath": false, + "Fleet1Onsen": false, + "Fleet2Value": 119, + "Fleet2Record": "2020-01-01 00:00:00", + "Fleet2Control": "prevent_yellow_face", + "Fleet2Recover": "not_in_dormitory", + "Fleet2Oath": false, + "Fleet2Onsen": false + }, + "Storage": { + "Storage": {} + } + }, "Hospital": { "Scheduler": { "Enable": false, diff --git a/module/combat/combat.py b/module/combat/combat.py index 4056458da..8b8f6d3bb 100644 --- a/module/combat/combat.py +++ b/module/combat/combat.py @@ -294,7 +294,7 @@ class Combat(Level, HPBalancer, Retirement, SubmarineCall, CombatAuto, CombatMan if not self._automation_set_timer.reached(): return False - if self.appear(AUTOMATION_ON): + if self.appear(AUTOMATION_ON, offset=(60, 10)): logger.info('[Automation] ON') if not auto: self.device.click(AUTOMATION_SWITCH) @@ -302,7 +302,7 @@ class Combat(Level, HPBalancer, Retirement, SubmarineCall, CombatAuto, CombatMan self._automation_set_timer.reset() return True - if self.appear(AUTOMATION_OFF): + if self.appear(AUTOMATION_OFF, offset=(60, 10)): logger.info('[Automation] OFF') if auto: self.device.click(AUTOMATION_SWITCH) diff --git a/module/config/argument/args.json b/module/config/argument/args.json index d6580a93b..eb9dcc7d2 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -3817,6 +3817,443 @@ } } }, + "RaidScuttle": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false, + "option": [ + true, + false + ] + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "RaidScuttle", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 0, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "00:00", + "display": "hide" + } + }, + "RaidScuttle": { + "Sacrifice": { + "type": "select", + "value": "vanguard", + "option": [ + "vanguard", + "flagship" + ] + } + }, + "Raid": { + "Mode": { + "type": "select", + "value": "hard", + "option": [ + "easy", + "normal", + "hard", + "ex" + ] + }, + "UseTicket": { + "type": "checkbox", + "value": false + } + }, + "Campaign": { + "Name": { + "type": "input", + "value": "dynamic", + "display": "hide" + }, + "Event": { + "type": "state", + "value": "campaign_main", + "option": [ + "raid_20260212" + ], + "option_cn": [ + "raid_20260212" + ], + "option_en": [ + "raid_20260212" + ], + "option_jp": [ + "raid_20260212" + ], + "option_tw": [ + "raid_20260212" + ], + "option_bold": [ + "raid_20260212" + ] + }, + "Mode": { + "type": "select", + "value": "normal", + "option": [ + "normal", + "hard" + ], + "display": "hide" + }, + "UseClearMode": { + "type": "checkbox", + "value": true, + "display": "hide" + }, + "UseFleetLock": { + "type": "checkbox", + "value": true, + "display": "hide" + }, + "UseAutoSearch": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "Use2xBook": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "AmbushEvade": { + "type": "checkbox", + "value": true, + "display": "hide" + }, + "ClearAfterSinking": { + "type": "checkbox", + "value": false, + "display": "hide" + } + }, + "StopCondition": { + "OilLimit": { + "type": "input", + "value": 1000 + }, + "RunCount": { + "type": "input", + "value": 0 + }, + "MapAchievement": { + "type": "select", + "value": "non_stop", + "option": [ + "non_stop", + "non_stop_clear_all", + "100_percent_clear", + "map_3_stars", + "threat_safe", + "threat_safe_without_3_stars" + ], + "display": "hide" + }, + "StageIncrease": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "GetNewShip": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "ReachLevel": { + "type": "input", + "value": 0, + "display": "hide" + } + }, + "Fleet": { + "Fleet1": { + "type": "select", + "value": 1, + "option": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "display": "hide" + }, + "Fleet1Formation": { + "type": "select", + "value": "double_line", + "option": [ + "line_ahead", + "double_line", + "diamond" + ], + "display": "hide" + }, + "Fleet1Mode": { + "type": "select", + "value": "combat_auto", + "option": [ + "combat_auto", + "combat_manual", + "stand_still_in_the_middle", + "hide_in_bottom_left", + "hide_in_upper_left" + ] + }, + "Fleet1Step": { + "type": "select", + "value": 3, + "option": [ + 2, + 3, + 4, + 5 + ], + "display": "hide" + }, + "Fleet2": { + "type": "select", + "value": 2, + "option": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "display": "hide" + }, + "Fleet2Formation": { + "type": "select", + "value": "double_line", + "option": [ + "line_ahead", + "double_line", + "diamond" + ], + "display": "hide" + }, + "Fleet2Mode": { + "type": "select", + "value": "combat_auto", + "option": [ + "combat_auto", + "combat_manual", + "stand_still_in_the_middle", + "hide_in_bottom_left", + "hide_in_upper_left" + ], + "display": "hide" + }, + "Fleet2Step": { + "type": "select", + "value": 3, + "option": [ + 2, + 3, + 4, + 5 + ], + "display": "hide" + }, + "FleetOrder": { + "type": "select", + "value": "fleet1_all_fleet2_standby", + "option": [ + "fleet1_mob_fleet2_boss", + "fleet1_boss_fleet2_mob", + "fleet1_all_fleet2_standby", + "fleet1_standby_fleet2_all" + ], + "display": "hide" + } + }, + "Submarine": { + "Fleet": { + "type": "select", + "value": 0, + "option": [ + 0, + 1, + 2 + ] + }, + "AutoRecommend": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "AutoSearchMode": { + "type": "select", + "value": "sub_standby", + "option": [ + "sub_standby", + "sub_auto_call" + ], + "display": "hide" + }, + "HuntMode": { + "type": "select", + "value": "do_not_use", + "option": [ + "do_not_use", + "hunt" + ], + "display": "hide" + }, + "CallMode": { + "type": "select", + "value": "do_not_use", + "option": [ + "do_not_use", + "boss_only", + "every_combat" + ] + }, + "Timing": { + "type": "select", + "value": "default", + "option": [ + "default", + "wait_for_boss" + ], + "display": "hide" + }, + "DistanceToBoss": { + "type": "select", + "value": "2_grid_to_boss", + "option": [ + "to_boss_position", + "1_grid_to_boss", + "2_grid_to_boss", + "use_open_ocean_support" + ], + "display": "hide" + } + }, + "Emotion": { + "Mode": { + "type": "lock", + "value": "calculate_ignore", + "option": [ + "calculate_ignore" + ], + "option_bold": [ + "calculate_ignore" + ] + }, + "Fleet1Value": { + "type": "input", + "value": 119 + }, + "Fleet1Record": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime", + "display": "disabled" + }, + "Fleet1Control": { + "type": "select", + "value": "prevent_yellow_face", + "option": [ + "keep_exp_bonus", + "prevent_green_face", + "prevent_yellow_face", + "prevent_red_face" + ], + "display": "hide" + }, + "Fleet1Recover": { + "type": "select", + "value": "not_in_dormitory", + "option": [ + "not_in_dormitory", + "dormitory_floor_1", + "dormitory_floor_2" + ] + }, + "Fleet1Oath": { + "type": "checkbox", + "value": false + }, + "Fleet1Onsen": { + "type": "checkbox", + "value": false + }, + "Fleet2Value": { + "type": "input", + "value": 119, + "display": "hide" + }, + "Fleet2Record": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime", + "display": "hide" + }, + "Fleet2Control": { + "type": "select", + "value": "prevent_yellow_face", + "option": [ + "keep_exp_bonus", + "prevent_green_face", + "prevent_yellow_face", + "prevent_red_face" + ], + "display": "hide" + }, + "Fleet2Recover": { + "type": "select", + "value": "not_in_dormitory", + "option": [ + "not_in_dormitory", + "dormitory_floor_1", + "dormitory_floor_2" + ], + "display": "hide" + }, + "Fleet2Oath": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "Fleet2Onsen": { + "type": "checkbox", + "value": false, + "display": "hide" + } + }, + "Storage": { + "Storage": { + "type": "storage", + "value": {}, + "valuetype": "ignore", + "display": "disabled" + } + } + }, "Hospital": { "Scheduler": { "Enable": { diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 97c1d877d..1f159430d 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -348,6 +348,10 @@ Raid: value: hard option: [ easy, normal, hard, ex ] UseTicket: false +RaidScuttle: + Sacrifice: + value: vanguard + option: [ vanguard, flagship ] RaidDaily: StageFilter: |- hard > normal > easy diff --git a/module/config/argument/menu.json b/module/config/argument/menu.json index 74a1b8120..fd6317e2b 100644 --- a/module/config/argument/menu.json +++ b/module/config/argument/menu.json @@ -28,6 +28,7 @@ "Event", "Event2", "Raid", + "RaidScuttle", "Hospital", "MaritimeEscort", "WarArchives" diff --git a/module/config/argument/override.yaml b/module/config/argument/override.yaml index 291ba5e40..b2e5408ef 100644 --- a/module/config/argument/override.yaml +++ b/module/config/argument/override.yaml @@ -169,6 +169,51 @@ Raid: Fleet2Recover: not_in_dormitory Fleet2Oath: false Fleet2Onsen: false +RaidScuttle: + Campaign: + Name: dynamic + Event: + type: state + Mode: normal + UseClearMode: true + UseFleetLock: true + UseAutoSearch: false + Use2xBook: false + AmbushEvade: true + ClearAfterSinking: false + StopCondition: + MapAchievement: non_stop + StageIncrease: false + GetNewShip: false + ReachLevel: 0 + Fleet: + Fleet1: 1 + Fleet1Formation: double_line + Fleet1Step: 3 + Fleet2: 2 + Fleet2Formation: double_line + Fleet2Mode: combat_auto + Fleet2Step: 3 + FleetOrder: fleet1_all_fleet2_standby + Submarine: + AutoRecommend: false + AutoSearchMode: sub_standby + HuntMode: do_not_use + Timing: default + DistanceToBoss: 2_grid_to_boss + Emotion: + Mode: + type: lock + value: calculate_ignore + option: [ calculate_ignore ] + option_bold: [ calculate_ignore ] + Fleet1Control: prevent_yellow_face + Fleet2Value: 119 + Fleet2Record: 2020-01-01 00:00:00 + Fleet2Control: prevent_yellow_face + Fleet2Recover: not_in_dormitory + Fleet2Oath: false + Fleet2Onsen: false Hospital: StopCondition: RunCount: 0 diff --git a/module/config/argument/task.yaml b/module/config/argument/task.yaml index 8d09fe15a..af62bb056 100644 --- a/module/config/argument/task.yaml +++ b/module/config/argument/task.yaml @@ -106,6 +106,15 @@ Event: - Campaign - StopCondition - Emotion + RaidScuttle: + - Scheduler + - RaidScuttle + - Raid + - Campaign + - StopCondition + - Fleet + - Submarine + - Emotion Hospital: - Scheduler - Hospital diff --git a/module/config/config_generated.py b/module/config/config_generated.py index 3426a1774..37666eacf 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -200,6 +200,9 @@ class GeneratedConfig: Raid_Mode = 'hard' # easy, normal, hard, ex Raid_UseTicket = False + # Group `RaidScuttle` + RaidScuttle_Sacrifice = 'vanguard' # vanguard, flagship + # Group `RaidDaily` RaidDaily_StageFilter = 'hard > normal > easy' diff --git a/module/config/config_manual.py b/module/config/config_manual.py index fcc6de026..d21952216 100644 --- a/module/config/config_manual.py +++ b/module/config/config_manual.py @@ -26,7 +26,7 @@ class ManualConfig: > Daily > Hard > OpsiAshBeacon > OpsiAshAssist > OpsiMonthBoss > Sos > EventSp > EventA > EventB > EventC > EventD > RaidDaily > CoalitionSp > WarArchives > MaritimeEscort - > Event > Event2 > Raid > Hospital > HospitalEvent > Coalition > Main > Main2 > Main3 + > Event > Event2 > Raid > RaidScuttle > Hospital > HospitalEvent > Coalition > Main > Main2 > Main3 > OpsiMeowfficerFarming > GemsFarming > OpsiHazard1Leveling diff --git a/module/config/config_updater.py b/module/config/config_updater.py index 82ff87e64..39e5fbca6 100644 --- a/module/config/config_updater.py +++ b/module/config/config_updater.py @@ -33,7 +33,7 @@ ARCHIVES_PREFIX = { MAINS = ['Main', 'Main2', 'Main3'] EVENTS = ['Event', 'Event2', 'EventA', 'EventB', 'EventC', 'EventD', 'EventSp'] GEMS_FARMINGS = ['GemsFarming'] -RAIDS = ['Raid', 'RaidDaily'] +RAIDS = ['Raid', 'RaidDaily', 'RaidScuttle'] WAR_ARCHIVES = ['WarArchives'] COALITIONS = ['Coalition', 'CoalitionSp'] MARITIME_ESCORTS = ['MaritimeEscort'] diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 49f9a02c7..d0188bf3f 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -86,6 +86,10 @@ "name": "Raid", "help": "" }, + "RaidScuttle": { + "name": "Raid Scuttle", + "help": "" + }, "Hospital": { "name": "Valley Hospital Story", "help": "" @@ -1449,6 +1453,18 @@ "help": "" } }, + "RaidScuttle": { + "_info": { + "name": "Raid Scuttle", + "help": "" + }, + "Sacrifice": { + "name": "Ship to sacrifice", + "help": "", + "vanguard": "Vanguard", + "flagship": "Flagship" + } + }, "RaidDaily": { "_info": { "name": "Raid Daily Settings", diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index f805ad71a..6591e72c5 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -86,6 +86,10 @@ "name": "Raid", "help": "" }, + "RaidScuttle": { + "name": "Task.RaidScuttle.name", + "help": "Task.RaidScuttle.help" + }, "Hospital": { "name": "病院探訪ストーリー", "help": "" @@ -1449,6 +1453,18 @@ "help": "Raid.UseTicket.help" } }, + "RaidScuttle": { + "_info": { + "name": "RaidScuttle._info.name", + "help": "RaidScuttle._info.help" + }, + "Sacrifice": { + "name": "RaidScuttle.Sacrifice.name", + "help": "RaidScuttle.Sacrifice.help", + "vanguard": "vanguard", + "flagship": "flagship" + } + }, "RaidDaily": { "_info": { "name": "RaidDaily._info.name", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index a18f524d1..a4bd08b44 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -86,6 +86,10 @@ "name": "共斗活动", "help": "" }, + "RaidScuttle": { + "name": "共斗沉船", + "help": "" + }, "Hospital": { "name": "深谷来信", "help": "" @@ -1449,6 +1453,18 @@ "help": "" } }, + "RaidScuttle": { + "_info": { + "name": "共斗沉船", + "help": "" + }, + "Sacrifice": { + "name": "牺牲船位置", + "help": "", + "vanguard": "前排", + "flagship": "旗舰" + } + }, "RaidDaily": { "_info": { "name": "共斗每日", diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 9ab7907df..340096db3 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -86,6 +86,10 @@ "name": "共鬥活動", "help": "" }, + "RaidScuttle": { + "name": "共鬥鑿船", + "help": "" + }, "Hospital": { "name": "深谷来信", "help": "" @@ -1449,6 +1453,18 @@ "help": "" } }, + "RaidScuttle": { + "_info": { + "name": "共鬥鑿船", + "help": "" + }, + "Sacrifice": { + "name": "牺牲船位置", + "help": "", + "vanguard": "前排", + "flagship": "旗舰" + } + }, "RaidDaily": { "_info": { "name": "共鬥每日", diff --git a/module/raid/assets.py b/module/raid/assets.py index 172c02e78..109b6a07d 100644 --- a/module/raid/assets.py +++ b/module/raid/assets.py @@ -75,7 +75,9 @@ KUYBYSHEY_RAID_EASY = Button(area={'cn': (1073, 503, 1124, 529), 'en': (1073, 50 KUYBYSHEY_RAID_EX = Button(area={'cn': (1082, 189, 1146, 217), 'en': (1082, 189, 1146, 217), 'jp': (1082, 189, 1146, 217), 'tw': (1082, 189, 1146, 217)}, color={'cn': (160, 174, 191), 'en': (160, 174, 191), 'jp': (160, 174, 191), 'tw': (160, 174, 191)}, button={'cn': (1082, 189, 1146, 217), 'en': (1082, 189, 1146, 217), 'jp': (1082, 189, 1146, 217), 'tw': (1082, 189, 1146, 217)}, file={'cn': './assets/cn/raid/KUYBYSHEY_RAID_EX.png', 'en': './assets/en/raid/KUYBYSHEY_RAID_EX.png', 'jp': './assets/cn/raid/KUYBYSHEY_RAID_EX.png', 'tw': './assets/tw/raid/KUYBYSHEY_RAID_EX.png'}) KUYBYSHEY_RAID_HARD = Button(area={'cn': (1073, 345, 1125, 371), 'en': (1074, 344, 1125, 372), 'jp': (1064, 348, 1127, 369), 'tw': (1075, 346, 1122, 373)}, color={'cn': (91, 100, 114), 'en': (84, 93, 107), 'jp': (85, 94, 108), 'tw': (101, 110, 124)}, button={'cn': (1073, 345, 1125, 371), 'en': (1074, 344, 1125, 372), 'jp': (1064, 348, 1127, 369), 'tw': (1075, 346, 1122, 373)}, file={'cn': './assets/cn/raid/KUYBYSHEY_RAID_HARD.png', 'en': './assets/en/raid/KUYBYSHEY_RAID_HARD.png', 'jp': './assets/jp/raid/KUYBYSHEY_RAID_HARD.png', 'tw': './assets/tw/raid/KUYBYSHEY_RAID_HARD.png'}) KUYBYSHEY_RAID_NORMAL = Button(area={'cn': (1045, 423, 1097, 451), 'en': (1036, 424, 1099, 449), 'jp': (1048, 427, 1091, 448), 'tw': (1044, 423, 1096, 452)}, color={'cn': (86, 95, 109), 'en': (81, 92, 105), 'jp': (131, 143, 154), 'tw': (86, 95, 109)}, button={'cn': (1045, 423, 1097, 451), 'en': (1036, 424, 1099, 449), 'jp': (1048, 427, 1091, 448), 'tw': (1044, 423, 1096, 452)}, file={'cn': './assets/cn/raid/KUYBYSHEY_RAID_NORMAL.png', 'en': './assets/en/raid/KUYBYSHEY_RAID_NORMAL.png', 'jp': './assets/jp/raid/KUYBYSHEY_RAID_NORMAL.png', 'tw': './assets/tw/raid/KUYBYSHEY_RAID_NORMAL.png'}) +RAID_FLEET_FLAGSHIP = Button(area={'cn': (402, 168, 462, 228), 'en': (402, 168, 462, 228), 'jp': (402, 168, 462, 228), 'tw': (402, 168, 462, 228)}, color={'cn': (73, 61, 55), 'en': (73, 61, 55), 'jp': (73, 61, 55), 'tw': (73, 61, 55)}, button={'cn': (402, 168, 462, 228), 'en': (402, 168, 462, 228), 'jp': (402, 168, 462, 228), 'tw': (402, 168, 462, 228)}, file={'cn': './assets/cn/raid/RAID_FLEET_FLAGSHIP.png', 'en': './assets/cn/raid/RAID_FLEET_FLAGSHIP.png', 'jp': './assets/cn/raid/RAID_FLEET_FLAGSHIP.png', 'tw': './assets/cn/raid/RAID_FLEET_FLAGSHIP.png'}) RAID_FLEET_PREPARATION = Button(area={'cn': (983, 577, 1181, 638), 'en': (1041, 592, 1121, 631), 'jp': (983, 579, 1180, 635), 'tw': (983, 577, 1181, 638)}, color={'cn': (236, 188, 115), 'en': (236, 184, 117), 'jp': (235, 183, 103), 'tw': (236, 188, 115)}, button={'cn': (983, 577, 1181, 638), 'en': (1041, 592, 1121, 631), 'jp': (983, 579, 1180, 635), 'tw': (983, 577, 1181, 638)}, file={'cn': './assets/cn/raid/RAID_FLEET_PREPARATION.png', 'en': './assets/en/raid/RAID_FLEET_PREPARATION.png', 'jp': './assets/jp/raid/RAID_FLEET_PREPARATION.png', 'tw': './assets/tw/raid/RAID_FLEET_PREPARATION.png'}) +RAID_FLEET_VANGUARD = Button(area={'cn': (718, 168, 778, 228), 'en': (718, 168, 778, 228), 'jp': (718, 168, 778, 228), 'tw': (718, 168, 778, 228)}, color={'cn': (51, 50, 54), 'en': (51, 50, 54), 'jp': (51, 50, 54), 'tw': (51, 50, 54)}, button={'cn': (718, 168, 778, 228), 'en': (718, 168, 778, 228), 'jp': (718, 168, 778, 228), 'tw': (718, 168, 778, 228)}, file={'cn': './assets/cn/raid/RAID_FLEET_VANGUARD.png', 'en': './assets/cn/raid/RAID_FLEET_VANGUARD.png', 'jp': './assets/cn/raid/RAID_FLEET_VANGUARD.png', 'tw': './assets/cn/raid/RAID_FLEET_VANGUARD.png'}) RAID_REWARDS = Button(area={'cn': (836, 127, 900, 169), 'en': (836, 127, 900, 169), 'jp': (836, 127, 900, 169), 'tw': (836, 127, 900, 169)}, color={'cn': (217, 103, 98), 'en': (217, 103, 98), 'jp': (217, 103, 98), 'tw': (217, 103, 98)}, button={'cn': (836, 127, 900, 169), 'en': (836, 127, 900, 169), 'jp': (836, 127, 900, 169), 'tw': (836, 127, 900, 169)}, file={'cn': './assets/cn/raid/RAID_REWARDS.png', 'en': './assets/en/raid/RAID_REWARDS.png', 'jp': './assets/jp/raid/RAID_REWARDS.png', 'tw': './assets/tw/raid/RAID_REWARDS.png'}) RPG_BACK = Button(area={'cn': (40, 30, 59, 57), 'en': (40, 30, 59, 57), 'jp': (40, 30, 59, 57), 'tw': (40, 30, 59, 57)}, color={'cn': (154, 127, 105), 'en': (154, 127, 105), 'jp': (154, 127, 105), 'tw': (154, 127, 105)}, button={'cn': (40, 30, 59, 57), 'en': (40, 30, 59, 57), 'jp': (40, 30, 59, 57), 'tw': (40, 30, 59, 57)}, file={'cn': './assets/cn/raid/RPG_BACK.png', 'en': './assets/en/raid/RPG_BACK.png', 'jp': './assets/jp/raid/RPG_BACK.png', 'tw': './assets/tw/raid/RPG_BACK.png'}) RPG_GOTO_STAGE = Button(area={'cn': (55, 495, 80, 520), 'en': (55, 495, 80, 520), 'jp': (55, 495, 80, 520), 'tw': (55, 495, 80, 520)}, color={'cn': (174, 168, 160), 'en': (174, 168, 160), 'jp': (174, 168, 160), 'tw': (174, 168, 160)}, button={'cn': (55, 495, 80, 520), 'en': (55, 495, 80, 520), 'jp': (55, 495, 80, 520), 'tw': (55, 495, 80, 520)}, file={'cn': './assets/cn/raid/RPG_GOTO_STAGE.png', 'en': './assets/en/raid/RPG_GOTO_STAGE.png', 'jp': './assets/jp/raid/RPG_GOTO_STAGE.png', 'tw': './assets/tw/raid/RPG_GOTO_STAGE.png'}) diff --git a/module/raid/scuttle.py b/module/raid/scuttle.py new file mode 100644 index 000000000..1b5aef3ce --- /dev/null +++ b/module/raid/scuttle.py @@ -0,0 +1,248 @@ +from module.combat.assets import OPTS_INFO_D, BATTLE_STATUS_D, EXP_INFO_D, BATTLE_STATUS_C, EXP_INFO_C +from module.exception import ScriptError, CampaignEnd +from module.logger import logger +from module.raid.assets import RAID_FLEET_PREPARATION, RAID_FLEET_VANGUARD, RAID_FLEET_FLAGSHIP +from module.raid.combat import RaidCombat +from module.raid.raid import raid_entrance +from module.raid.run import RaidRun +from module.retire.assets import DOCK_CHECK +from module.retire.dock import Dock +from module.retire.scanner import ShipScanner +from module.ui.page import page_raid, page_rpg_stage + + +class RaidScuttleCombat(RaidCombat): + triggered_normal_end = False + + def handle_battle_status(self, drop=None): + """ + Args: + drop (DropImage): + + Returns: + bool: + """ + if self.is_combat_executing(): + return False + if self.appear(BATTLE_STATUS_D, interval=self.battle_status_click_interval): + if drop: + drop.handle_add(self) + else: + self.device.sleep((0.25, 0.5)) + self.device.click(BATTLE_STATUS_D) + return True + if self.appear(OPTS_INFO_D, interval=self.battle_status_click_interval): + if drop: + drop.handle_add(self) + else: + self.device.sleep((0.25, 0.5)) + self.device.click(OPTS_INFO_D) + return True + if super().handle_battle_status(drop=drop): + logger.warning("Triggered normal end") + self.triggered_normal_end = True + return True + + return False + + def handle_exp_info(self): + """ + Returns: + bool: + """ + if self.is_combat_executing(): + return False + if self.appear_then_click(EXP_INFO_D): + self.device.sleep((0.25, 0.5)) + return True + if super().handle_exp_info(): + return True + + return False + + def handle_combat_weapon_release(self): + return False + + +class RaidScuttleRun(RaidRun, RaidScuttleCombat, Dock): + @property + def manual_mode(self): + return self.config.Fleet_Fleet1Mode + + @property + def change_vanguard(self): + return 'vanguard' in self.config.RaidScuttle_Sacrifice + + @property + def change_flagship(self): + return 'flagship' in self.config.RaidScuttle_Sacrifice + + def triggered_stop_condition(self, oil_check=False, pt_check=False, coin_check=False): + if self.triggered_normal_end: + return True + if super().triggered_stop_condition(oil_check, pt_check, coin_check): + return True + + return False + + def raid_enter_preparation(self, mode, raid, skip_first_screenshot=True): + """ + Args: + mode: + raid: + skip_first_screenshot: + + Pages: + in: page_raid + out: BATTLE_PREPARATION + """ + # UI ensure + self.device.stuck_record_clear() + self.device.click_record_clear() + if not self.is_raid_rpg(): + self.ui_ensure(page_raid) + else: + self.ui_ensure(page_rpg_stage) + self.raid_rpg_swipe() + entrance = raid_entrance(raid=raid, mode=mode) + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if self.appear(entrance, offset=(10, 10), interval=5): + self.device.click(entrance) + continue + + # End + if self.appear_then_click(RAID_FLEET_PREPARATION, offset=(20, 20), interval=5): + break + + def combat_auto_reset(self): + pass + + def raid_execute_once(self, mode, raid): + """ + Args: + mode: + raid: + + Returns: + in: page_raid + out: page_raid + """ + logger.hr('Raid Execute') + self.config.override( + Campaign_Name=f'{raid}_{mode}', + Campaign_UseAutoSearch=False, + Fleet_FleetOrder='fleet1_all_fleet2_standby' + ) + + if mode == 'ex': + backup = self.config.temporary( + Submarine_Fleet=1, + Submarine_Mode='every_combat' + ) + + self.emotion.check_reduce(1) + + self.raid_enter(mode=mode, raid=raid) + self.combat(balance_hp=False, auto_mode=self.manual_mode, expected_end=self.raid_expected_end) + + if mode == 'ex': + backup.recover() + + logger.hr('Raid End') + + def get_common_rarity_ship(self, index='all'): + self.dock_favourite_set(False, wait_loading=False) + self.dock_sort_method_dsc_set(False, wait_loading=False) + self.dock_filter_set( + index=index, rarity='common', extra='enhanceable', sort='total' + ) + + logger.hr('FINDING SHIP') + + scanner = ShipScanner(level=(1, 31), fleet=0, status='free') + scanner.disable('rarity') + + return scanner.scan(self.device.image) + + def vanguard_change(self): + logger.hr('Change vanguard', level=2) + for _ in self.loop(): + if self.appear(DOCK_CHECK, offset=(20, 20)): + break + if self.appear(RAID_FLEET_PREPARATION, offset=(20, 20)): + self.device.click(RAID_FLEET_VANGUARD) + continue + + ship = self.get_common_rarity_ship(index='vanguard') + if ship: + self._ship_change_confirm(min(ship, key=lambda s: (s.level, -s.emotion)).button) + logger.info('Change vanguard success') + return True + else: + logger.info('Change vanguard failed, no vanguard in common rarity.') + self._dock_reset() + self.ui_back(check_button=RAID_FLEET_PREPARATION) + return False + + def flagship_change(self): + logger.hr('Change flagship', level=2) + for _ in self.loop(): + if self.appear(DOCK_CHECK, offset=(20, 20)): + break + if self.appear(RAID_FLEET_PREPARATION, offset=(20, 20)): + self.device.click(RAID_FLEET_FLAGSHIP) + continue + + ship = self.get_common_rarity_ship(index='main') + if ship: + self._ship_change_confirm(min(ship, key=lambda s: (s.level, -s.emotion)).button) + logger.info('Change flagship success') + return True + else: + logger.info('Change flagship failed, no flagship in common rarity.') + self._dock_reset() + self.ui_back(check_button=RAID_FLEET_PREPARATION) + return False + + def run(self, name='', mode='', total=0): + """ + Args: + name (str): Raid name, such as 'raid_20200624' + mode (str): Raid mode, such as 'hard', 'normal', 'easy' + total (int): Total run count + """ + name = name if name else self.config.Campaign_Event + mode = mode if mode else self.config.Raid_Mode + if not name or not mode: + raise ScriptError(f'RaidRun arguments unfilled. name={name}, mode={mode}') + + while 1: + super().run(name=name, mode=mode, total=total) + + # End + if self.triggered_normal_end: + self.raid_enter_preparation(mode=mode, raid=name, skip_first_screenshot=False) + success = True + if self.change_vanguard: + success = self.vanguard_change() + if self.change_flagship: + success = success and self.flagship_change() + + self.enter_map_cancel(skip_first_screenshot=False) + self.triggered_normal_end = False + + # Scheduler + if self.config.task_switched(): + self.campaign.ensure_auto_search_exit() + self.config.task_stop() + elif not success: + self.campaign.ensure_auto_search_exit() + self.config.task_delay(minute=30) + self.config.task_stop() + else: + break