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 )
182233 self .ui_back (check_button = check_button )
@@ -245,6 +296,7 @@ def get_common_rarity_cv(self, max_level=31, min_emotion=0):
245296 candidates = self .find_candidates (templates , scanner , output = True )
246297 return candidates
247298
299+ @Config .when (Campaign_Mode = 'normal' )
248300 def flagship_change_execute (self ):
249301 self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = False )
250302 candidate = self .get_common_rarity_cv ()
@@ -263,6 +315,40 @@ def flagship_change_execute(self):
263315 self .ui_leave_ship ()
264316 return False
265317
318+ @Config .when (Campaign_Mode = 'hard' )
319+ def flagship_change_execute (self ):
320+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_1' ]
321+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_3' ]
322+
323+ self .ui_enter_ship (unmount_button , long_click = False )
324+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
325+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
326+
327+ self .ui_enter_ship (mount_button , long_click = False )
328+ candidate = self .get_common_rarity_cv (max_level = 31 , min_emotion = self .min_emotion )
329+ if candidate :
330+ ship = max (candidate , key = lambda s : (s .level , s .emotion ))
331+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
332+ self .dock_select_one (ship .button )
333+ self .dock_reset ()
334+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
335+ logger .info ('Change flagship success' )
336+ return True
337+
338+ logger .info ('Change flagship failed, try using leveled and exhausted CVs.' )
339+ candidate = self .get_common_rarity_cv (max_level = self .max_level , min_emotion = 0 )
340+ if candidate :
341+ ship = min (candidate , key = lambda s : (s .level , - s .emotion ))
342+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
343+ self .dock_select_one (ship .button )
344+ self .dock_reset ()
345+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
346+ return False
347+ else :
348+ # This should not happen in general since the ship unmounted is also a candidate,
349+ # but just in case, we raise human takeover instead of leaving the flagship empty.
350+ raise RequestHumanTakeover ('No CV was found, please change flagship manually.' )
351+
266352 def flagship_change (self ):
267353 """
268354 Change flagship and flagship's equipment
@@ -273,10 +359,11 @@ def flagship_change(self):
273359 logger .hr ('Change flagship' , level = 1 )
274360 logger .attr ('ChangeFlagship' , self .config .GemsFarming_ChangeFlagship )
275361 self .ui_goto_fleet ()
362+ button = self .fleet_backline_1_button
276363
277364 if self .change_flagship_equip :
278365 logger .hr ('Unmount flagship equipments' , level = 2 )
279- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
366+ self .ui_enter_ship (button , long_click = True )
280367 self .ship_equipment_take_off ()
281368 self .ui_leave_ship ()
282369
@@ -285,7 +372,7 @@ def flagship_change(self):
285372
286373 if self .change_flagship_equip :
287374 logger .hr ('Mount flagship equipments' , level = 2 )
288- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
375+ self .ui_enter_ship (button , long_click = True )
289376 self .ship_equipment_take_on ()
290377 self .ui_leave_ship ()
291378
@@ -353,6 +440,7 @@ def get_common_rarity_dd(self, min_emotion=0):
353440 candidates = self .find_candidates (templates , scanner , output = True )
354441 return candidates
355442
443+ @Config .when (Campaign_Mode = 'normal' )
356444 def vanguard_change_execute (self ):
357445 self .ui_enter_ship (FLEET_ENTER , long_click = False )
358446 candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
@@ -371,6 +459,40 @@ def vanguard_change_execute(self):
371459 self .ui_leave_ship ()
372460 return False
373461
462+ @Config .when (Campaign_Mode = 'hard' )
463+ def vanguard_change_execute (self ):
464+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_1' ]
465+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_3' ]
466+
467+ self .ui_enter_ship (unmount_button , long_click = False )
468+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
469+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
470+
471+ self .ui_enter_ship (mount_button , long_click = False )
472+ candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
473+ if candidate :
474+ ship = max (candidate , key = lambda s : s .emotion )
475+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
476+ self .dock_select_one (ship .button )
477+ self .dock_reset ()
478+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
479+ logger .info ('Change vanguard success' )
480+ return True
481+
482+ logger .info ('Change vanguard failed, try using exhausted DDs.' )
483+ candidate = self .get_common_rarity_dd (min_emotion = 0 )
484+ if candidate :
485+ ship = max (candidate , key = lambda s : s .emotion )
486+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
487+ self .dock_select_one (ship .button )
488+ self .dock_reset ()
489+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
490+ return False
491+ else :
492+ # This should not happen in general since the ship unmounted is also a candidate,
493+ # but just in case, we raise human takeover instead of leaving the vanguard slot empty.
494+ raise RequestHumanTakeover ('No DD was found, please change vanguard manually.' )
495+
374496 def vanguard_change (self ):
375497 """
376498 Change vanguard and vanguard's equipment
@@ -381,10 +503,11 @@ def vanguard_change(self):
381503 logger .hr ('Change vanguard' , level = 1 )
382504 logger .attr ('ChangeVanguard' , self .config .GemsFarming_ChangeVanguard )
383505 self .ui_goto_fleet ()
506+ button = self .fleet_vanguard_1_button
384507
385508 if self .change_vanguard_equip :
386509 logger .hr ('Unmount vanguard equipments' , level = 2 )
387- self .ui_enter_ship (FLEET_ENTER , long_click = True )
510+ self .ui_enter_ship (button , long_click = True )
388511 self .ship_equipment_take_off ()
389512 self .ui_leave_ship ()
390513
@@ -393,7 +516,7 @@ def vanguard_change(self):
393516
394517 if self .change_vanguard_equip :
395518 logger .hr ('Mount vanguard equipments' , level = 2 )
396- self .ui_enter_ship (FLEET_ENTER , long_click = True )
519+ self .ui_enter_ship (button , long_click = True )
397520 self .ship_equipment_take_on ()
398521 self .ui_leave_ship ()
399522
0 commit comments