Add: claim immersifier rewards

This commit is contained in:
LmeSzinc 2023-10-20 17:48:22 +08:00
parent fe39645e59
commit 9a113a7b9b
21 changed files with 255 additions and 22 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -58,6 +58,7 @@
},
"DungeonStorage": {
"TrailblazePower": {},
"Immersifier": {},
"DungeonDouble": {},
"EchoOfWar": {},
"SimulatedUniverse": {}

View File

@ -390,6 +390,12 @@
"order": 1,
"color": "#eb8efe"
},
"Immersifier": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredImmersifier"
},
"DungeonDouble": {
"type": "stored",
"value": {},

View File

@ -116,6 +116,8 @@ DungeonStorage:
stored: StoredTrailblazePower
order: 1
color: "#eb8efe"
Immersifier:
stored: StoredImmersifier
DungeonDouble:
stored: StoredDungeonDouble
EchoOfWar:

View File

@ -101,6 +101,19 @@
"order": 8,
"color": "#fc8f8b"
},
"Immersifier": {
"name": "Immersifier",
"path": "Dungeon.DungeonStorage.Immersifier",
"i18n": "DungeonStorage.Immersifier.name",
"stored": "StoredImmersifier",
"attrs": {
"time": "2020-01-01 00:00:00",
"total": 8,
"value": 0
},
"order": 0,
"color": "#777777"
},
"DungeonDouble": {
"name": "DungeonDouble",
"path": "Dungeon.DungeonStorage.DungeonDouble",

View File

@ -57,6 +57,7 @@ class GeneratedConfig:
# Group `DungeonStorage`
DungeonStorage_TrailblazePower = {}
DungeonStorage_Immersifier = {}
DungeonStorage_DungeonDouble = {}
DungeonStorage_EchoOfWar = {}
DungeonStorage_SimulatedUniverse = {}

View File

@ -401,6 +401,10 @@
"name": "Power",
"help": ""
},
"Immersifier": {
"name": "Immersifier",
"help": ""
},
"DungeonDouble": {
"name": "Dungeon Double",
"help": ""

View File

@ -401,6 +401,10 @@
"name": "Poder",
"help": ""
},
"Immersifier": {
"name": "Inmersor",
"help": ""
},
"DungeonDouble": {
"name": "Mazmorra x2",
"help": ""

View File

@ -401,6 +401,10 @@
"name": "DungeonStorage.TrailblazePower.name",
"help": "DungeonStorage.TrailblazePower.help"
},
"Immersifier": {
"name": "DungeonStorage.Immersifier.name",
"help": "DungeonStorage.Immersifier.help"
},
"DungeonDouble": {
"name": "DungeonStorage.DungeonDouble.name",
"help": "DungeonStorage.DungeonDouble.help"

View File

@ -401,6 +401,10 @@
"name": "开拓力",
"help": ""
},
"Immersifier": {
"name": "沉浸器",
"help": ""
},
"DungeonDouble": {
"name": "副本双倍",
"help": ""

View File

@ -401,6 +401,10 @@
"name": "開拓力",
"help": ""
},
"Immersifier": {
"name": "沉浸器",
"help": ""
},
"DungeonDouble": {
"name": "副本雙倍",
"help": ""
@ -806,20 +810,20 @@
"combat": "偏好戰鬥",
"occurrence": "偏好事件"
},
"ImmersionReward": {
"name": "领取浸器奖励",
"help": "注意:选择 \"使用沉浸器和开拓力领取\" 时,每日副本任务不再打本,所有开拓力将优先被用于领取浸器奖励,双倍活动时除外",
"do_not_claim": "不领取",
"immersifier": "仅使用沉浸器领取",
"immersifier_trailblaze_power": "使用沉浸器和开拓力领取"
},
"StopCondition": {
"name": "停止条件",
"help": "注意:\"每周100精英怪掉落奖励达到上限\" 时,模拟宇宙任务将运行数小时",
"weekly_point_reward": "每周点数奖励达到上限",
"100_elite_boss": "每周100精英怪掉落奖励达到上限",
"non_stop": "不停止 (仅用于除錯)"
}
"ImmersionReward": {
"name": "領取浸器獎勵",
"help": "注意:選擇 \"使用沉浸器和開拓力領取\" 時,每日副本任務不再打本,所有開拓力將優先被用於領取浸器獎勵,雙倍活動時除外",
"do_not_claim": "不領取",
"immersifier": "只使用沉浸器領取",
"immersifier_trailblaze_power": "使用沉浸器和開拓力領取"
},
"StopCondition": {
"name": "停止條件",
"help": "注意:\"每週100精英怪掉落獎勵達到上限\" 時,模擬宇宙任務將運行數小時",
"weekly_point_reward": "每週點數獎勵達到上限",
"100_elite_boss": "每週100精英怪掉落獎勵達到上限",
"non_stop": "不停止 (只用於除錯)"
}
},
"RoguePath": {
"_info": {

View File

@ -177,6 +177,29 @@ class StoredDailyActivity(StoredCounter, StoredExpiredAt0400):
class StoredTrailblazePower(StoredCounter):
FIXED_TOTAL = 240
def predict_current(self) -> int:
"""
Predict current stamina from records
"""
# Overflowed
value = self.value
if value >= self.FIXED_TOTAL:
return value
# Invalid time, record in the future
record = self.time
now = datetime.now()
if record >= now:
return value
# Calculate
# Recover 1 trailbaze power each 6 minutes
diff = (now - record).total_seconds()
value += int(diff // 360)
return value
class StoredImmersifier(StoredCounter):
FIXED_TOTAL = 8
class StoredSimulatedUniverse(StoredCounter, StoredExpiredAtMonday0400):
pass

View File

@ -10,6 +10,7 @@ from module.config.stored.classes import (
StoredEchoOfWar,
StoredExpiredAt0400,
StoredExpiredAtMonday0400,
StoredImmersifier,
StoredInt,
StoredSimulatedUniverse,
StoredTrailblazePower,
@ -21,6 +22,7 @@ from module.config.stored.classes import (
class StoredGenerated:
TrailblazePower = StoredTrailblazePower("Dungeon.DungeonStorage.TrailblazePower")
Immersifier = StoredImmersifier("Dungeon.DungeonStorage.Immersifier")
DungeonDouble = StoredDungeonDouble("Dungeon.DungeonStorage.DungeonDouble")
EchoOfWar = StoredEchoOfWar("Dungeon.DungeonStorage.EchoOfWar")
SimulatedUniverse = StoredSimulatedUniverse("Dungeon.DungeonStorage.SimulatedUniverse")

View File

@ -0,0 +1,45 @@
from module.base.button import Button, ButtonWrapper
# This file was auto-generated, do not modify it manually. To generate:
# ``` python -m dev_tools.button_extract ```
OCR_REMAIN = ButtonWrapper(
name='OCR_REMAIN',
share=Button(
file='./assets/share/rogue/reward/OCR_REMAIN.png',
area=(675, 11, 1181, 64),
search=(655, 0, 1201, 84),
color=(75, 89, 125),
button=(675, 11, 1181, 64),
),
)
REWARD_CLOSE = ButtonWrapper(
name='REWARD_CLOSE',
share=Button(
file='./assets/share/rogue/reward/REWARD_CLOSE.png',
area=(1043, 194, 1073, 224),
search=(1023, 174, 1093, 244),
color=(174, 175, 178),
button=(1043, 194, 1073, 224),
),
)
USE_IMMERSIFIER = ButtonWrapper(
name='USE_IMMERSIFIER',
share=Button(
file='./assets/share/rogue/reward/USE_IMMERSIFIER.png',
area=(713, 509, 737, 523),
search=(693, 489, 757, 543),
color=(189, 189, 189),
button=(684, 499, 963, 535),
),
)
USE_STAMINA = ButtonWrapper(
name='USE_STAMINA',
share=Button(
file='./assets/share/rogue/reward/USE_STAMINA.png',
area=(345, 509, 378, 524),
search=(325, 489, 398, 544),
color=(172, 172, 172),
button=(319, 499, 595, 535),
),
)

117
tasks/rogue/event/reward.py Normal file
View File

@ -0,0 +1,117 @@
from module.base.timer import Timer
from module.logger import logger
from module.ocr.ocr import DigitCounter
from tasks.base.assets.assets_base_popup import GET_REWARD
from tasks.combat.interact import CombatInteract
from tasks.rogue.assets.assets_rogue_reward import OCR_REMAIN, REWARD_CLOSE, USE_IMMERSIFIER, USE_STAMINA
from tasks.rogue.bleesing.ui import RogueUI
class RogueReward(RogueUI, CombatInteract):
def _reward_update_stamina(self, skip_first_screenshot=True):
ocr = DigitCounter(OCR_REMAIN)
timeout = Timer(1, count=2).start()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
stamina = (0, 0, 0)
immersifier = (0, 0, 0)
if timeout.reached():
logger.warning('_reward_update_stamina() timeout')
break
for row in ocr.detect_and_ocr(self.device.image):
if row.ocr_text.isdigit():
continue
if row.ocr_text == '+':
continue
data = ocr.format_result(row.ocr_text)
if data[2] == self.config.stored.TrailblazePower.FIXED_TOTAL:
stamina = data
if data[2] == self.config.stored.Immersifier.FIXED_TOTAL:
immersifier = data
if stamina[2] > 0 and immersifier[2] > 0:
break
stamina = stamina[0]
immersifier = immersifier[0]
logger.attr('TrailblazePower', stamina)
logger.attr('Imersifier', immersifier)
with self.config.multi_set():
self.config.stored.TrailblazePower.value = stamina
self.config.stored.Immersifier.value = immersifier
def claim_domain_reward(
self,
use_trailblaze_power=False,
use_immersifier=True,
skip_first_screenshot=True
):
"""
Pages:
in: page_main, DUNGEON_COMBAT_INTERACT, near immersifier
"""
logger.hr('Claim domain reward', level=2)
logger.info(f'use_trailblaze_power={use_trailblaze_power}, use_immersifier={use_immersifier}')
if not use_trailblaze_power and not use_immersifier:
return
confirm = Timer(0.6, count=2).start()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.is_in_main():
if confirm.reached():
break
else:
confirm.reset()
if self.handle_combat_interact():
self.interval_clear(USE_STAMINA)
confirm.reset()
continue
if self.handle_reward():
self.interval_clear(USE_STAMINA)
confirm.reset()
continue
if self.appear(REWARD_CLOSE, interval=2):
self._reward_update_stamina()
if use_immersifier and self.config.stored.Immersifier.value > 0:
self.device.click(USE_IMMERSIFIER)
self.interval_reset(USE_STAMINA)
self.interval_clear(GET_REWARD)
confirm.reset()
continue
elif use_trailblaze_power and self.config.stored.TrailblazePower.value >= 40:
self.device.click(USE_STAMINA)
self.interval_reset(USE_STAMINA)
self.interval_clear(GET_REWARD)
confirm.reset()
continue
else:
logger.info('Cannot claim more rewards')
self.device.click(REWARD_CLOSE)
self.interval_reset(USE_STAMINA)
confirm.reset()
continue
def can_claim_domain_reward(
self,
use_trailblaze_power=False,
use_immersifier=True
):
if not use_trailblaze_power and not use_immersifier:
return False
if use_immersifier and self.config.stored.Immersifier.value >= 0:
return True
if use_trailblaze_power and self.config.stored.TrailblazePower.predict_current() >= 40:
return True
return False

View File

@ -11,10 +11,11 @@ from tasks.rogue.bleesing.blessing import RogueBlessingSelector
from tasks.rogue.bleesing.bonus import RogueBonusSelector
from tasks.rogue.bleesing.curio import RogueCurioSelector
from tasks.rogue.event.event import RogueEvent
from tasks.rogue.event.reward import RogueReward
from tasks.rogue.route.exit import RogueExit
class RouteBase(RouteBase_, RogueExit, RogueEvent):
class RouteBase(RouteBase_, RogueExit, RogueEvent, RogueReward):
registered_domain_exit = None
def combat_expected_end(self):
@ -174,14 +175,16 @@ class RouteBase(RouteBase_, RogueExit, RogueEvent):
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
# TODO: Skip if user don't want rewards or stamina exhausted
return []
result = self.goto(*waypoints)
# TODO: Get reward
pass
if self.can_claim_domain_reward(use_trailblaze_power=use_trailblaze_power, use_immersifier=use_immersifier):
logger.info('Can claim domain reward')
result = self.goto(*waypoints)
self.claim_domain_reward(use_trailblaze_power=use_trailblaze_power, use_immersifier=use_immersifier)
else:
logger.info('Cannot claim more rewards')
result = []
return result