Refactor: Abstract StaminaStatus class to handle various states
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
BIN
assets/share/combat/stamina/status/ICON_SEARCH.png
Normal file
After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
BIN
assets/share/combat/stamina/status/STAMINA_OCR.png
Normal file
After Width: | Height: | Size: 12 KiB |
@ -1,165 +0,0 @@
|
|||||||
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 ```
|
|
||||||
|
|
||||||
EXTRACT_RESERVED_TRAILBLAZE_POWER = ButtonWrapper(
|
|
||||||
name='EXTRACT_RESERVED_TRAILBLAZE_POWER',
|
|
||||||
share=Button(
|
|
||||||
file='./assets/share/combat/fuel/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/fuel/FUEL.png',
|
|
||||||
area=(592, 276, 688, 366),
|
|
||||||
search=(474, 271, 811, 396),
|
|
||||||
color=(123, 96, 134),
|
|
||||||
button=(592, 276, 688, 366),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
FUEL_ENTRANCE = ButtonWrapper(
|
|
||||||
name='FUEL_ENTRANCE',
|
|
||||||
share=Button(
|
|
||||||
file='./assets/share/combat/fuel/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/fuel/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/fuel/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/fuel/FUEL_SELECTED.png',
|
|
||||||
area=(587, 271, 692, 368),
|
|
||||||
search=(474, 271, 811, 396),
|
|
||||||
color=(136, 112, 144),
|
|
||||||
button=(587, 271, 692, 368),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
FUEL_SLIDER = ButtonWrapper(
|
|
||||||
name='FUEL_SLIDER',
|
|
||||||
share=Button(
|
|
||||||
file='./assets/share/combat/fuel/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/fuel/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/fuel/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/fuel/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/fuel/OCR_RESERVED_TRAILBLAZE_POWER.png',
|
|
||||||
area=(883, 29, 992, 44),
|
|
||||||
search=(863, 9, 1012, 64),
|
|
||||||
color=(51, 65, 65),
|
|
||||||
button=(883, 29, 992, 44),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
RESERVED_MINUS = ButtonWrapper(
|
|
||||||
name='RESERVED_MINUS',
|
|
||||||
share=Button(
|
|
||||||
file='./assets/share/combat/fuel/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/fuel/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/fuel/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/fuel/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/fuel/USING_FUEL.png',
|
|
||||||
area=(263, 265, 363, 365),
|
|
||||||
search=(243, 245, 383, 385),
|
|
||||||
color=(161, 116, 129),
|
|
||||||
button=(263, 265, 363, 365),
|
|
||||||
),
|
|
||||||
)
|
|
@ -20,16 +20,6 @@ COMBAT_PREPARE = ButtonWrapper(
|
|||||||
button=(956, 640, 1225, 676),
|
button=(956, 640, 1225, 676),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
OCR_TRAILBLAZE_POWER = ButtonWrapper(
|
|
||||||
name='OCR_TRAILBLAZE_POWER',
|
|
||||||
share=Button(
|
|
||||||
file='./assets/share/combat/prepare/OCR_TRAILBLAZE_POWER.png',
|
|
||||||
area=(998, 26, 1130, 48),
|
|
||||||
search=(978, 6, 1150, 68),
|
|
||||||
color=(77, 76, 87),
|
|
||||||
button=(998, 26, 1130, 48),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
OCR_WAVE_COST = ButtonWrapper(
|
OCR_WAVE_COST = ButtonWrapper(
|
||||||
name='OCR_WAVE_COST',
|
name='OCR_WAVE_COST',
|
||||||
share=Button(
|
share=Button(
|
||||||
|
85
tasks/combat/assets/assets_combat_stamina_fuel.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
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 ```
|
||||||
|
|
||||||
|
FUEL = ButtonWrapper(
|
||||||
|
name='FUEL',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/fuel/FUEL.png',
|
||||||
|
area=(592, 276, 688, 366),
|
||||||
|
search=(474, 271, 811, 396),
|
||||||
|
color=(123, 96, 134),
|
||||||
|
button=(592, 276, 688, 366),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
FUEL_MINUS = ButtonWrapper(
|
||||||
|
name='FUEL_MINUS',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/fuel/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/stamina/fuel/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/stamina/fuel/FUEL_SELECTED.png',
|
||||||
|
area=(587, 271, 692, 368),
|
||||||
|
search=(474, 271, 811, 396),
|
||||||
|
color=(136, 112, 144),
|
||||||
|
button=(587, 271, 692, 368),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
FUEL_SLIDER = ButtonWrapper(
|
||||||
|
name='FUEL_SLIDER',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/fuel/FUEL_SLIDER.png',
|
||||||
|
area=(561, 434, 916, 441),
|
||||||
|
search=(541, 414, 936, 461),
|
||||||
|
color=(215, 185, 154),
|
||||||
|
button=(561, 434, 916, 441),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
OCR_FUEL = ButtonWrapper(
|
||||||
|
name='OCR_FUEL',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/fuel/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/stamina/fuel/OCR_FUEL_COUNT.png',
|
||||||
|
area=(686, 409, 881, 425),
|
||||||
|
search=(666, 389, 901, 445),
|
||||||
|
color=(205, 205, 205),
|
||||||
|
button=(686, 409, 881, 425),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
USING_FUEL = ButtonWrapper(
|
||||||
|
name='USING_FUEL',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/fuel/USING_FUEL.png',
|
||||||
|
area=(263, 265, 363, 365),
|
||||||
|
search=(243, 245, 383, 385),
|
||||||
|
color=(161, 116, 129),
|
||||||
|
button=(263, 265, 363, 365),
|
||||||
|
),
|
||||||
|
)
|
55
tasks/combat/assets/assets_combat_stamina_reserved.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
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 ```
|
||||||
|
|
||||||
|
EXTRACT_RESERVED_TRAILBLAZE_POWER = ButtonWrapper(
|
||||||
|
name='EXTRACT_RESERVED_TRAILBLAZE_POWER',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/reserved/EXTRACT_RESERVED_TRAILBLAZE_POWER.png',
|
||||||
|
area=(909, 506, 929, 526),
|
||||||
|
search=(889, 486, 949, 546),
|
||||||
|
color=(91, 91, 91),
|
||||||
|
button=(909, 506, 929, 526),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT = ButtonWrapper(
|
||||||
|
name='OCR_EXTRACT_RESERVED_TRAILBLAZE_POWER_COUNT',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/reserved/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),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
RESERVED_MINUS = ButtonWrapper(
|
||||||
|
name='RESERVED_MINUS',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/reserved/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/stamina/reserved/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/stamina/reserved/RESERVED_SLIDER.png',
|
||||||
|
area=(334, 483, 873, 489),
|
||||||
|
search=(314, 463, 893, 509),
|
||||||
|
color=(212, 173, 130),
|
||||||
|
button=(334, 483, 873, 489),
|
||||||
|
),
|
||||||
|
)
|
75
tasks/combat/assets/assets_combat_stamina_status.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
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 ```
|
||||||
|
|
||||||
|
ICON_SEARCH = ButtonWrapper(
|
||||||
|
name='ICON_SEARCH',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/ICON_SEARCH.png',
|
||||||
|
area=(568, 8, 1265, 66),
|
||||||
|
search=(548, 0, 1280, 86),
|
||||||
|
color=(71, 70, 100),
|
||||||
|
button=(568, 8, 1265, 66),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
IMMERSIFIER_ICON = ButtonWrapper(
|
||||||
|
name='IMMERSIFIER_ICON',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/IMMERSIFIER_ICON.png',
|
||||||
|
area=(1047, 26, 1066, 49),
|
||||||
|
search=(1027, 6, 1086, 69),
|
||||||
|
color=(138, 127, 117),
|
||||||
|
button=(1047, 26, 1066, 49),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
IMMERSIFIER_OCR = ButtonWrapper(
|
||||||
|
name='IMMERSIFIER_OCR',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/IMMERSIFIER_OCR.png',
|
||||||
|
area=(1049, 26, 1151, 48),
|
||||||
|
search=(1029, 6, 1171, 68),
|
||||||
|
color=(64, 61, 61),
|
||||||
|
button=(1049, 26, 1151, 48),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
RESERVED_ICON = ButtonWrapper(
|
||||||
|
name='RESERVED_ICON',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/RESERVED_ICON.png',
|
||||||
|
area=(895, 26, 916, 48),
|
||||||
|
search=(875, 6, 936, 68),
|
||||||
|
color=(155, 212, 215),
|
||||||
|
button=(895, 26, 916, 48),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
RESERVED_OCR = ButtonWrapper(
|
||||||
|
name='RESERVED_OCR',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/RESERVED_OCR.png',
|
||||||
|
area=(895, 26, 999, 48),
|
||||||
|
search=(875, 6, 1019, 68),
|
||||||
|
color=(50, 69, 83),
|
||||||
|
button=(895, 26, 999, 48),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
STAMINA_ICON = ButtonWrapper(
|
||||||
|
name='STAMINA_ICON',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/STAMINA_ICON.png',
|
||||||
|
area=(873, 26, 894, 48),
|
||||||
|
search=(853, 6, 914, 68),
|
||||||
|
color=(188, 180, 226),
|
||||||
|
button=(873, 26, 894, 48),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
STAMINA_OCR = ButtonWrapper(
|
||||||
|
name='STAMINA_OCR',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/combat/stamina/status/STAMINA_OCR.png',
|
||||||
|
area=(873, 26, 1013, 48),
|
||||||
|
search=(853, 6, 1033, 68),
|
||||||
|
color=(66, 64, 88),
|
||||||
|
button=(873, 26, 1013, 48),
|
||||||
|
),
|
||||||
|
)
|
@ -54,7 +54,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
|
|||||||
|
|
||||||
# Check limits
|
# Check limits
|
||||||
if self.config.stored.TrailblazePower.value < self.combat_wave_cost:
|
if self.config.stored.TrailblazePower.value < self.combat_wave_cost:
|
||||||
return self._try_get_more_trablaize_power(self.config.stored.TrailblazePower.value, self.combat_wave_cost)
|
return self._try_get_more_trablaize_power(self.combat_wave_cost)
|
||||||
if self.combat_waves <= 0:
|
if self.combat_waves <= 0:
|
||||||
logger.info('Combat wave limited, cannot continue combat')
|
logger.info('Combat wave limited, cannot continue combat')
|
||||||
return False
|
return False
|
||||||
@ -225,7 +225,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
|
|||||||
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again')
|
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again')
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return self._try_get_more_trablaize_power(current, self.combat_wave_cost * self.combat_waves)
|
return self._try_get_more_trablaize_power(self.combat_wave_cost * self.combat_waves)
|
||||||
elif self.combat_wave_cost <= 0:
|
elif self.combat_wave_cost <= 0:
|
||||||
logger.info(f'Free combat, combat costs {self.combat_wave_cost}, can not run again')
|
logger.info(f'Free combat, combat costs {self.combat_wave_cost}, can not run again')
|
||||||
return False
|
return False
|
||||||
@ -234,20 +234,15 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
|
|||||||
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again')
|
logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again')
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return self._try_get_more_trablaize_power(current, self.combat_wave_cost * self.combat_waves)
|
return self._try_get_more_trablaize_power(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')
|
|
||||||
if self.extract_reserved_trailblaze_power(current):
|
|
||||||
self.combat_get_trailblaze_power()
|
|
||||||
self.get_interval_timer(COMBAT_EXIT).wait()
|
|
||||||
if self.config.TrailblazePower_UseFuel:
|
|
||||||
logger.info('Use fuel to get more trailblaze power')
|
|
||||||
if self.use_fuel(current):
|
|
||||||
self.combat_get_trailblaze_power()
|
|
||||||
self.get_interval_timer(COMBAT_AGAIN).wait()
|
|
||||||
|
|
||||||
|
def _try_get_more_trablaize_power(self, cost):
|
||||||
|
self.extract_stamina(
|
||||||
|
update=False,
|
||||||
|
use_reserved=self.config.TrailblazePower_ExtractReservedTrailblazePower,
|
||||||
|
use_fuel=self.config.TrailblazePower_UseFuel
|
||||||
|
)
|
||||||
|
current = self.config.stored.TrailblazePower.value
|
||||||
if current >= cost:
|
if current >= cost:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
@ -4,14 +4,16 @@ from module.base.utils import area_offset, crop
|
|||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import Digit
|
from module.ocr.ocr import Digit
|
||||||
from tasks.base.assets.assets_base_popup import GET_REWARD, POPUP_CANCEL, POPUP_CONFIRM
|
from tasks.base.assets.assets_base_popup import GET_REWARD, POPUP_CANCEL, POPUP_CONFIRM
|
||||||
from tasks.base.ui import UI
|
|
||||||
from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN, COMBAT_EXIT
|
from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN, COMBAT_EXIT
|
||||||
from tasks.combat.assets.assets_combat_fuel import *
|
|
||||||
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
|
from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
|
||||||
|
from tasks.combat.assets.assets_combat_stamina_fuel import *
|
||||||
|
from tasks.combat.assets.assets_combat_stamina_reserved import *
|
||||||
|
from tasks.combat.assets.assets_combat_stamina_status import *
|
||||||
|
from tasks.combat.stamina_status import StaminaStatus
|
||||||
from tasks.item.slider import Slider
|
from tasks.item.slider import Slider
|
||||||
|
|
||||||
|
|
||||||
class Fuel(UI):
|
class Fuel(StaminaStatus):
|
||||||
fuel_trailblaze_power = 60
|
fuel_trailblaze_power = 60
|
||||||
|
|
||||||
def _use_fuel_finish(self):
|
def _use_fuel_finish(self):
|
||||||
@ -26,7 +28,7 @@ class Fuel(UI):
|
|||||||
return True
|
return True
|
||||||
if self.appear(COMBAT_PREPARE):
|
if self.appear(COMBAT_PREPARE):
|
||||||
if self.image_color_count(COMBAT_PREPARE.button, color=(230, 230, 230), threshold=240, count=400):
|
if self.image_color_count(COMBAT_PREPARE.button, color=(230, 230, 230), threshold=240, count=400):
|
||||||
logger.info(f'Use fuel finished at COMBAT_AGAIN')
|
logger.info(f'Use fuel finished at COMBAT_PREPARE')
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -87,7 +89,7 @@ class Fuel(UI):
|
|||||||
timer = self.get_interval_timer(COMBAT_EXIT, interval=5, renew=True)
|
timer = self.get_interval_timer(COMBAT_EXIT, interval=5, renew=True)
|
||||||
timer.set_current(4.4)
|
timer.set_current(4.4)
|
||||||
|
|
||||||
def extract_reserved_trailblaze_power(self, current, skip_first_screenshot=True):
|
def extract_reserved_trailblaze_power(self, skip_first_screenshot=True):
|
||||||
"""
|
"""
|
||||||
Extract reserved trailblaze power from previous combat.
|
Extract reserved trailblaze power from previous combat.
|
||||||
|
|
||||||
@ -95,11 +97,8 @@ class Fuel(UI):
|
|||||||
bool: If extracted
|
bool: If extracted
|
||||||
"""
|
"""
|
||||||
logger.info('Extract 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 False
|
|
||||||
|
|
||||||
|
RESERVED_ICON.load_search(ICON_SEARCH.area)
|
||||||
self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_REWARD])
|
self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_REWARD])
|
||||||
while 1:
|
while 1:
|
||||||
if skip_first_screenshot:
|
if skip_first_screenshot:
|
||||||
@ -111,12 +110,14 @@ class Fuel(UI):
|
|||||||
break
|
break
|
||||||
if self.appear_then_click(EXTRACT_RESERVED_TRAILBLAZE_POWER):
|
if self.appear_then_click(EXTRACT_RESERVED_TRAILBLAZE_POWER):
|
||||||
continue
|
continue
|
||||||
if self.appear_then_click(RESERVED_TRAILBLAZE_POWER_ENTRANCE):
|
if self.appear_then_click(RESERVED_ICON):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
count = min(reserved, self.config.stored.TrailblazePower.FIXED_TOTAL - current)
|
# No need, amount will be set by game client
|
||||||
logger.info(f'Having {reserved} reserved, going to use {count}')
|
# count = min(reserved, self.config.stored.TrailblazePower.FIXED_TOTAL - current)
|
||||||
self.set_reserved_trailblaze_power(count, total=reserved)
|
# logger.info(f'Having {reserved} reserved, going to use {count}')
|
||||||
|
# self.set_reserved_trailblaze_power(count, total=reserved)
|
||||||
|
|
||||||
self._fuel_confirm()
|
self._fuel_confirm()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -160,6 +161,7 @@ class Fuel(UI):
|
|||||||
|
|
||||||
logger.info("Use Fuel")
|
logger.info("Use Fuel")
|
||||||
|
|
||||||
|
STAMINA_ICON.load_search(ICON_SEARCH.area)
|
||||||
timeout = Timer(1, count=3)
|
timeout = Timer(1, count=3)
|
||||||
has_fuel = False
|
has_fuel = False
|
||||||
while 1:
|
while 1:
|
||||||
@ -182,7 +184,7 @@ class Fuel(UI):
|
|||||||
if self.appear_then_click(FUEL):
|
if self.appear_then_click(FUEL):
|
||||||
has_fuel = True
|
has_fuel = True
|
||||||
continue
|
continue
|
||||||
if not self.appear(POPUP_CONFIRM) and self.appear_then_click(FUEL_ENTRANCE):
|
if not self.appear(POPUP_CONFIRM) and self.appear_then_click(STAMINA_ICON):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
offset = FUEL_SELECTED.button_offset
|
offset = FUEL_SELECTED.button_offset
|
||||||
@ -215,3 +217,39 @@ class Fuel(UI):
|
|||||||
self.set_fuel_count(use)
|
self.set_fuel_count(use)
|
||||||
self._fuel_confirm()
|
self._fuel_confirm()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def extract_stamina(self, update=True, use_reserved=True, use_fuel=False):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
update:
|
||||||
|
use_reserved:
|
||||||
|
use_fuel:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: If used
|
||||||
|
"""
|
||||||
|
if not use_reserved and not use_fuel:
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.hr('Extract stamina', level=2)
|
||||||
|
logger.info(f'Extract stamina, reserved={use_reserved}, fuel={use_fuel}')
|
||||||
|
if update:
|
||||||
|
self.update_stamina_status()
|
||||||
|
used = False
|
||||||
|
|
||||||
|
if use_reserved:
|
||||||
|
if self.config.stored.Reserved.value <= 0:
|
||||||
|
logger.info('No reserved stamina')
|
||||||
|
else:
|
||||||
|
self.extract_reserved_trailblaze_power()
|
||||||
|
used = True
|
||||||
|
self.update_stamina_status()
|
||||||
|
self.get_interval_timer(COMBAT_AGAIN).wait()
|
||||||
|
|
||||||
|
if use_fuel:
|
||||||
|
self.use_fuel(current=self.config.stored.TrailblazePower.value)
|
||||||
|
used = True
|
||||||
|
self.update_stamina_status()
|
||||||
|
self.get_interval_timer(COMBAT_AGAIN).wait()
|
||||||
|
|
||||||
|
return used
|
||||||
|
@ -1,35 +1,20 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
import module.config.server as server
|
import module.config.server as server
|
||||||
from module.base.timer import Timer
|
from module.base.timer import Timer
|
||||||
from module.base.utils import color_similar, get_color
|
from module.base.utils import color_similar, get_color
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import Digit, DigitCounter
|
from module.ocr.ocr import Digit
|
||||||
from tasks.base.ui import UI
|
|
||||||
from tasks.combat.assets.assets_combat_prepare import (
|
from tasks.combat.assets.assets_combat_prepare import (
|
||||||
OCR_TRAILBLAZE_POWER,
|
|
||||||
OCR_WAVE_COST,
|
OCR_WAVE_COST,
|
||||||
OCR_WAVE_COUNT,
|
OCR_WAVE_COUNT,
|
||||||
WAVE_MINUS,
|
WAVE_MINUS,
|
||||||
WAVE_PLUS, WAVE_SLIDER
|
WAVE_PLUS,
|
||||||
|
WAVE_SLIDER
|
||||||
)
|
)
|
||||||
|
from tasks.combat.stamina_status import StaminaStatus
|
||||||
from tasks.item.slider import Slider
|
from tasks.item.slider import Slider
|
||||||
|
|
||||||
|
|
||||||
class TrailblazePowerOcr(DigitCounter):
|
class CombatPrepare(StaminaStatus):
|
||||||
def after_process(self, result):
|
|
||||||
result = super().after_process(result)
|
|
||||||
# The trailblaze power icon is recognized as 买
|
|
||||||
# OCR_TRAILBLAZE_POWER includes the icon because the length varies by value
|
|
||||||
result = re.sub(r'[买米装:()]', '', result)
|
|
||||||
# 61240 -> 6/240
|
|
||||||
result = re.sub(r'1240$', '/240', result)
|
|
||||||
# 0*0/24 -> 0/240
|
|
||||||
result = re.sub(r'24$', '240', result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class CombatPrepare(UI):
|
|
||||||
# Current combat waves,
|
# Current combat waves,
|
||||||
combat_waves = 1
|
combat_waves = 1
|
||||||
# Limit combat runs, 0 means no limit.
|
# Limit combat runs, 0 means no limit.
|
||||||
@ -78,20 +63,20 @@ class CombatPrepare(UI):
|
|||||||
else:
|
else:
|
||||||
self.device.screenshot()
|
self.device.screenshot()
|
||||||
|
|
||||||
current, _, total = TrailblazePowerOcr(OCR_TRAILBLAZE_POWER).ocr_single_line(self.device.image)
|
data = self.update_stamina_status(image=self.device.image)
|
||||||
# Empty result
|
if data.stamina is None:
|
||||||
if total == 0:
|
|
||||||
continue
|
continue
|
||||||
# Confirm if it is > 240, sometimes just OCR errors
|
# Confirm if it is > 240, sometimes just OCR errors
|
||||||
if current > 240 and timeout.reached():
|
# if current > 240 and timeout.reached():
|
||||||
|
# break
|
||||||
|
if expect_reduce and timeout.reached():
|
||||||
break
|
break
|
||||||
if expect_reduce and current >= before:
|
if expect_reduce and data.stamina >= before:
|
||||||
continue
|
continue
|
||||||
if current <= 240:
|
if data.stamina <= 240:
|
||||||
break
|
break
|
||||||
|
|
||||||
self.config.stored.TrailblazePower.value = current
|
return data.stamina
|
||||||
return current
|
|
||||||
|
|
||||||
def combat_get_wave_cost(self, skip_first_screenshot=True):
|
def combat_get_wave_cost(self, skip_first_screenshot=True):
|
||||||
"""
|
"""
|
||||||
|
161
tasks/combat/stamina_status.py
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from module.base.timer import Timer
|
||||||
|
from module.base.utils import crop
|
||||||
|
from module.logger import logger
|
||||||
|
from module.ocr.ocr import Digit, DigitCounter
|
||||||
|
from tasks.base.ui import UI
|
||||||
|
from tasks.combat.assets.assets_combat_stamina_status import *
|
||||||
|
|
||||||
|
|
||||||
|
class StaminaOcr(DigitCounter):
|
||||||
|
def after_process(self, result):
|
||||||
|
result = super().after_process(result)
|
||||||
|
# The trailblaze power icon is recognized as 买
|
||||||
|
# OCR_TRAILBLAZE_POWER includes the icon because the length varies by value
|
||||||
|
result = re.sub(r'[买米装来:()]', '', result)
|
||||||
|
# 61240 -> 6/240
|
||||||
|
result = re.sub(r'1240$', '/240', result)
|
||||||
|
# 0*0/24 -> 0/240
|
||||||
|
result = re.sub(r'24$', '240', result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class ReservedOcr(Digit):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ImmersifierOcr(DigitCounter):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DataStaminaStatus(BaseModel):
|
||||||
|
stamina: int | None
|
||||||
|
reserved: int | None
|
||||||
|
immersifier: int | None
|
||||||
|
|
||||||
|
|
||||||
|
class StaminaStatus(UI):
|
||||||
|
@staticmethod
|
||||||
|
def get_stamina_status(image) -> DataStaminaStatus:
|
||||||
|
"""
|
||||||
|
Update trailblaze power, stored trailblaze power, immersifier
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Stamina, or None if stamina not displayed or error on OCR
|
||||||
|
int: Reserved stamina
|
||||||
|
int: Immersifier
|
||||||
|
"""
|
||||||
|
for button in [STAMINA_ICON, RESERVED_ICON, IMMERSIFIER_ICON]:
|
||||||
|
button.load_search(ICON_SEARCH.area)
|
||||||
|
|
||||||
|
stamina = None
|
||||||
|
if STAMINA_ICON.match_template(image):
|
||||||
|
STAMINA_OCR.load_offset(STAMINA_ICON)
|
||||||
|
im = crop(image, STAMINA_OCR.button, copy=False)
|
||||||
|
stamina, _, total = StaminaOcr(STAMINA_OCR).ocr_single_line(im, direct_ocr=True)
|
||||||
|
if total > 240 or total == 0:
|
||||||
|
logger.warning(f'Unexpected stamina total: {total}')
|
||||||
|
stamina = None
|
||||||
|
|
||||||
|
reserved = None
|
||||||
|
if RESERVED_ICON.match_template(image):
|
||||||
|
RESERVED_OCR.load_offset(RESERVED_ICON)
|
||||||
|
im = crop(image, RESERVED_OCR.button, copy=False)
|
||||||
|
reserved = ReservedOcr(RESERVED_OCR).ocr_single_line(im, direct_ocr=True)
|
||||||
|
if reserved > 2400:
|
||||||
|
logger.warning(f'Unexpected reserved value: {reserved}')
|
||||||
|
reserved = None
|
||||||
|
|
||||||
|
immersifier = None
|
||||||
|
if IMMERSIFIER_ICON.match_template(image):
|
||||||
|
IMMERSIFIER_OCR.load_offset(IMMERSIFIER_ICON)
|
||||||
|
im = crop(image, IMMERSIFIER_OCR.button, copy=False)
|
||||||
|
immersifier, _, total = StaminaOcr(IMMERSIFIER_OCR).ocr_single_line(im, direct_ocr=True)
|
||||||
|
if total != 8:
|
||||||
|
logger.warning(f'Unexpected immersifier total: {total}')
|
||||||
|
immersifier = None
|
||||||
|
|
||||||
|
return DataStaminaStatus(
|
||||||
|
stamina=stamina,
|
||||||
|
reserved=reserved,
|
||||||
|
immersifier=immersifier,
|
||||||
|
)
|
||||||
|
|
||||||
|
def update_stamina_status(
|
||||||
|
self,
|
||||||
|
image=None,
|
||||||
|
skip_first_screenshot=True,
|
||||||
|
expect_stamina=False,
|
||||||
|
expect_reserved=False,
|
||||||
|
expect_immersifier=False,
|
||||||
|
) -> DataStaminaStatus:
|
||||||
|
"""
|
||||||
|
Update stamina status with retry
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image: Detect given image only, no new screenshot will be taken
|
||||||
|
and all expect_* are considered False
|
||||||
|
skip_first_screenshot:
|
||||||
|
expect_stamina:
|
||||||
|
True to expect stamina exists, retry detect if it wasn't
|
||||||
|
expect_reserved:
|
||||||
|
expect_immersifier:
|
||||||
|
|
||||||
|
Pages:
|
||||||
|
in: page_guild, Survival_Index, Simulated_Universe
|
||||||
|
or page_rogue, LEVEL_CONFIRM
|
||||||
|
or rogue, REWARD_CLOSE
|
||||||
|
"""
|
||||||
|
timeout = Timer(1, count=2).start()
|
||||||
|
if image is None:
|
||||||
|
image = self.device.image
|
||||||
|
use_cached_image = False
|
||||||
|
else:
|
||||||
|
skip_first_screenshot = True
|
||||||
|
use_cached_image = True
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
if skip_first_screenshot:
|
||||||
|
skip_first_screenshot = False
|
||||||
|
else:
|
||||||
|
self.device.screenshot()
|
||||||
|
image = self.device.image
|
||||||
|
|
||||||
|
# Timeout
|
||||||
|
if timeout.reached():
|
||||||
|
logger.warning('dungeon_update_stamina() timeout')
|
||||||
|
return DataStaminaStatus(
|
||||||
|
stamina=None,
|
||||||
|
reserved=None,
|
||||||
|
immersifier=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ocr
|
||||||
|
status = self.get_stamina_status(image)
|
||||||
|
valid = True
|
||||||
|
if expect_stamina and status.stamina is None:
|
||||||
|
valid = False
|
||||||
|
if expect_reserved and status.reserved is None:
|
||||||
|
valid = False
|
||||||
|
if expect_immersifier and status.immersifier is None:
|
||||||
|
valid = False
|
||||||
|
if status.stamina is None and status.reserved is None and status.immersifier is None:
|
||||||
|
logger.warning('update_stamina_status: No icon detected')
|
||||||
|
valid = False
|
||||||
|
|
||||||
|
# Write config
|
||||||
|
with self.config.multi_set():
|
||||||
|
if status.stamina is not None:
|
||||||
|
self.config.stored.TrailblazePower.value = status.stamina
|
||||||
|
if status.reserved is not None:
|
||||||
|
self.config.stored.Reserved.value = status.reserved
|
||||||
|
if status.immersifier is not None:
|
||||||
|
self.config.stored.Immersifier.value = status.reserved
|
||||||
|
|
||||||
|
if use_cached_image or valid:
|
||||||
|
return status
|
||||||
|
else:
|
||||||
|
continue
|
@ -41,16 +41,6 @@ AMOUNT_PLUS = ButtonWrapper(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
ENTER_IMMERSIFIER = ButtonWrapper(
|
|
||||||
name='ENTER_IMMERSIFIER',
|
|
||||||
share=Button(
|
|
||||||
file='./assets/share/dungeon/stamina/ENTER_IMMERSIFIER.png',
|
|
||||||
area=(1047, 26, 1066, 49),
|
|
||||||
search=(1027, 6, 1086, 69),
|
|
||||||
color=(138, 127, 117),
|
|
||||||
button=(1049, 26, 1151, 48),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
IMMERSIFIER_CHECK = ButtonWrapper(
|
IMMERSIFIER_CHECK = ButtonWrapper(
|
||||||
name='IMMERSIFIER_CHECK',
|
name='IMMERSIFIER_CHECK',
|
||||||
share=Button(
|
share=Button(
|
||||||
|
@ -3,6 +3,7 @@ from module.base.timer import Timer
|
|||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import Digit
|
from module.ocr.ocr import Digit
|
||||||
from tasks.base.page import page_guide
|
from tasks.base.page import page_guide
|
||||||
|
from tasks.combat.assets.assets_combat_stamina_status import ICON_SEARCH, IMMERSIFIER_ICON
|
||||||
from tasks.dungeon.assets.assets_dungeon_stamina import *
|
from tasks.dungeon.assets.assets_dungeon_stamina import *
|
||||||
from tasks.dungeon.keywords import KEYWORDS_DUNGEON_TAB
|
from tasks.dungeon.keywords import KEYWORDS_DUNGEON_TAB
|
||||||
from tasks.dungeon.ui import DungeonUI
|
from tasks.dungeon.ui import DungeonUI
|
||||||
@ -16,6 +17,7 @@ class DungeonStamina(DungeonUI):
|
|||||||
out: IMMERSIFIER_CHECK
|
out: IMMERSIFIER_CHECK
|
||||||
"""
|
"""
|
||||||
logger.info('Enter immersifier')
|
logger.info('Enter immersifier')
|
||||||
|
IMMERSIFIER_ICON.load_search(ICON_SEARCH.area)
|
||||||
while 1:
|
while 1:
|
||||||
if skip_first_screenshot:
|
if skip_first_screenshot:
|
||||||
skip_first_screenshot = False
|
skip_first_screenshot = False
|
||||||
@ -24,7 +26,7 @@ class DungeonStamina(DungeonUI):
|
|||||||
|
|
||||||
if self.appear(IMMERSIFIER_CHECK):
|
if self.appear(IMMERSIFIER_CHECK):
|
||||||
break
|
break
|
||||||
if self.appear_then_click(ENTER_IMMERSIFIER, interval=2):
|
if self.appear_then_click(IMMERSIFIER_ICON, interval=2):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
def _immersifier_exit(self, skip_first_screenshot=True):
|
def _immersifier_exit(self, skip_first_screenshot=True):
|
||||||
@ -140,7 +142,7 @@ class DungeonStamina(DungeonUI):
|
|||||||
logger.hr('Immersifier store', level=2)
|
logger.hr('Immersifier store', level=2)
|
||||||
logger.info(f'Max store: {max_store}')
|
logger.info(f'Max store: {max_store}')
|
||||||
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
|
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
|
||||||
self.dungeon_update_stamina()
|
self.update_stamina_status()
|
||||||
before = self.config.stored.Immersifier.value
|
before = self.config.stored.Immersifier.value
|
||||||
|
|
||||||
if self.config.stored.Immersifier.is_full():
|
if self.config.stored.Immersifier.is_full():
|
||||||
@ -159,7 +161,7 @@ class DungeonStamina(DungeonUI):
|
|||||||
self._immersifier_enter()
|
self._immersifier_enter()
|
||||||
self._item_amount_set(amount, ocr_button=OCR_IMMERSIFIER_AMOUNT)
|
self._item_amount_set(amount, ocr_button=OCR_IMMERSIFIER_AMOUNT)
|
||||||
self._item_confirm()
|
self._item_confirm()
|
||||||
self.dungeon_update_stamina()
|
self.update_stamina_status()
|
||||||
diff = self.config.stored.Immersifier.value - before
|
diff = self.config.stored.Immersifier.value - before
|
||||||
logger.info(f'Stored {diff} immersifiers')
|
logger.info(f'Stored {diff} immersifiers')
|
||||||
return diff
|
return diff
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from module.base.base import ModuleBase
|
from module.base.base import ModuleBase
|
||||||
from module.base.timer import Timer
|
|
||||||
from module.base.utils import crop
|
from module.base.utils import crop
|
||||||
from module.config.stored.classes import now
|
from module.config.stored.classes import now
|
||||||
from module.config.utils import DEFAULT_TIME, get_server_next_monday_update, get_server_next_update
|
from module.config.utils import DEFAULT_TIME, get_server_next_monday_update, get_server_next_update
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import DigitCounter
|
from module.ocr.ocr import DigitCounter
|
||||||
from tasks.base.ui import UI
|
from tasks.combat.stamina_status import StaminaStatus
|
||||||
from tasks.dungeon.assets.assets_dungeon_state import OCR_SIMUNI_POINT, OCR_SIMUNI_POINT_OFFSET, OCR_STAMINA
|
from tasks.dungeon.assets.assets_dungeon_state import OCR_SIMUNI_POINT, OCR_SIMUNI_POINT_OFFSET
|
||||||
from tasks.dungeon.keywords import DungeonList
|
from tasks.dungeon.keywords import DungeonList
|
||||||
|
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ class OcrSimUniPoint(DigitCounter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class DungeonState(UI):
|
class DungeonState(StaminaStatus):
|
||||||
def dungeon_get_simuni_point(self, image=None) -> int:
|
def dungeon_get_simuni_point(self, image=None) -> int:
|
||||||
"""
|
"""
|
||||||
Page:
|
Page:
|
||||||
@ -48,67 +47,6 @@ class DungeonState(UI):
|
|||||||
logger.warning(f'Invalid SimulatedUniverse points: {value}/{total}')
|
logger.warning(f'Invalid SimulatedUniverse points: {value}/{total}')
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def dungeon_update_stamina(self, image=None, skip_first_screenshot=True):
|
|
||||||
"""
|
|
||||||
Returns:
|
|
||||||
bool: If success
|
|
||||||
|
|
||||||
Pages:
|
|
||||||
in: page_guild, Survival_Index, Simulated_Universe
|
|
||||||
or page_rogue, LEVEL_CONFIRM
|
|
||||||
or rogue, REWARD_CLOSE
|
|
||||||
"""
|
|
||||||
ocr = DigitCounter(OCR_STAMINA)
|
|
||||||
timeout = Timer(1, count=2).start()
|
|
||||||
if image is None:
|
|
||||||
image = self.device.image
|
|
||||||
use_cached_image = False
|
|
||||||
else:
|
|
||||||
skip_first_screenshot = True
|
|
||||||
use_cached_image = True
|
|
||||||
|
|
||||||
while 1:
|
|
||||||
if skip_first_screenshot:
|
|
||||||
skip_first_screenshot = False
|
|
||||||
else:
|
|
||||||
self.device.screenshot()
|
|
||||||
image = self.device.image
|
|
||||||
|
|
||||||
stamina = (0, 0, 0)
|
|
||||||
immersifier = (0, 0, 0)
|
|
||||||
|
|
||||||
if timeout.reached():
|
|
||||||
logger.warning('dungeon_update_stamina() timeout')
|
|
||||||
return False
|
|
||||||
|
|
||||||
for row in ocr.detect_and_ocr(image):
|
|
||||||
if row.ocr_text.isdigit():
|
|
||||||
continue
|
|
||||||
if row.ocr_text == '+':
|
|
||||||
continue
|
|
||||||
if not ocr.is_format_matched(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
|
|
||||||
if use_cached_image:
|
|
||||||
logger.info('dungeon_update_stamina() ended')
|
|
||||||
return
|
|
||||||
|
|
||||||
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
|
|
||||||
return True
|
|
||||||
|
|
||||||
def dungeon_update_simuni(self):
|
def dungeon_update_simuni(self):
|
||||||
"""
|
"""
|
||||||
Update rogue weekly points, stamina, immersifier
|
Update rogue weekly points, stamina, immersifier
|
||||||
@ -122,8 +60,8 @@ class DungeonState(UI):
|
|||||||
def func(image):
|
def func(image):
|
||||||
logger.info('Update thread start')
|
logger.info('Update thread start')
|
||||||
with self.config.multi_set():
|
with self.config.multi_set():
|
||||||
self.dungeon_get_simuni_point(image)
|
# self.dungeon_get_simuni_point(image)
|
||||||
self.dungeon_update_stamina(image)
|
self.update_stamina_status(image)
|
||||||
|
|
||||||
ModuleBase.worker.submit(func, self.device.image)
|
ModuleBase.worker.submit(func, self.device.image)
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ class OrnamentCombat(Dungeon, RouteLoader, DungeonState):
|
|||||||
|
|
||||||
after = before
|
after = before
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
self.dungeon_update_stamina()
|
self.update_stamina_status()
|
||||||
after = self.get_equivalent_stamina()
|
after = self.get_equivalent_stamina()
|
||||||
if expect_reduce:
|
if expect_reduce:
|
||||||
if before > after:
|
if before > after:
|
||||||
|
@ -261,7 +261,7 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonRogueUI
|
|||||||
if not self.image_color_count(LEVEL_CONFIRM, color=(223, 223, 225), threshold=240, count=50):
|
if not self.image_color_count(LEVEL_CONFIRM, color=(223, 223, 225), threshold=240, count=50):
|
||||||
self.interval_clear(LEVEL_CONFIRM)
|
self.interval_clear(LEVEL_CONFIRM)
|
||||||
continue
|
continue
|
||||||
self.dungeon_update_stamina()
|
self.update_stamina_status()
|
||||||
self.check_stop_condition()
|
self.check_stop_condition()
|
||||||
self.device.click(LEVEL_CONFIRM)
|
self.device.click(LEVEL_CONFIRM)
|
||||||
continue
|
continue
|
||||||
|
@ -54,7 +54,7 @@ class RogueReward(RogueUI, CombatInteract, DungeonState):
|
|||||||
confirm.reset()
|
confirm.reset()
|
||||||
continue
|
continue
|
||||||
if self.appear(REWARD_CLOSE, interval=2):
|
if self.appear(REWARD_CLOSE, interval=2):
|
||||||
self.dungeon_update_stamina()
|
self.update_stamina_status()
|
||||||
if not init:
|
if not init:
|
||||||
initial_stamina = self.config.stored.TrailblazePower.value
|
initial_stamina = self.config.stored.TrailblazePower.value
|
||||||
initial_immersifier = self.config.stored.Immersifier.value
|
initial_immersifier = self.config.stored.Immersifier.value
|
||||||
|