mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-22 00:35:34 +00:00
Fix: No kids as low camera height may miss enemy aim icon
This commit is contained in:
parent
0f11911e5c
commit
21307e209e
@ -8,6 +8,7 @@ from hashlib import md5
|
||||
|
||||
from module.base.code_generator import CodeGenerator
|
||||
from module.config.utils import deep_get, read_file
|
||||
from module.exception import ScriptError
|
||||
from module.logger import logger
|
||||
|
||||
UI_LANGUAGES = ['cn', 'cht', 'en', 'jp', 'es']
|
||||
@ -38,15 +39,24 @@ def blessing_name(name: str) -> str:
|
||||
return name
|
||||
|
||||
|
||||
nickname_count = 0
|
||||
|
||||
|
||||
def character_name(name: str) -> str:
|
||||
name = text_to_variable(name)
|
||||
name = re.sub('_', '', name)
|
||||
return name
|
||||
|
||||
|
||||
def convert_inner_character_to_keyword(name):
|
||||
convert_dict = {
|
||||
'Silwolf': 'SilverWolf',
|
||||
'Klara': 'Clara',
|
||||
'Mar_7th': 'March7th',
|
||||
'PlayerGirl': 'TrailblazerFemale',
|
||||
'PlayerBoy': 'TrailblazerMale',
|
||||
'Ren': 'Blade',
|
||||
}
|
||||
return convert_dict.get(name, name)
|
||||
|
||||
|
||||
class TextMap:
|
||||
DATA_FOLDER = ''
|
||||
|
||||
@ -381,6 +391,30 @@ class KeywordExtract:
|
||||
self.load_character_name_keywords()
|
||||
self.write_keywords(keyword_class='CharacterList', output_file='./tasks/character/keywords/character_list.py',
|
||||
text_convert=character_name)
|
||||
# Generate character height
|
||||
characters = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'FreeStyleCharacterConfig.json'))
|
||||
regex = re.compile(r'NPC_Avatar_(?P<height>.*?)_(?P<character>.*?)_00')
|
||||
gen = CodeGenerator()
|
||||
dict_height = {}
|
||||
height_index = ['Kid', 'Girl', 'Boy', 'Maid', 'Miss', 'Lady', 'Lad', 'Male']
|
||||
for key in characters.keys():
|
||||
if res := regex.search(key):
|
||||
character, height = res.group('character'), res.group('height')
|
||||
if height not in height_index:
|
||||
continue
|
||||
dict_height[character] = height
|
||||
dict_height = {k: v for k, v in sorted(dict_height.items(), key=lambda item: height_index.index(item[1]))}
|
||||
from tasks.character.keywords.classes import CharacterList
|
||||
with gen.Dict('CHARACTER_HEIGHT'):
|
||||
for character, height in dict_height.items():
|
||||
character = convert_inner_character_to_keyword(character)
|
||||
try:
|
||||
CharacterList.find_name(character)
|
||||
except ScriptError:
|
||||
print(f'Character height data {character} is not defined')
|
||||
continue
|
||||
gen.DictItem(key=character, value=height)
|
||||
gen.write('./tasks/character/keywords/height.py')
|
||||
|
||||
def generate_battle_pass_quests(self):
|
||||
battle_pass_quests = read_file(os.path.join(TextMap.DATA_FOLDER, 'ExcelOutput', 'BattlePassConfig.json'))
|
||||
|
@ -180,3 +180,24 @@ class Keyword:
|
||||
|
||||
# Not found
|
||||
raise ScriptError(f'Cannot find a {cls.__name__} instance that matches "{name}"')
|
||||
|
||||
@classmethod
|
||||
def find_name(cls, name):
|
||||
"""
|
||||
Args:
|
||||
name: Attribute name of keyword.
|
||||
|
||||
Returns:
|
||||
Keyword instance.
|
||||
|
||||
Raises:
|
||||
ScriptError: If nothing found.
|
||||
"""
|
||||
if isinstance(name, Keyword):
|
||||
return name
|
||||
for instance in cls.instances.values():
|
||||
if name == instance.name:
|
||||
return instance
|
||||
|
||||
# Not found
|
||||
raise ScriptError(f'Cannot find a {cls.__name__} instance that matches "{name}"')
|
||||
|
@ -9,9 +9,19 @@ from module.ocr.keyword import Keyword
|
||||
class CharacterList(Keyword):
|
||||
instances: ClassVar = {}
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return super().__hash__()
|
||||
|
||||
@cached_property
|
||||
def is_trailblazer(self) -> bool:
|
||||
return 'Trailblazer' in self.name
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return super().__hash__()
|
||||
@cached_property
|
||||
def height(self) -> str:
|
||||
"""
|
||||
Returns:
|
||||
str: Character height, from list ['Kid', 'Girl', 'Boy', 'Maid', 'Miss', 'Lady', 'Lad', 'Male']
|
||||
or 'Unknown' if no data
|
||||
"""
|
||||
from tasks.character.keywords.height import CHARACTER_HEIGHT
|
||||
return CHARACTER_HEIGHT.get(self.name, 'Unknown')
|
||||
|
31
tasks/character/keywords/height.py
Normal file
31
tasks/character/keywords/height.py
Normal file
@ -0,0 +1,31 @@
|
||||
CHARACTER_HEIGHT = {
|
||||
'Hook': 'Kid',
|
||||
'Bailu': 'Kid',
|
||||
'SilverWolf': 'Girl',
|
||||
'Qingque': 'Girl',
|
||||
'Pela': 'Girl',
|
||||
'Clara': 'Girl',
|
||||
'Herta': 'Girl',
|
||||
'FuXuan': 'Girl',
|
||||
'Yanqing': 'Boy',
|
||||
'Arlan': 'Boy',
|
||||
'Tingyun': 'Maid',
|
||||
'Sushang': 'Maid',
|
||||
'Seele': 'Maid',
|
||||
'March7th': 'Maid',
|
||||
'Jingliu': 'Maid',
|
||||
'Bronya': 'Maid',
|
||||
'Asta': 'Maid',
|
||||
'Yukong': 'Lady',
|
||||
'Serval': 'Lady',
|
||||
'Natasha': 'Lady',
|
||||
'Kafka': 'Lady',
|
||||
'Himeko': 'Lady',
|
||||
'DanHeng': 'Lad',
|
||||
'Welt': 'Male',
|
||||
'Sampo': 'Male',
|
||||
'Blade': 'Male',
|
||||
'Luocha': 'Male',
|
||||
'JingYuan': 'Male',
|
||||
'Gepard': 'Male',
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
import re
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from scipy import signal
|
||||
@ -17,6 +19,8 @@ class OcrCharacterName(OcrWhiteLetterOnComplexBackground):
|
||||
|
||||
def after_process(self, result):
|
||||
result = result.replace('蛆', '妲')
|
||||
# Dan Heng o.ImbibitorLunae
|
||||
result = re.sub(r'[0Oo\-. ]{1,3}Imbi', 'Imbi', result)
|
||||
|
||||
return super().after_process(result)
|
||||
|
||||
@ -140,7 +144,7 @@ class CharacterSwitch(UI):
|
||||
return selected
|
||||
|
||||
def _convert_selected_to_character(self, selected: list[int]) -> CharacterList | None:
|
||||
expected_peaks = np.array([201, 279, 357, 435])
|
||||
expected_peaks = [201, 279, 357, 435]
|
||||
if not selected:
|
||||
logger.warning(f'No current character')
|
||||
logger.attr('CurrentCharacter', None)
|
||||
@ -227,6 +231,14 @@ class CharacterSwitch(UI):
|
||||
if ranged_character in self.characters:
|
||||
logger.info(f'Use ranged character: {ranged_character}, range={level}')
|
||||
return ranged_character
|
||||
# No kids, as low camera height may miss enemy aim icon
|
||||
if self.character_current.height == 'Kid':
|
||||
# Switch to whoever tall
|
||||
for height in ['Male', 'Lad', 'Lady', 'Miss', 'Maid', 'Boy', 'Girl']:
|
||||
for tall_character in self.characters:
|
||||
if tall_character.height == height:
|
||||
logger.info(f'No kids, use tall character: {tall_character}')
|
||||
return tall_character
|
||||
# No ranged characters
|
||||
logger.info('No ranged characters in team')
|
||||
return False
|
||||
|
@ -155,7 +155,7 @@ class RoguePathHandler(RogueUI):
|
||||
or page_main if previous rogue run had bonus selected but didn't finish any domain
|
||||
"""
|
||||
logger.hr('Rogue path select', level=2)
|
||||
path: RoguePath = RoguePath.find_path(path)
|
||||
path: RoguePath = RoguePath.find_name(path)
|
||||
logger.info(f'Select path: {path}')
|
||||
entry = self._get_path_click(path)
|
||||
while 1:
|
||||
|
@ -36,16 +36,6 @@ class RoguePath(Keyword):
|
||||
return [self.__getattribute__(f"{server}_parsed").replace("the", '')
|
||||
for server in UI_LANGUAGES if hasattr(self, f"{server}_parsed")]
|
||||
|
||||
@classmethod
|
||||
def find_path(cls, name):
|
||||
if isinstance(name, RoguePath):
|
||||
return name
|
||||
for instance in cls.instances.values():
|
||||
if name == instance.name:
|
||||
return instance
|
||||
# Not found
|
||||
raise ScriptError(f'Cannot find a {cls.__name__} instance that matches "{name}"')
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class RogueResonance(Keyword):
|
||||
|
Loading…
Reference in New Issue
Block a user