Add: Prioritize stamina for rogue

This commit is contained in:
LmeSzinc 2023-12-08 18:09:33 +08:00
parent a7ac003479
commit fcb81bde46
16 changed files with 199 additions and 132 deletions

View File

@ -179,8 +179,8 @@
"Path": "The_Hunt",
"Bonus": "Blessing Cosmos",
"DomainStrategy": "combat",
"ImmersionReward": "immersifier",
"StopCondition": "weekly_point_reward"
"UseImmersifier": true,
"UseStamina": false
},
"RogueBlessing": {
"PresetBlessingFilter": "preset-1",
@ -196,6 +196,9 @@
"PresetResonanceFilter": "preset-1",
"ResonanceSelectionStrategy": "follow-presets",
"CustomResonanceFilter": "回响构音:均晶转变 > 回响构音:零维强化\n> 回响构音:第二次初恋 > 回响构音:体验的富翁\n> 回响构音:局外人 > 回响构音:怀疑的四重根\n> 回响构音:诸法无我 > 回响构音:诸行无常\n> 回响构音:射不主皮 > 回响构音:柘弓危矢\n> 回响构音:激变变星 > 回响构音:极端氦闪\n> 回响构音:末日狂欢 > 回响构音:树苗长高舞\n> random"
},
"RogueDebug": {
"DebugMode": false
}
}
}

View File

@ -1226,22 +1226,13 @@
"occurrence"
]
},
"ImmersionReward": {
"type": "select",
"value": "immersifier",
"option": [
"do_not_claim",
"immersifier",
"immersifier_trailblaze_power"
]
"UseImmersifier": {
"type": "checkbox",
"value": true
},
"StopCondition": {
"type": "select",
"value": "weekly_point_reward",
"option": [
"weekly_point_reward",
"debug"
]
"UseStamina": {
"type": "checkbox",
"value": false
}
},
"RogueBlessing": {
@ -1312,6 +1303,12 @@
"type": "textarea",
"value": "回响构音:均晶转变 > 回响构音:零维强化\n> 回响构音:第二次初恋 > 回响构音:体验的富翁\n> 回响构音:局外人 > 回响构音:怀疑的四重根\n> 回响构音:诸法无我 > 回响构音:诸行无常\n> 回响构音:射不主皮 > 回响构音:柘弓危矢\n> 回响构音:激变变星 > 回响构音:极端氦闪\n> 回响构音:末日狂欢 > 回响构音:树苗长高舞\n> random"
}
},
"RogueDebug": {
"DebugMode": {
"type": "checkbox",
"value": false
}
}
}
}

View File

@ -135,7 +135,7 @@ Weekly:
Name:
# Dungeon names will be injected in config updater
value: Echo_of_War_Divine_Seed
options: []
options: [ ]
Team:
value: 1
option: [ 1, 2, 3, 4, 5, 6 ]
@ -219,12 +219,8 @@ RogueWorld:
DomainStrategy:
value: combat
option: [ combat, occurrence ]
ImmersionReward:
value: immersifier
option: [ do_not_claim, immersifier, immersifier_trailblaze_power ]
StopCondition:
value: weekly_point_reward
option: [ weekly_point_reward, debug ]
UseImmersifier: true
UseStamina: false
RoguePath:
PresetResonanceFilter:
@ -263,3 +259,6 @@ RogueCurio:
option: [ follow-presets, unrecorded-first, before-random ]
CustomCurioFilter: |-
博士之袍 > 福灵胶 > 分裂金币 > 信仰债券 > 换境桂冠 > 俱乐部券 > 碎星芳饵 > random
RogueDebug:
DebugMode: false

View File

@ -59,3 +59,4 @@ Weekly:
- RogueBlessing
- RogueCurio
- RoguePath
- RogueDebug

View File

