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 self .ui_back (check_button = page_fleet .check_button )
@@ -247,6 +298,7 @@ def get_common_rarity_cv(self, max_level=31, min_emotion=0):
247298 candidates = self .find_candidates (templates , scanner , output = True )
248299 return candidates
249300
301+ @Config .when (Campaign_Mode = 'normal' )
250302 def flagship_change_execute (self ):
251303 self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = False )
252304 candidate = self .get_common_rarity_cv (min_emotion = self .min_emotion )
@@ -265,6 +317,40 @@ def flagship_change_execute(self):
265317 self .ui_leave_ship ()
266318 return False
267319
320+ @Config .when (Campaign_Mode = 'hard' )
321+ def flagship_change_execute (self ):
322+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_1' ]
323+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _BACKLINE_3' ]
324+
325+ self .ui_enter_ship (unmount_button , long_click = False )
326+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
327+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
328+
329+ self .ui_enter_ship (mount_button , long_click = False )
330+ candidate = self .get_common_rarity_cv (max_level = 31 , min_emotion = self .min_emotion )
331+ if candidate :
332+ ship = max (candidate , key = lambda s : (s .level , s .emotion ))
333+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
334+ self .dock_select_one (ship .button )
335+ self .dock_reset ()
336+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
337+ logger .info ('Change flagship success' )
338+ return True
339+
340+ logger .info ('Change flagship failed, try using leveled and exhausted CVs.' )
341+ candidate = self .get_common_rarity_cv (max_level = self .max_level , min_emotion = 0 )
342+ if candidate :
343+ ship = min (candidate , key = lambda s : (s .level , - s .emotion ))
344+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
345+ self .dock_select_one (ship .button )
346+ self .dock_reset ()
347+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
348+ return False
349+ else :
350+ # This should not happen in general since the ship unmounted is also a candidate,
351+ # but just in case, we raise human takeover instead of leaving the flagship empty.
352+ raise RequestHumanTakeover ('No CV was found, please change flagship manually.' )
353+
268354 def flagship_change (self ):
269355 """
270356 Change flagship and flagship's equipment
@@ -275,10 +361,11 @@ def flagship_change(self):
275361 logger .hr ('Change flagship' , level = 1 )
276362 logger .attr ('ChangeFlagship' , self .config .GemsFarming_ChangeFlagship )
277363 self .ui_goto_fleet ()
364+ button = self .fleet_backline_1_button
278365
279366 if self .change_flagship_equip :
280367 logger .hr ('Unmount flagship equipments' , level = 2 )
281- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
368+ self .ui_enter_ship (button , long_click = True )
282369 self .ship_equipment_take_off ()
283370 self .ui_leave_ship ()
284371
@@ -287,7 +374,7 @@ def flagship_change(self):
287374
288375 if self .change_flagship_equip :
289376 logger .hr ('Mount flagship equipments' , level = 2 )
290- self .ui_enter_ship (FLEET_ENTER_FLAGSHIP , long_click = True )
377+ self .ui_enter_ship (button , long_click = True )
291378 self .ship_equipment_take_on ()
292379 self .ui_leave_ship ()
293380
@@ -355,6 +442,7 @@ def get_common_rarity_dd(self, min_emotion=0):
355442 candidates = self .find_candidates (templates , scanner , output = True )
356443 return candidates
357444
445+ @Config .when (Campaign_Mode = 'normal' )
358446 def vanguard_change_execute (self ):
359447 self .ui_enter_ship (FLEET_ENTER , long_click = False )
360448 candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
@@ -373,6 +461,40 @@ def vanguard_change_execute(self):
373461 self .ui_leave_ship ()
374462 return False
375463
464+ @Config .when (Campaign_Mode = 'hard' )
465+ def vanguard_change_execute (self ):
466+ unmount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_1' ]
467+ mount_button = globals ()[f'FLEET_{ self .fleet_to_attack } _VANGUARD_3' ]
468+
469+ self .ui_enter_ship (unmount_button , long_click = False )
470+ self .ui_click (DOCK_UNMOUNT , check_button = FLEET_PREPARATION , appear_button = DOCK_CHECK ,
471+ additional = self .ensure_no_info_bar , confirm_wait = 1 , retry_wait = 5 )
472+
473+ self .ui_enter_ship (mount_button , long_click = False )
474+ candidate = self .get_common_rarity_dd (min_emotion = self .min_emotion )
475+ if candidate :
476+ ship = max (candidate , key = lambda s : s .emotion )
477+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
478+ self .dock_select_one (ship .button )
479+ self .dock_reset ()
480+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
481+ logger .info ('Change vanguard success' )
482+ return True
483+
484+ logger .info ('Change vanguard failed, try using exhausted DDs.' )
485+ candidate = self .get_common_rarity_dd (min_emotion = 0 )
486+ if candidate :
487+ ship = max (candidate , key = lambda s : s .emotion )
488+ self ._new_fleet_emotion = min (ship .emotion , self ._new_fleet_emotion ) if self ._new_fleet_emotion else ship .emotion
489+ self .dock_select_one (ship .button )
490+ self .dock_reset ()
491+ self .dock_select_confirm (check_button = FLEET_PREPARATION )
492+ return False
493+ else :
494+ # This should not happen in general since the ship unmounted is also a candidate,
495+ # but just in case, we raise human takeover instead of leaving the vanguard slot empty.
496+ raise RequestHumanTakeover ('No DD was found, please change vanguard manually.' )
497+
376498 def vanguard_change (self ):
377499 """
378500 Change vanguard and vanguard's equipment
@@ -383,10 +505,11 @@ def vanguard_change(self):
383505 logger .hr ('Change vanguard' , level = 1 )
384506 logger .attr ('ChangeVanguard' , self .config .GemsFarming_ChangeVanguard )
385507 self .ui_goto_fleet ()
508+ button = self .fleet_vanguard_1_button
386509
387510 if self .change_vanguard_equip :
388511 logger .hr ('Unmount vanguard equipments' , level = 2 )
389- self .ui_enter_ship (FLEET_ENTER , long_click = True )
512+ self .ui_enter_ship (button , long_click = True )
390513 self .ship_equipment_take_off ()
391514 self .ui_leave_ship ()
392515
@@ -395,7 +518,7 @@ def vanguard_change(self):
395518
396519 if self .change_vanguard_equip :
397520 logger .hr ('Mount vanguard equipments' , level = 2 )
398- self .ui_enter_ship (FLEET_ENTER , long_click = True )
521+ self .ui_enter_ship (button , long_click = True )
399522 self .ship_equipment_take_on ()
400523 self .ui_leave_ship ()
401524
0 commit comments