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 000000000..e52b21328 Binary files /dev/null and b/assets/cn/raid/RAID_FLEET_FLAGSHIP.png differ diff --git a/assets/cn/raid/RAID_FLEET_VANGUARD.png b/assets/cn/raid/RAID_FLEET_VANGUARD.png new file mode 100644 index 000000000..ca40b01a3 Binary files /dev/null and b/assets/cn/raid/RAID_FLEET_VANGUARD.png differ 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