Merge pull request #551 from 5upernova-heng/add/more_trablaize_power

Add: use fuel & extract trailblaze power
This commit is contained in:
LmeSzinc 2024-07-16 01:23:07 +08:00 committed by GitHub
commit b70d6bb48b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 472 additions and 7 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

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: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -111,6 +111,11 @@
"DungeonDouble": {},
"EchoOfWar": {},
"SimulatedUniverse": {}
},
"TrailblazePower": {
"ExtractReservedTrailblazePower": false,
"UseFuel": false,
"UseFuelUntilRemainCount": 0
}
},
"DailyQuest": {

View File

@ -738,6 +738,20 @@
"order": 6,
"color": "#8fb5fe"
}
},
"TrailblazePower": {
"ExtractReservedTrailblazePower": {
"type": "checkbox",
"value": false
},
"UseFuel": {
"type": "checkbox",
"value": false
},
"UseFuelUntilRemainCount": {
"type": "input",
"value": 0
}
}
},
"DailyQuest": {

View File

@ -103,6 +103,10 @@ Dungeon:
Team:
value: 1
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
TrailblazePower:
ExtractReservedTrailblazePower: false
UseFuel: false
UseFuelUntilRemainCount: 0
DungeonSupport:
Use:
value: when_daily

View File

@ -28,6 +28,7 @@ Daily:
- Dungeon
- DungeonSupport
- DungeonStorage
- TrailblazePower
DailyQuest:
- Scheduler
- DailyStorage

View File

@ -46,6 +46,11 @@ class GeneratedConfig:
Dungeon_NameAtDoubleRelic = 'Cavern_of_Corrosion_Path_of_Providence' # Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive, Cavern_of_Corrosion_Path_of_Cavalier
Dungeon_Team = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
# Group `TrailblazePower`
TrailblazePower_ExtractReservedTrailblazePower = False
TrailblazePower_UseFuel = False
TrailblazePower_UseFuelUntilRemainCount = 0
# Group `DungeonSupport`
DungeonSupport_Use = 'when_daily' # always_use, when_daily, do_not_use
DungeonSupport_Character = 'FirstCharacter' # FirstCharacter, Acheron, Argenti, Arlan, Asta, Aventurine, Bailu, BlackSwan, Blade, Boothill, Bronya, Clara, DanHeng, DanHengImbibitorLunae, DrRatio, Firefly, FuXuan, Gallagher, Gepard, Guinaifen, Hanya, Herta, Himeko, Hook, Huohuo, JingYuan, Jingliu, Kafka, Luka, Luocha, Lynx, March7th, Misha, Natasha, Pela, Qingque, Robin, RuanMei, Sampo, Seele, Serval, SilverWolf, Sparkle, Sushang, Tingyun, TopazNumby, TrailblazerDestruction, TrailblazerHarmony, TrailblazerPreservation, Welt, Xueyi, Yanqing, Yukong

View File

@ -828,6 +828,8 @@ class ConfigUpdater:
Yields:
str: Arg path that should be hidden
"""
if deep_get(data, 'Dungeon.TrailblazePower.UseFuel') == False:
yield 'Dungeon.TrailblazePower.UseFuelUntilRemainCount'
if deep_get(data, 'Rogue.RogueBlessing.PresetBlessingFilter') != 'custom':
yield 'Rogue.RogueBlessing.CustomBlessingFilter'
if deep_get(data, 'Rogue.RogueBlessing.PresetResonanceFilter') != 'custom':

View File

@ -345,6 +345,24 @@
"9": "9"
}
},
"TrailblazePower": {
"_info": {
"name": "TrailblazePower Settings",
"help": ""
},
"ExtractReservedTrailblazePower": {
"name": "Extract reserve exploration power",
"help": ""
},
"UseFuel": {
"name": "Use Fuel",
"help": ""
},
"UseFuelUntilRemainCount": {
"name": "Supplement exploration power with fuel until X fuel remains",
"help": ""
}
},
"DungeonSupport": {
"_info": {
"name": "Support Settings",

View File

@ -345,6 +345,24 @@
"9": "9"
}
},
"TrailblazePower": {
"_info": {
"name": "TrailblazePower._info.name",
"help": "TrailblazePower._info.help"
},
"ExtractReservedTrailblazePower": {
"name": "TrailblazePower.ExtractReservedTrailblazePower.name",
"help": "TrailblazePower.ExtractReservedTrailblazePower.help"
},
"UseFuel": {
"name": "TrailblazePower.UseFuel.name",
"help": "TrailblazePower.UseFuel.help"
},
"UseFuelUntilRemainCount": {
"name": "TrailblazePower.UseFuelUntilRemainCount.name",
"help": "TrailblazePower.UseFuelUntilRemainCount.help"
}
},
"DungeonSupport": {
"_info": {
"name": "Ajustes de Apoyo",

View File

@ -345,6 +345,24 @@
"9": "9"
}
},
"TrailblazePower": {
"_info": {
"name": "TrailblazePower._info.name",
"help": "TrailblazePower._info.help"
},
"ExtractReservedTrailblazePower": {
"name": "TrailblazePower.ExtractReservedTrailblazePower.name",
"help": "TrailblazePower.ExtractReservedTrailblazePower.help"
},
"UseFuel": {
"name": "TrailblazePower.UseFuel.name",
"help": "TrailblazePower.UseFuel.help"
},
"UseFuelUntilRemainCount": {
"name": "TrailblazePower.UseFuelUntilRemainCount.name",
"help": "TrailblazePower.UseFuelUntilRemainCount.help"
}
},
"DungeonSupport": {
"_info": {
"name": "DungeonSupport._info.name",

View File

@ -345,6 +345,24 @@
"9": "9"
}
},
"TrailblazePower": {
"_info": {
"name": "开拓力设置",
"help": ""
},
"ExtractReservedTrailblazePower": {
"name": "取出后备开拓力",
"help": ""
},
"UseFuel": {
"name": "使用燃料",
"help": ""
},
"UseFuelUntilRemainCount": {
"name": "使用燃料补充开拓力,直到剩余 X 燃料",
"help": ""
}
},
"DungeonSupport": {
"_info": {
"name": "支援设置",

View File

@ -345,6 +345,24 @@
"9": "9"
}
},
"TrailblazePower": {
"_info": {
"name": "TrailblazePower._info.name",
"help": "TrailblazePower._info.help"
},
"ExtractReservedTrailblazePower": {
"name": "TrailblazePower.ExtractReservedTrailblazePower.name",
"help": "TrailblazePower.ExtractReservedTrailblazePower.help"
},
"UseFuel": {
"name": "TrailblazePower.UseFuel.name",
"help": "TrailblazePower.UseFuel.help"
},
"UseFuelUntilRemainCount": {
"name": "TrailblazePower.UseFuelUntilRemainCount.name",
"help": "TrailblazePower.UseFuelUntilRemainCount.help"
}
},
"DungeonSupport": {
"_info": {
"name": "支援設定",

View File

@ -20,6 +20,116 @@ COMBAT_PREPARE = ButtonWrapper(
button=(956, 640, 1225, 676),
),
)
EXTRACT_RESERVED_TRAILBLAZE_POWER = ButtonWrapper(
name='EXTRACT_RESERVED_TRAILBLAZE_POWER',
share=Button(
file='./assets/share/combat/prepare/EXTRACT_RESERVED_TRAILBLAZE_POWER.png',
area=(909, 506, 929, 526),
search=(889, 486, 949, 546),
color=(91, 91, 91),
button=(909, 506, 929, 526),
),
)
FUEL = ButtonWrapper(
name='FUEL',
share=Button(
file='./assets/share/combat/prepare/FUEL.png',
area=(592, 276, 688, 388),
search=(572, 256, 708, 408),
color=(113, 90, 123),
button=(592, 276, 688, 388),
),
)
FUEL_ENTRANCE = ButtonWrapper(
name='FUEL_ENTRANCE',
share=Button(
file='./assets/share/combat/prepare/FUEL_ENTRANCE.png',
area=(1035, 26, 1056, 48),
search=(1015, 6, 1076, 68),
color=(188, 180, 226),
button=(1035, 26, 1056, 48),
),
)
FUEL_MINUS = ButtonWrapper(
name='FUEL_MINUS',
share=Button(
file='./assets/share/combat/prepare/FUEL_MINUS.png',
area=(472, 425, 510, 450),
search=(452, 405, 530, 470),
color=(236, 236, 236),
button=(472, 425, 510, 450),
),
)
FUEL_PLUS = ButtonWrapper(
name='FUEL_PLUS',
share=Button(
file='./assets/share/combat/prepare/FUEL_PLUS.png',
area=(967, 426, 1005, 449),
search=(947, 406, 1025, 469),
color=(232, 232, 232),
button=(967, 426, 1005, 449),
),
)
FUEL_SELECTED = ButtonWrapper(
name='FUEL_SELECTED',
share=Button(
file='./assets/share/combat/prepare/FUEL_SELECTED.png',
area=(587, 271, 692, 395),
search=(474, 271, 811, 396),
color=(130, 111, 137),
button=(587, 271, 692, 395),
),
)
FUEL_SLIDER = ButtonWrapper(
name='FUEL_SLIDER',
share=Button(
file='./assets/share/combat/prepare/FUEL_SLIDER.png',
area=(561, 434, 916, 441),
search=(541, 414, 936, 461),
color=(215, 185, 154),
button=(561, 434, 916, 441),
),
)
OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT = ButtonWrapper(
name='OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT',
share=Button(
file='./assets/share/combat/prepare/OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT.png',
area=(425, 415, 688, 436),
search=(405, 395, 708, 456),
color=(192, 192, 192),
button=(425, 415, 688, 436),
),
)
OCR_FUEL = ButtonWrapper(
name='OCR_FUEL',
share=Button(
file='./assets/share/combat/prepare/OCR_FUEL.png',
area=(605, 369, 678, 386),
search=(585, 349, 698, 406),
color=(66, 66, 66),
button=(605, 369, 678, 386),
),
)
OCR_FUEL_COUNT = ButtonWrapper(
name='OCR_FUEL_COUNT',
share=Button(
file='./assets/share/combat/prepare/OCR_FUEL_COUNT.png',
area=(686, 409, 881, 425),
search=(666, 389, 901, 445),
color=(205, 205, 205),
button=(686, 409, 881, 425),
),
)
OCR_RESERVED_TRAILBLAZE_POWER = ButtonWrapper(
name='OCR_RESERVED_TRAILBLAZE_POWER',
share=Button(
file='./assets/share/combat/prepare/OCR_RESERVED_TRAILBLAZE_POWER.png',
area=(883, 29, 992, 44),
search=(863, 9, 1012, 64),
color=(51, 65, 65),
button=(883, 29, 992, 44),
),
)
OCR_TRAILBLAZE_POWER = ButtonWrapper(
name='OCR_TRAILBLAZE_POWER',
share=Button(
@ -50,6 +160,56 @@ OCR_WAVE_COUNT = ButtonWrapper(
button=(911, 555, 1151, 581),
),
)
RESERVED_MINUS = ButtonWrapper(
name='RESERVED_MINUS',
share=Button(
file='./assets/share/combat/prepare/RESERVED_MINUS.png',
area=(248, 474, 281, 498),
search=(228, 454, 301, 518),
color=(238, 238, 238),
button=(248, 474, 281, 498),
),
)
RESERVED_PLUS = ButtonWrapper(
name='RESERVED_PLUS',
share=Button(
file='./assets/share/combat/prepare/RESERVED_PLUS.png',
area=(938, 475, 974, 498),
search=(918, 455, 994, 518),
color=(232, 232, 232),
button=(938, 475, 974, 498),
),
)
RESERVED_SLIDER = ButtonWrapper(
name='RESERVED_SLIDER',
share=Button(
file='./assets/share/combat/prepare/RESERVED_SLIDER.png',
area=(334, 483, 873, 489),
search=(314, 463, 893, 509),
color=(212, 173, 130),
button=(334, 483, 873, 489),
),
)
RESERVED_TRAILBLAZE_POWER_ENTRANCE = ButtonWrapper(
name='RESERVED_TRAILBLAZE_POWER_ENTRANCE',
share=Button(
file='./assets/share/combat/prepare/RESERVED_TRAILBLAZE_POWER_ENTRANCE.png',
area=(895, 26, 916, 48),
search=(875, 6, 936, 68),
color=(154, 213, 214),
button=(895, 26, 916, 48),
),
)
USING_FUEL = ButtonWrapper(
name='USING_FUEL',
share=Button(
file='./assets/share/combat/prepare/USING_FUEL.png',
area=(263, 265, 363, 365),
search=(243, 245, 383, 385),
color=(161, 116, 129),
button=(263, 265, 363, 365),
),
)
WAVE_MINUS = ButtonWrapper(
name='WAVE_MINUS',
share=Button(

View File

@ -5,6 +5,7 @@ from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN, COMBAT_EXIT
from tasks.combat.assets.assets_combat_interact import DUNGEON_COMBAT_INTERACT
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT
from tasks.combat.fuel import Fuel
from tasks.combat.interact import CombatInteract
from tasks.combat.obtain import CombatObtain
from tasks.combat.prepare import CombatPrepare
@ -17,7 +18,7 @@ from tasks.map.control.joystick import MapControlJoystick
class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, CombatSkill, CombatObtain,
MapControlJoystick):
MapControlJoystick, Fuel):
dungeon: DungeonList | None = None
is_doing_planner: bool = False
@ -53,8 +54,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
# Check limits
if self.config.stored.TrailblazePower.value < self.combat_wave_cost:
logger.info('Trailblaze power exhausted, cannot continue combat')
return False
return self._try_get_more_trablaize_power(self.config.stored.TrailblazePower.value, self.combat_wave_cost)
if self.combat_waves <= 0:
logger.info('Combat wave limited, cannot continue combat')
return False
@ -221,8 +221,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again')
return True
else:
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can not run again')
return False
return self._try_get_more_trablaize_power(current, self.combat_wave_cost * self.combat_waves)
elif self.combat_wave_cost <= 0:
logger.info(f'Free combat, combat costs {self.combat_wave_cost}, can not run again')
return False
@ -230,6 +229,21 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
if current >= self.combat_wave_cost:
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again')
return True
else:
return self._try_get_more_trablaize_power(current, self.combat_wave_cost * self.combat_waves)
def _try_get_more_trablaize_power(self, current, cost):
if self.config.TrailblazePower_ExtractReservedTrailblazePower:
logger.info('Extract reserved trailblaze power to get more trailblaze power')
self.extract_reserved_trailblaze_power(current)
current = self.combat_get_trailblaze_power()
if self.config.TrailblazePower_UseFuel:
logger.info('Use fuel to get more trailblaze power')
self.use_fuel(current)
current = self.combat_get_trailblaze_power()
if current >= cost:
return True
else:
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can not run again')
return False

170
tasks/combat/fuel.py Normal file
View File

@ -0,0 +1,170 @@
import module.config.server as server
from module.base.utils import crop, area_offset
from module.logger import logger
from module.ocr.ocr import Digit
from tasks.base.assets.assets_base_popup import POPUP_CONFIRM, POPUP_CANCEL
from tasks.base.ui import UI
from tasks.item.slider import Slider
from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN
from tasks.combat.assets.assets_combat_prepare import (
COMBAT_PREPARE,
EXTRACT_RESERVED_TRAILBLAZE_POWER,
FUEL,
FUEL_MINUS,
FUEL_PLUS,
FUEL_SELECTED,
OCR_FUEL,
OCR_FUEL_COUNT,
OCR_RESERVED_TRAILBLAZE_POWER,
OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT,
RESERVED_TRAILBLAZE_POWER_ENTRANCE,
RESERVED_MINUS,
RESERVED_PLUS,
RESERVED_SLIDER,
FUEL_ENTRANCE,
USING_FUEL,
FUEL_SLIDER
)
class Fuel(UI):
fuel_trailblaze_power = 60
trailblaze_max_limit = 240
def _use_fuel_finish(self):
"""
Two possible finish states after using fuel/extract trailblaze power:
1. COMBAT_PREPARE
2. COMBAT_AGAIN
"""
return self.appear(COMBAT_PREPARE) or self.appear(COMBAT_AGAIN)
def extract_reserved_trailblaze_power(self, current, skip_first_screenshot=True):
"""
Extract reserved trailblaze power from previous combat.
Returns:
int: Reserved trailblaze power
"""
logger.info('Extract reserved trailblaze power')
reserved = Digit(OCR_RESERVED_TRAILBLAZE_POWER).ocr_single_line(self.device.image)
if reserved == 0:
logger.info('No reserved trailblaze power')
return
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(POPUP_CONFIRM):
break
if self.appear_then_click(EXTRACT_RESERVED_TRAILBLAZE_POWER):
continue
if self.appear_then_click(RESERVED_TRAILBLAZE_POWER_ENTRANCE):
continue
count = min(reserved, self.trailblaze_max_limit - current)
self.set_reserved_trailblaze_power(count, total=reserved)
skip_first_screenshot = True
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self._use_fuel_finish():
break
if self.appear_then_click(POPUP_CONFIRM):
continue
if self.handle_reward():
continue
def set_reserved_trailblaze_power(self, count, total):
slider = Slider(main=self, slider=RESERVED_SLIDER)
slider.set(count, total)
self.ui_ensure_index(
count, letter=Digit(OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT, lang=server.lang),
next_button=RESERVED_PLUS, prev_button=RESERVED_MINUS,
skip_first_screenshot=True
)
def set_fuel_count(self, count, total):
slider = Slider(main=self, slider=FUEL_SLIDER)
slider.set(count, total)
self.ui_ensure_index(
count, letter=Digit(OCR_FUEL_COUNT, lang=server.lang),
next_button=FUEL_PLUS, prev_button=FUEL_MINUS,
skip_first_screenshot=True
)
def use_fuel(self, current, skip_first_screenshot=True):
need = (self.trailblaze_max_limit - current) // self.fuel_trailblaze_power
if need == 0:
logger.info(f"Current trailblaze power is near {self.trailblaze_max_limit}, no need to use fuel")
return
logger.info("Use Fuel")
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(POPUP_CONFIRM) and not (self.appear(FUEL_SELECTED) and self.appear(FUEL)):
logger.info("No fuel found")
return
if self.appear(FUEL_SELECTED):
break
if self.appear_then_click(FUEL):
continue
if self.appear_then_click(FUEL_ENTRANCE):
continue
offset = FUEL_SELECTED.button_offset
count = Digit(OCR_FUEL).ocr_single_line(crop(self.device.image, area_offset(OCR_FUEL.area, offset)),
direct_ocr=True)
available_count = count - self.config.TrailblazePower_UseFuelUntilRemainCount
need = min(need, available_count)
if need <= 0:
logger.info("Fuel remain is under the threshold, stop using fuel")
while 1:
self.device.screenshot()
if self.appear_then_click(POPUP_CANCEL):
return
skip_first_screenshot = True
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(USING_FUEL):
break
if self.appear(FUEL) and self.appear_then_click(POPUP_CONFIRM):
continue
self.set_fuel_count(need, count)
skip_first_screenshot = True
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self._use_fuel_finish():
break
if self.appear_then_click(POPUP_CONFIRM):
continue
if self.handle_reward():
continue