@ -520,10 +520,6 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
def DEVICE_CONTROL_METHOD(self):
return self.Emulator_ControlMethod
@property
def IS_ROGUE_DEBUG(self):
return self.RogueWorld_StopCondition == 'debug'
def temporary(self, **kwargs):
"""
Cover some settings, and recover later.

View File

@ -122,8 +122,8 @@ class GeneratedConfig:
RogueWorld_Path = 'The_Hunt' # Preservation, Remembrance, Nihility, Abundance, The_Hunt, Destruction, Elation
RogueWorld_Bonus = 'Blessing Cosmos' # Blessing Cosmos, Miracle Cosmos, Fragmented Cosmos
RogueWorld_DomainStrategy = 'combat' # combat, occurrence
RogueWorld_ImmersionReward = 'immersifier' # do_not_claim, immersifier, immersifier_trailblaze_power
RogueWorld_StopCondition = 'weekly_point_reward' # weekly_point_reward, debug
RogueWorld_UseImmersifier = True
RogueWorld_UseStamina = False
# Group `RoguePath`
RoguePath_PresetResonanceFilter = 'preset-1' # preset-1, custom
@ -139,3 +139,6 @@ class GeneratedConfig:
RogueCurio_PresetCurioFilter = 'preset-1' # preset-1, custom
RogueCurio_CurioSelectionStrategy = 'follow-presets' # follow-presets, unrecorded-first, before-random
RogueCurio_CustomCurioFilter = '博士之袍 > 福灵胶 > 分裂金币 > 信仰债券 > 换境桂冠 > 俱乐部券 > 碎星芳饵 > random'
# Group `RogueDebug`
RogueDebug_DebugMode = False

View File

@ -369,6 +369,7 @@ class ConfigGenerator:
if dungeon.name in dailies:
value = dungeon.__getattribute__(ingame_lang)
deep_set(new, keys=['Dungeon', 'Name', dungeon.name], value=value)
# Copy dungeon i18n to double events
def update_dungeon_names(keys):
for dungeon in deep_get(self.argument, keys=f'{keys}.option', default=[]):
@ -715,6 +716,13 @@ class ConfigUpdater:
set_daily('Synthesize_Consumable_1_time', 'achievable')
set_daily('Synthesize_material_1_time', 'achievable')
set_daily('Use_Consumables_1_time', 'achievable')
# Limit setting combinations
if deep_get(data, keys='Rogue.RogueWorld.UseImmersifier') is False:
deep_set(data, keys='Rogue.RogueWorld.UseStamina', value=False)
if deep_get(data, keys='Rogue.RogueWorld.UseStamina') is True:
deep_set(data, keys='Rogue.RogueWorld.UseImmersifier', value=True)
return data
def save_callback(self, key: str, value: t.Any) -> t.Iterable[t.Tuple[str, t.Any]]:
@ -755,6 +763,10 @@ class ConfigUpdater:
yield 'Dungeon.DungeonDaily.CavernOfCorrosion', value
elif key.endswith('CavernOfCorrosion'):
yield 'Dungeon.Dungeon.NameAtDoubleRelic', value
elif key == 'Rogue.RogueWorld.UseImmersifier' and value is False:
yield 'Rogue.RogueWorld.UseStamina', False
elif key == 'Rogue.RogueWorld.UseStamina' and value is True:
yield 'Rogue.RogueWorld.UseImmersifier', True
def read_file(self, config_name, is_template=False):
"""

View File

