22
33import numpy as np
44
5- from module .base .decorator import cached_property
5+ from module .base .decorator import Config , cached_property
6+ from module .base .timer import Timer
67from module .campaign .campaign_base import CampaignBase
78from module .campaign .run import CampaignRun
89from module .combat .assets import BATTLE_PREPARATION
910from module .combat .emotion import Emotion
1011from module .equipment .assets import *
1112from module .equipment .equipment import Equipment
12- from module .exception import CampaignEnd
13+ from module .exception import CampaignEnd , RequestHumanTakeover
1314from module .handler .assets import AUTO_SEARCH_MAP_OPTION_OFF
1415from module .logger import logger
1516from module .map .assets import FLEET_PREPARATION , MAP_PREPARATION
@@ -141,13 +142,21 @@ def min_emotion(self):
141142
142143 _new_fleet_emotion = 0
143144
145+ @property
146+ def fleet_to_attack (self ):
147+ if self .config .Fleet_FleetOrder == 'fleet1_standby_fleet2_all' :
148+ return 2
149+ else :
150+ return 1
151+
144152 @property
145153 def fleet_to_attack_index (self ):
146154 if self .config .Fleet_FleetOrder == 'fleet1_standby_fleet2_all' :
147155 return self .config .Fleet_Fleet2
148156 else :
149157 return self .config .Fleet_Fleet1
150158
159+ @Config .when (Campaign_Mode = 'normal' )
151160 def ui_goto_fleet (self ):
152161 self .ui_ensure (page_fleet )
153162 self .ui_ensure_index (self .fleet_to_attack_index ,
@@ -156,6 +165,48 @@ def ui_goto_fleet(self):
156165 prev_button = FLEET_PREV ,
157166 skip_first_screenshot = True )
158167
168+ @Config .when (Campaign_Mode = 'hard' )
169+ def ui_goto_fleet (self ):
170+ if self .appear (FLEET_PREPARATION , offset = (20 , 50 )):
171+ return
172+ self .campaign .ensure_campaign_ui (self .stage , 'hard' )
173+ self .campaign .ENTRANCE .area = self .campaign .ENTRANCE .button
174+ campaign_timer = Timer (5 )
175+ map_timer = Timer (5 )
176+ for _ in self .loop ():
177+ if self .appear (FLEET_PREPARATION , offset = (20 , 50 )):
178+ break
179+ if map_timer .reached () \
180+ and self .campaign .handle_map_mode_switch ('hard' ) \
181+ and self .campaign .handle_map_preparation ():
182+ self .device .click (MAP_PREPARATION )
183+ map_timer .reset ()
184+ campaign_timer .reset ()
185+ # Retire
186+ if self .campaign .handle_retirement ():
187+ continue
188+ if campaign_timer .reached () and self .appear_then_click (self .campaign .ENTRANCE ):
189+ campaign_timer .reset ()
190+ continue
191+
192+ @property
193+ def fleet_check_button (self ):
194+ if self .config .Campaign_Mode == 'hard' :
195+ return FLEET_PREPARATION
196+ return page_fleet .check_button
197+
198+ @property
199+ def fleet_backline_1_button (self ):
200+ if self .config .Campaign_Mode == 'hard' :
201+ return globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_1' ]
202+ return FLEET_ENTER_FLAGSHIP
203+
204+ @property
205+ def fleet_vanguard_1_button (self ):
206+ if self .config .Campaign_Mode == 'hard' :
207+ return globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_1' ]
208+ return FLEET_ENTER
209+
159210 def ui_enter_ship (self , click_button , long_click = True ):
160211 if long_click :
161212 enter_button_map = {
@@ -167,7 +218,7 @@ def ui_enter_ship(self, click_button, long_click=True):
167218 self .ship_info_enter (click_button = click_button , long_click = True , skip_first_screenshot = False )
168219 return
169220
170- self .ui_click (FLEET_DETAIL , appear_button = page_fleet . check_button ,
221+ self .ui_click (FLEET_DETAIL , appear_button = self . fleet_check_button ,
171222 check_button = FLEET_DETAIL_CHECK , skip_first_screenshot = True )
172223 self .ship_info_enter (enter_button , long_click = False )
173224 else :
@@ -176,7 +227,7 @@ def ui_enter_ship(self, click_button, long_click=True):
176227
177228 def ui_leave_ship (self , check_button = None ):
178229 if check_button is None :
179- check_button = page_fleet . check_button
230+ check_button = self . fleet_check_button
180231 if check_button == page_fleet .check_button :
181232 self .ui_back (check_button = [FLEET_DETAIL_CHECK , page_fleet .check_button ])
182233 if self .appear (FLEET_DETAIL_CHECK , offset = (20 , 20 )):
@@ -248,6 +299,7 @@ def get_common_rarity_cv(self, max_level=31, min_emotion=0):
248299 candidates = self .find_candidates (templates , scanner , output = True )
249300 return candidates
250301
302+ @Config .when (Campaign_Mode = 'normal' )
251303 def flagship_change_execute (self ):
252304 self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = False )
253305 candidate = self .get_common_rarity_cv ()
@@ -266,6 +318,40 @@ def flagship_change_execute(self):
266318 self .ui_leave_ship ()
267319 return False
268320
321+ @Config .when (Campaign_Mode = 'hard' )
322+ def flagship_change_execute (self ):
323+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_1' ]
324+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_3' ]
325+
326+ self .ui_enter_ship (unmount_button , long_click = False )
327+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
328+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
329+
330+ self .ui_enter_ship (mount_button , long_click = False )
331+ candidate = self .get_common_rarity_cv (max_level = 31 , min_emotion = self .min_emotion )
332+ if candidate :
333+ ship = max (candidate , key = lambda s : (s .level , s .emotion ))
334+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
335+ self .dock_select_one (ship .button )
336+ self .dock_reset ()
337+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
338+ logger .info ('Change flagship success' )
339+ return True
340+
341+ logger .info ('Change flagship failed, try using leveled and exhausted CVs.' )
342+ candidate = self .get_common_rarity_cv (max_level = self .max_level , min_emotion = 0 )
343+ if candidate :
344+ ship = min (candidate , key = lambda s : (s .level , - s .emotion ))
345+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
346+ self .dock_select_one (ship .button )
347+ self .dock_reset ()
348+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
349+ return False
350+ else :
351+ # This should not happen in general since the ship unmounted is also a candidate,
352+ # but just in case, we raise human takeover instead of leaving the flagship empty.
353+ raise RequestHumanTakeover ('No CV was found, please change flagship manually.' )
354+
269355 def flagship_change (self ):
270356 """
271357 Change flagship and flagship's equipment
@@ -276,10 +362,11 @@ def flagship_change(self):
276362 logger .hr ('Change flagship' , level = 1 )
277363 logger .attr ('ChangeFlagship' , self .config .GemsFarming_ChangeFlagship )
278364 self .ui_goto_fleet ()
365+ button = self .fleet_backline_1_button
279366
280367 if self .change_flagship_equip :
281368 logger .hr ('Unmount flagship equipments' , level = 2 )
282- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
369+ self .ui_enter_ship (button , long_click = True )
283370 self .ship_equipment_take_off ()
284371 self .ui_leave_ship ()
285372
@@ -288,7 +375,7 @@ def flagship_change(self):
288375
289376 if self .change_flagship_equip :
290377 logger .hr ('Mount flagship equipments' , level = 2 )
291- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
378+ self .ui_enter_ship (button , long_click = True )
292379 self .ship_equipment_take_on ()
293380 self .ui_leave_ship ()
294381
@@ -356,6 +443,7 @@ def get_common_rarity_dd(self, min_emotion=0):
356443 candidates = self .find_candidates (templates , scanner , output = True )
357444 return candidates
358445
446+ @Config .when (Campaign_Mode = 'normal' )
359447 def vanguard_change_execute (self ):
360448 self .ui_enter_ship (FLEET_ENTER , long_click = False )
361449 candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
@@ -374,6 +462,40 @@ def vanguard_change_execute(self):
374462 self .ui_leave_ship ()
375463 return False
376464
465+ @Config .when (Campaign_Mode = 'hard' )
466+ def vanguard_change_execute (self ):
467+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_1' ]
468+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_3' ]
469+
470+ self .ui_enter_ship (unmount_button , long_click = False )
471+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
472+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
473+
474+ self .ui_enter_ship (mount_button , long_click = False )
475+ candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
476+ if candidate :
477+ ship = max (candidate , key = lambda s : s .emotion )
478+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
479+ self .dock_select_one (ship .button )
480+ self .dock_reset ()
481+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
482+ logger .info ('Change vanguard success' )
483+ return True
484+
485+ logger .info ('Change vanguard failed, try using exhausted DDs.' )
486+ candidate = self .get_common_rarity_dd (min_emotion = 0 )
487+ if candidate :
488+ ship = max (candidate , key = lambda s : s .emotion )
489+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
490+ self .dock_select_one (ship .button )
491+ self .dock_reset ()
492+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
493+ return False
494+ else :
495+ # This should not happen in general since the ship unmounted is also a candidate,
496+ # but just in case, we raise human takeover instead of leaving the vanguard slot empty.
497+ raise RequestHumanTakeover ('No DD was found, please change vanguard manually.' )
498+
377499 def vanguard_change (self ):
378500 """
379501 Change vanguard and vanguard's equipment
@@ -384,10 +506,11 @@ def vanguard_change(self):
384506 logger .hr ('Change vanguard' , level = 1 )
385507 logger .attr ('ChangeVanguard' , self .config .GemsFarming_ChangeVanguard )
386508 self .ui_goto_fleet ()
509+ button = self .fleet_vanguard_1_button
387510
388511 if self .change_vanguard_equip :
389512 logger .hr ('Unmount vanguard equipments' , level = 2 )
390- self .ui_enter_ship (FLEET_ENTER , long_click = True )
513+ self .ui_enter_ship (button , long_click = True )
391514 self .ship_equipment_take_off ()
392515 self .ui_leave_ship ()
393516
@@ -396,7 +519,7 @@ def vanguard_change(self):
396519
397520 if self .change_vanguard_equip :
398521 logger .hr ('Mount vanguard equipments' , level = 2 )
399- self .ui_enter_ship (FLEET_ENTER , long_click = True )
522+ self .ui_enter_ship (button , long_click = True )
400523 self .ship_equipment_take_on ()
401524 self .ui_leave_ship ()
402525
0 commit comments