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
@@ -146,13 +147,21 @@ def min_emotion(self):
146147
147148 _new_fleet_emotion = 0
148149
150+ @property
151+ def fleet_to_attack (self ):
152+ if self .config .Fleet_FleetOrder == 'fleet1_standby_fleet2_all' :
153+ return 2
154+ else :
155+ return 1
156+
149157 @property
150158 def fleet_to_attack_index (self ):
151159 if self .config .Fleet_FleetOrder == 'fleet1_standby_fleet2_all' :
152160 return self .config .Fleet_Fleet2
153161 else :
154162 return self .config .Fleet_Fleet1
155163
164+ @Config .when (Campaign_Mode = 'normal' )
156165 def ui_goto_fleet (self ):
157166 self .ui_ensure (page_fleet )
158167 self .ui_ensure_index (self .fleet_to_attack_index ,
@@ -161,6 +170,48 @@ def ui_goto_fleet(self):
161170 prev_button = FLEET_PREV ,
162171 skip_first_screenshot = True )
163172
173+ @Config .when (Campaign_Mode = 'hard' )
174+ def ui_goto_fleet (self ):
175+ if self .appear (FLEET_PREPARATION , offset = (20 , 50 )):
176+ return
177+ self .campaign .ensure_campaign_ui (self .stage , 'hard' )
178+ self .campaign .ENTRANCE .area = self .campaign .ENTRANCE .button
179+ campaign_timer = Timer (5 )
180+ map_timer = Timer (5 )
181+ for _ in self .loop ():
182+ if self .appear (FLEET_PREPARATION , offset = (20 , 50 )):
183+ break
184+ if map_timer .reached () \
185+ and self .campaign .handle_map_mode_switch ('hard' ) \
186+ and self .campaign .handle_map_preparation ():
187+ self .device .click (MAP_PREPARATION )
188+ map_timer .reset ()
189+ campaign_timer .reset ()
190+ # Retire
191+ if self .campaign .handle_retirement ():
192+ continue
193+ if campaign_timer .reached () and self .appear_then_click (self .campaign .ENTRANCE ):
194+ campaign_timer .reset ()
195+ continue
196+
197+ @property
198+ def fleet_check_button (self ):
199+ if self .config .Campaign_Mode == 'hard' :
200+ return FLEET_PREPARATION
201+ return page_fleet .check_button
202+
203+ @property
204+ def fleet_backline_1_button (self ):
205+ if self .config .Campaign_Mode == 'hard' :
206+ return globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_1' ]
207+ return FLEET_ENTER_FLAGSHIP
208+
209+ @property
210+ def fleet_vanguard_1_button (self ):
211+ if self .config .Campaign_Mode == 'hard' :
212+ return globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_1' ]
213+ return FLEET_ENTER
214+
164215 def ui_enter_ship (self , click_button , long_click = True ):
165216 if long_click :
166217 enter_button_map = {
@@ -172,7 +223,7 @@ def ui_enter_ship(self, click_button, long_click=True):
172223 self .ship_info_enter (click_button = click_button , long_click = True , skip_first_screenshot = False )
173224 return
174225
175- self .ui_click (FLEET_DETAIL , appear_button = page_fleet . check_button ,
226+ self .ui_click (FLEET_DETAIL , appear_button = self . fleet_check_button ,
176227 check_button = FLEET_DETAIL_CHECK , skip_first_screenshot = True )
177228 self .ship_info_enter (enter_button , long_click = False )
178229 else :
@@ -181,7 +232,7 @@ def ui_enter_ship(self, click_button, long_click=True):
181232
182233 def ui_leave_ship (self , check_button = None ):
183234 if check_button is None :
184- check_button = page_fleet . check_button
235+ check_button = self . fleet_check_button
185236 if check_button == page_fleet .check_button :
186237 self .ui_back (check_button = [FLEET_DETAIL_CHECK , page_fleet .check_button ])
187238 self .ui_back (check_button = page_fleet .check_button )
@@ -252,6 +303,7 @@ def get_common_rarity_cv(self, max_level=31, min_emotion=0):
252303 candidates = self .find_candidates (templates , scanner , output = True )
253304 return candidates
254305
306+ @Config .when (Campaign_Mode = 'normal' )
255307 def flagship_change_execute (self ):
256308 self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = False )
257309 candidate = self .get_common_rarity_cv (min_emotion = self .min_emotion )
@@ -270,6 +322,40 @@ def flagship_change_execute(self):
270322 self .ui_leave_ship ()
271323 return False
272324
325+ @Config .when (Campaign_Mode = 'hard' )
326+ def flagship_change_execute (self ):
327+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_1' ]
328+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_3' ]
329+
330+ self .ui_enter_ship (unmount_button , long_click = False )
331+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
332+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
333+
334+ self .ui_enter_ship (mount_button , long_click = False )
335+ candidate = self .get_common_rarity_cv (max_level = 31 , min_emotion = self .min_emotion )
336+ if candidate :
337+ ship = max (candidate , key = lambda s : (s .level , s .emotion ))
338+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
339+ self .dock_select_one (ship .button )
340+ self .dock_reset ()
341+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
342+ logger .info ('Change flagship success' )
343+ return True
344+
345+ logger .info ('Change flagship failed, try using leveled and exhausted CVs.' )
346+ candidate = self .get_common_rarity_cv (max_level = self .max_level , min_emotion = 0 )
347+ if candidate :
348+ ship = min (candidate , key = lambda s : (s .level , - s .emotion ))
349+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
350+ self .dock_select_one (ship .button )
351+ self .dock_reset ()
352+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
353+ return False
354+ else :
355+ # This should not happen in general since the ship unmounted is also a candidate,
356+ # but just in case, we raise human takeover instead of leaving the flagship empty.
357+ raise RequestHumanTakeover ('No CV was found, please change flagship manually.' )
358+
273359 def flagship_change (self ):
274360 """
275361 Change flagship and flagship's equipment
@@ -280,10 +366,11 @@ def flagship_change(self):
280366 logger .hr ('Change flagship' , level = 1 )
281367 logger .attr ('ChangeFlagship' , self .config .GemsFarming_ChangeFlagship )
282368 self .ui_goto_fleet ()
369+ button = self .fleet_backline_1_button
283370
284371 if self .change_flagship_equip :
285372 logger .hr ('Unmount flagship equipments' , level = 2 )
286- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
373+ self .ui_enter_ship (button , long_click = True )
287374 self .ship_equipment_take_off ()
288375 self .ui_leave_ship ()
289376
@@ -292,7 +379,7 @@ def flagship_change(self):
292379
293380 if self .change_flagship_equip :
294381 logger .hr ('Mount flagship equipments' , level = 2 )
295- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
382+ self .ui_enter_ship (button , long_click = True )
296383 self .ship_equipment_take_on ()
297384 self .ui_leave_ship ()
298385
@@ -360,6 +447,7 @@ def get_common_rarity_dd(self, min_emotion=0):
360447 candidates = self .find_candidates (templates , scanner , output = True )
361448 return candidates
362449
450+ @Config .when (Campaign_Mode = 'normal' )
363451 def vanguard_change_execute (self ):
364452 self .ui_enter_ship (FLEET_ENTER , long_click = False )
365453 candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
@@ -378,6 +466,40 @@ def vanguard_change_execute(self):
378466 self .ui_leave_ship ()
379467 return False
380468
469+ @Config .when (Campaign_Mode = 'hard' )
470+ def vanguard_change_execute (self ):
471+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_1' ]
472+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_3' ]
473+
474+ self .ui_enter_ship (unmount_button , long_click = False )
475+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
476+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
477+
478+ self .ui_enter_ship (mount_button , long_click = False )
479+ candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
480+ if candidate :
481+ ship = max (candidate , key = lambda s : s .emotion )
482+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
483+ self .dock_select_one (ship .button )
484+ self .dock_reset ()
485+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
486+ logger .info ('Change vanguard success' )
487+ return True
488+
489+ logger .info ('Change vanguard failed, try using exhausted DDs.' )
490+ candidate = self .get_common_rarity_dd (min_emotion = 0 )
491+ if candidate :
492+ ship = max (candidate , key = lambda s : s .emotion )
493+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
494+ self .dock_select_one (ship .button )
495+ self .dock_reset ()
496+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
497+ return False
498+ else :
499+ # This should not happen in general since the ship unmounted is also a candidate,
500+ # but just in case, we raise human takeover instead of leaving the vanguard slot empty.
501+ raise RequestHumanTakeover ('No DD was found, please change vanguard manually.' )
502+
381503 def vanguard_change (self ):
382504 """
383505 Change vanguard and vanguard's equipment
@@ -388,10 +510,11 @@ def vanguard_change(self):
388510 logger .hr ('Change vanguard' , level = 1 )
389511 logger .attr ('ChangeVanguard' , self .config .GemsFarming_ChangeVanguard )
390512 self .ui_goto_fleet ()
513+ button = self .fleet_vanguard_1_button
391514
392515 if self .change_vanguard_equip :
393516 logger .hr ('Unmount vanguard equipments' , level = 2 )
394- self .ui_enter_ship (FLEET_ENTER , long_click = True )
517+ self .ui_enter_ship (button , long_click = True )
395518 self .ship_equipment_take_off ()
396519 self .ui_leave_ship ()
397520
@@ -400,7 +523,7 @@ def vanguard_change(self):
400523
401524 if self .change_vanguard_equip :
402525 logger .hr ('Mount vanguard equipments' , level = 2 )
403- self .ui_enter_ship (FLEET_ENTER , long_click = True )
526+ self .ui_enter_ship (button , long_click = True )
404527 self .ship_equipment_take_on ()
405528 self .ui_leave_ship ()
406529
0 commit comments