@ -819,18 +819,13 @@
"combat": "Prefer Combat",
"occurrence": "Prefer Occurrence"
},
"ImmersionReward": {
"name": "Claim Immersion Rewards",
"help": "Note: If \"Use Immersifier and Trailblaze Power\" is selected, the dungeon task will no longer run, and all trailblaze power will be used first to claim immersion rewards, except for double events.",
"do_not_claim": "Do not Claim",
"immersifier": "Use Immersifier",
"immersifier_trailblaze_power": "Use Immersifier and Trailblaze Power"
"UseImmersifier": {
"name": "Claim Planers Using Immersifiers",
"help": ""
},
"StopCondition": {
"name": "Stop Condition",
"help": "",
"weekly_point_reward": "Reached Weekly Point Rewards",
"debug": "(for debugging only)"
"UseStamina": {
"name": "Farm Planers Using Trailblase Power",
"help": "Task \"Dungeon\" will no longer run, and all trailblaze power will be used first to claim immersion rewards, except for double events."
}
},
"RoguePath": {
@ -902,6 +897,16 @@
"help": "Only takes effect when \"Preset Curio Filter\" is \"custom\""
}
},
"RogueDebug": {
"_info": {
"name": "Debug Settings",
"help": ""
},
"DebugMode": {
"name": "Debug Mode",
"help": ""
}
},
"Gui": {
"Aside": {
"Install": "Install",

View File

@ -819,18 +819,13 @@
"combat": "Prefiero Batalla",
"occurrence": "Prefiero Evento"
},
"ImmersionReward": {
"name": "Reclamar recompensas de inmersión",
"help": "Si se selecciona \"Usa inmersor y poder trazacaminos\", la tarea de mazmorra ya no se ejecutará y todo el poder trazacaminos se usará primero para reclamar recompensas de inmersión, excepto para eventos dobles",
"do_not_claim": "No reclamar",
"immersifier": "Usar inmersor",
"immersifier_trailblaze_power": "Usa inmersor y poder trazacaminos"
"UseImmersifier": {
"name": "Reclamar de planers mediante inmersor",
"help": ""
},
"StopCondition": {
"name": "Condición de detención",
"help": "",
"weekly_point_reward": "Recompensas de puntos semanales alcanzados",
"debug": "(solo para depuración)"
"UseStamina": {
"name": "Reclamar de planers mediante poder trazacaminos",
"help": "La tarea de mazmorra ya no se ejecutará y todo el poder trazacaminos se usará primero para reclamar recompensas de inmersión, excepto para eventos dobles"
}
},
"RoguePath": {
@ -902,6 +897,16 @@
"help": "Only takes effect when \"Preset Curio Filter\" is \"custom\""
}
},
"RogueDebug": {
"_info": {
"name": "Configuración de depuración",
"help": ""
},
"DebugMode": {
"name": "Modo de depuración",
"help": ""
}
},
"Gui": {
"Aside": {
"Install": "Instalar",

View File

@ -819,18 +819,13 @@
"combat": "combat",
"occurrence": "occurrence"
},
"ImmersionReward": {
"name": "RogueWorld.ImmersionReward.name",
"help": "RogueWorld.ImmersionReward.help",
"do_not_claim": "do_not_claim",
"immersifier": "immersifier",
"immersifier_trailblaze_power": "immersifier_trailblaze_power"
"UseImmersifier": {
"name": "RogueWorld.UseImmersifier.name",
"help": "RogueWorld.UseImmersifier.help"
},
"StopCondition": {
"name": "RogueWorld.StopCondition.name",
"help": "RogueWorld.StopCondition.help",
"weekly_point_reward": "weekly_point_reward",
"debug": "debug"
"UseStamina": {
"name": "RogueWorld.UseStamina.name",
"help": "RogueWorld.UseStamina.help"
}
},
"RoguePath": {
@ -902,6 +897,16 @@
"help": "RogueCurio.CustomCurioFilter.help"
}
},
"RogueDebug": {
"_info": {
"name": "RogueDebug._info.name",
"help": "RogueDebug._info.help"
},
"DebugMode": {
"name": "RogueDebug.DebugMode.name",
"help": "RogueDebug.DebugMode.help"
}
},
"Gui": {
"Aside": {
"Install": "インストール",

View File

@ -819,18 +819,13 @@
"combat": "偏好战斗",
"occurrence": "偏好事件"
},
"ImmersionReward": {
"name": "领取浸器奖励",
"help": "注意:选择 \"使用沉浸器和开拓力领取\" 时,每日副本任务不再打本,所有开拓力将优先被用于领取浸器奖励,双倍活动时除外",
"do_not_claim": "不领取",
"immersifier": "仅使用沉浸器领取",
"immersifier_trailblaze_power": "使用沉浸器和开拓力领取"
"UseImmersifier": {
"name": "使用沉浸器领取遗器",
"help": ""
},
"StopCondition": {
"name": "停止条件",
"help": "",
"weekly_point_reward": "每周点数奖励达到上限",
"debug": "(仅用于调试)"
"UseStamina": {
"name": "使用开拓力刷内圈遗器",
"help": "每日副本任务将不再打本,所有开拓力将优先被用于领取浸器奖励,双倍活动时除外"
}
},
"RoguePath": {
@ -902,6 +897,16 @@
"help": "仅在\"奇物过滤器\"设置为\"自定义\"时生效"
}
},
"RogueDebug": {
"_info": {
"name": "调试设置",
"help": ""
},
"DebugMode": {
"name": "调试模式",
"help": ""
}
},
"Gui": {
"Aside": {
"Install": "安装",

View File

@ -819,18 +819,13 @@
"combat": "偏好戰鬥",
"occurrence": "偏好事件"
},
"ImmersionReward": {
"name": "領取浸器獎勵",
"help": "注意:選擇 \"使用沉浸器和開拓力領取\" 時,每日副本任務不再打本,所有開拓力將優先被用於領取浸器獎勵,雙倍活動時除外",
"do_not_claim": "不領取",
"immersifier": "只使用沉浸器領取",
"immersifier_trailblaze_power": "使用沉浸器和開拓力領取"
"UseImmersifier": {
"name": "使用沉浸器領取遺器",
"help": ""
},
"StopCondition": {
"name": "停止條件",
"help": "",
"weekly_point_reward": "每週點數獎勵達到上限",
"debug": "(只用於偵錯)"
"UseStamina": {
"name": "用開拓力農遺器",
"help": "每日副本任務將不再打本,所有開拓力將優先被用於領取浸器獎勵,雙倍活動時除外"
}
},
"RoguePath": {
@ -902,6 +897,16 @@
"help": "僅在\"奇物過濾器\"設定為\"自訂\"時生效"
}
},
"RogueDebug": {
"_info": {
"name": "偵錯設定",
"help": ""
},
"DebugMode": {
"name": "偵錯模式",
"help": ""
}
},
"Gui": {
"Aside": {
"Install": "安裝",

View File

@ -1,15 +1,11 @@
from datetime import timedelta
from module.base.utils import area_offset
from module.config.stored.classes import now
from module.config.utils import DEFAULT_TIME
from module.logger import logger
from tasks.battle_pass.keywords import KEYWORD_BATTLE_PASS_QUEST
from tasks.combat.combat import Combat
from tasks.daily.keywords import KEYWORDS_DAILY_QUEST
from tasks.dungeon.event import DungeonEvent
from tasks.dungeon.keywords import DungeonList, KEYWORDS_DUNGEON_LIST, KEYWORDS_DUNGEON_TAB
from tasks.dungeon.ui import DungeonUI
from tasks.battle_pass.keywords import KEYWORD_BATTLE_PASS_QUEST
class Dungeon(DungeonUI, DungeonEvent, Combat):
@ -239,21 +235,25 @@ class Dungeon(DungeonUI, DungeonEvent, Combat):
dungeon = DungeonList.find(self.config.DungeonDaily_CavernOfCorrosion)
self.dungeon_run(dungeon=dungeon, wave_limit=1)
# Check daily
if self.achieved_daily_quest:
self.config.task_call('DailyQuest')
self.config.task_stop()
# Prioritize rogue
if self.config.is_task_enabled('Rogue') \
and self.config.cross_get('Rogue.RogueWorld.UseStamina'):
logger.info('Prioritize stamina for simulated universe, skip dungeon')
with self.config.multi_set():
self.config.task_call('Rogue')
self.config.task_delay(server_update=True)
self.config.task_stop()
# Combat
self.dungeon_run(final)
self.delay_dungeon_task(final)
def delay_dungeon_task(self, dungeon):
if dungeon.is_Cavern_of_Corrosion:
limit = 80
elif dungeon.is_Echo_of_War:
limit = 30
else:
limit = 60
# Recover 1 trailbaze power each 6 minutes
current = self.config.stored.TrailblazePower.value
cover = max(limit - current, 0) * 6
logger.info(f'Currently has {current} need {cover} minutes to reach {limit}')
def delay_dungeon_task(self, dungeon: DungeonList):
logger.attr('achieved_daily_quest', self.achieved_daily_quest)
with self.config.multi_set():
# Check battle pass
@ -268,12 +268,7 @@ class Dungeon(DungeonUI, DungeonEvent, Combat):
if self.achieved_daily_quest:
self.config.task_call('DailyQuest')
# Delay tasks
future = now() + timedelta(minutes=cover)
for task in ['Dungeon', 'Weekly']:
next_run = self.config.cross_get(keys=f'{task}.Scheduler.NextRun', default=DEFAULT_TIME)
if future > next_run:
logger.info(f"Delay task `{task}` to {future}")
self.config.cross_set(keys=f'{task}.Scheduler.NextRun', value=future)
self.dungeon_stamina_delay(dungeon)
self.config.task_stop()

View File

@ -1,11 +1,15 @@
import threading
from datetime import timedelta
from module.base.timer import Timer
from module.base.utils import crop
from module.config.stored.classes import now
from module.config.utils import DEFAULT_TIME
from module.logger import logger
from module.ocr.ocr import DigitCounter
from tasks.base.ui import UI
from tasks.dungeon.assets.assets_dungeon_state import OCR_SIMUNI_POINT, OCR_SIMUNI_POINT_OFFSET, OCR_STAMINA
from tasks.dungeon.keywords import DungeonList
class OcrSimUniPoint(DigitCounter):
@ -123,3 +127,29 @@ class DungeonState(UI):
thread = threading.Thread(target=func, args=(self.device.image,))
thread.start()
def dungeon_stamina_delay(self, dungeon: DungeonList):
"""
Delay tasks that use stamina
"""
if dungeon.is_Simulated_Universe:
limit = 80
elif dungeon.is_Cavern_of_Corrosion:
limit = 80
elif dungeon.is_Echo_of_War:
limit = 30
else:
limit = 60
# Recover 1 trailbaze power each 6 minutes
current = self.config.stored.TrailblazePower.value
cover = max(limit - current, 0) * 6
future = now() + timedelta(minutes=cover)
logger.info(f'Currently has {current} need {cover} minutes to reach {limit}')
tasks = ['Dungeon', 'Weekly']
with self.config.multi_set():
for task in tasks:
next_run = self.config.cross_get(keys=f'{task}.Scheduler.NextRun', default=DEFAULT_TIME)
if future > next_run:
logger.info(f"Delay task `{task}` to {future}")
self.config.cross_set(keys=f'{task}.Scheduler.NextRun', value=future)

View File

@ -2,7 +2,7 @@ import re
from datetime import datetime, timedelta
from module.base.timer import Timer
from module.exception import RequestHumanTakeover
from module.exception import RequestHumanTakeover, ScriptError
from module.logger import logger
from module.ocr.ocr import Ocr
from tasks.base.assets.assets_base_main_page import ROGUE_LEAVE_FOR_NOW
@ -251,26 +251,29 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonUI):
Raises:
RogueReachedWeeklyPointLimit: Raised if task should stop
"""
logger.attr('RogueWorld_StopCondition', self.config.RogueWorld_StopCondition)
logger.attr('RogueWorld_ImmersionReward', self.config.RogueWorld_ImmersionReward)
if self.config.RogueWorld_StopCondition == 'non_stop':
logger.info(f'RogueWorld_UseImmersifier={self.config.RogueWorld_UseImmersifier}, '
f'RogueWorld_UseStamina={self.config.RogueWorld_UseStamina}, '
f'RogueDebug_DebugMode={self.config.RogueDebug_DebugMode}')
# This shouldn't happen
if self.config.RogueWorld_UseStamina and not self.config.RogueWorld_UseImmersifier:
logger.error('Invalid rogue reward settings')
raise ScriptError
if self.config.RogueDebug_DebugMode:
# Always run
return
if self.config.RogueWorld_StopCondition == 'weekly_point_reward':
if self.config.stored.SimulatedUniverse.is_expired():
# Expired, do rogue
pass
elif self.config.stored.SimulatedUniverse.is_full():
if self.config.RogueWorld_ImmersionReward in ['immersifier', 'immersifier_trailblaze_power'] \
and self.config.stored.Immersifier.value > 0:
logger.info('Reached weekly point limit but still have immersifiers left, continue to use them')
else:
raise RogueReachedWeeklyPointLimit
if self.config.stored.SimulatedUniverse.is_expired():
# Expired, do rogue
pass
elif self.config.stored.SimulatedUniverse.is_full():
if self.config.RogueWorld_UseImmersifier and self.config.stored.Immersifier.value > 0:
logger.info('Reached weekly point limit but still have immersifiers left, continue to use them')
else:
# Not full, do rogue
pass
raise RogueReachedWeeklyPointLimit
else:
raise RogueReachedWeeklyPointLimit
# Not full, do rogue
pass
def rogue_world_enter(self, world: int | DungeonList = None):
"""

View File

@ -205,12 +205,15 @@ class RouteBase(RouteBase_, RogueExit, RogueEvent, RogueReward):
Get reward of the DomainElite and DomainBoss
"""
logger.hr('Clear reward', level=1)
use_trailblaze_power = 'trailblaze' in self.config.RogueWorld_ImmersionReward
use_immersifier = 'immersifier' in self.config.RogueWorld_ImmersionReward
if self.can_claim_domain_reward(use_trailblaze_power=use_trailblaze_power, use_immersifier=use_immersifier):
if self.can_claim_domain_reward(
use_trailblaze_power=self.config.RogueWorld_UseStamina,
use_immersifier=self.config.RogueWorld_UseImmersifier,
):
result = self.goto(*waypoints)
self.claim_domain_reward(use_trailblaze_power=use_trailblaze_power, use_immersifier=use_immersifier)
self.claim_domain_reward(
use_trailblaze_power=self.config.RogueWorld_UseStamina,
use_immersifier=self.config.RogueWorld_UseImmersifier,
)
else:
result = []
@ -348,13 +351,13 @@ class RouteBase(RouteBase_, RogueExit, RogueEvent, RogueReward):
# Choose a door
logger.hr('Find domain exit', level=2)
logger.info(f'Migrate={self.config.IS_ROGUE_DEBUG}, left_door={left_door}, right_door={right_door}')
if not self.config.IS_ROGUE_DEBUG and (not left_door and not right_door):
logger.info(f'Migrate={self.config.RogueDebug_DebugMode}, left_door={left_door}, right_door={right_door}')
if not self.config.RogueDebug_DebugMode and (not left_door and not right_door):
return self._domain_exit_old()
logger.info(f'Using new predict_door()')
door = self.predict_door()
if self.config.IS_ROGUE_DEBUG and self.exit_has_double_door and (not left_door or not right_door):
if self.config.RogueDebug_DebugMode and self.exit_has_double_door and (not left_door or not right_door):
logger.critical(f'Domain exit is not defined, please record it: {self.route_func}')
exit(1)