mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-12-01 03:37:56 +00:00
178 lines
4.8 KiB
Python
178 lines
4.8 KiB
Python
from dataclasses import dataclass
|
|
from functools import cached_property
|
|
from typing import ClassVar
|
|
|
|
from module.exception import ScriptError
|
|
from module.ocr.keyword import Keyword
|
|
|
|
|
|
@dataclass(repr=False)
|
|
class MapPlane(Keyword):
|
|
instances: ClassVar = {}
|
|
|
|
# 0, 1, 2, 3
|
|
world_id: int
|
|
# 1010201
|
|
plane_id: int
|
|
|
|
# Map floors, 'F1' by default
|
|
# Example: ['B1', 'F1', 'F2']
|
|
floors = ['F1']
|
|
|
|
# Page on bigmap sidebar
|
|
# 'top' or 'bottom'
|
|
page = 'top'
|
|
|
|
@classmethod
|
|
def find_plane_id(cls, plane_id):
|
|
"""
|
|
Args:
|
|
plane_id:
|
|
|
|
Returns:
|
|
MapPlane: MapPlane object or None
|
|
"""
|
|
for instance in cls.instances.values():
|
|
if instance.plane_id == plane_id:
|
|
return instance
|
|
return None
|
|
|
|
def __hash__(self) -> int:
|
|
return super().__hash__()
|
|
|
|
@cached_property
|
|
def world(self) -> "MapWorld":
|
|
"""
|
|
Returns:
|
|
MapWorld: MapWorld object or None
|
|
"""
|
|
return MapWorld.find_world_id(self.world_id)
|
|
|
|
@cached_property
|
|
def has_multiple_floors(self):
|
|
return self.floors and self.floors != ['F1']
|
|
|
|
def convert_to_floor_index(self, floor: str | int) -> int:
|
|
"""
|
|
Args:
|
|
floor: int for floor index counted from bottom, such as 1, 2, 3
|
|
str for floor names in game, such as "B1", "F1", "F2"
|
|
|
|
Returns:
|
|
int: 1 to 3 counted from bottom.
|
|
|
|
Raises:
|
|
ScriptError: If floor doesn't exist
|
|
"""
|
|
if isinstance(floor, int):
|
|
# Check exist
|
|
try:
|
|
_ = self.floors[floor - 1]
|
|
return floor
|
|
except (IndexError, ValueError):
|
|
raise ScriptError(f'Plane {self} does not have floor index {floor}')
|
|
elif isinstance(floor, str):
|
|
# Convert to floor index
|
|
floor = floor.upper()
|
|
try:
|
|
return self.floors.index(floor) + 1
|
|
except (IndexError, ValueError):
|
|
raise ScriptError(f'Plane {self} does not have floor name {floor}')
|
|
else:
|
|
raise ScriptError(f'Plane {self} does not have floor {floor}')
|
|
|
|
def convert_to_floor_name(self, floor: str | int) -> str:
|
|
"""
|
|
Args:
|
|
floor: int for floor index counted from bottom, such as 1, 2, 3
|
|
str for floor names in game, such as "B1", "F1", "F2"
|
|
|
|
Returns:
|
|
str: Floor names in game, such as "B1", "F1", "F2"
|
|
|
|
Raises:
|
|
ScriptError: If floor doesn't exist
|
|
"""
|
|
if isinstance(floor, int):
|
|
# Convert to floor index
|
|
try:
|
|
return self.floors[floor - 1]
|
|
except (IndexError, ValueError):
|
|
raise ScriptError(f'Plane {self} does not have floor index {floor}')
|
|
elif isinstance(floor, str):
|
|
# Check exist
|
|
floor = floor.upper()
|
|
try:
|
|
_ = self.floors.index(floor) + 1
|
|
return floor
|
|
except (IndexError, ValueError):
|
|
raise ScriptError(f'Plane {self} does not have floor name {floor}')
|
|
else:
|
|
raise ScriptError(f'Plane {self} does not have floor {floor}')
|
|
|
|
@cached_property
|
|
def rogue_domain(self) -> str:
|
|
if self.name.startswith('Rogue_Domain'):
|
|
return self.name.removeprefix('Rogue_Domain')
|
|
else:
|
|
return ''
|
|
|
|
@cached_property
|
|
def is_rogue_combat(self) -> bool:
|
|
return self.rogue_domain in ['Combat']
|
|
|
|
@cached_property
|
|
def is_rogue_occurrence(self) -> bool:
|
|
return self.rogue_domain in ['Occurrence', 'Encounter', 'Transaction']
|
|
|
|
@cached_property
|
|
def is_rogue_respite(self) -> bool:
|
|
return self.rogue_domain in ['Respite']
|
|
|
|
@cached_property
|
|
def is_rogue_elite(self) -> bool:
|
|
return self.rogue_domain in ['Elite', 'Boss']
|
|
|
|
|
|
@dataclass(repr=False)
|
|
class MapWorld(Keyword):
|
|
instances: ClassVar = {}
|
|
|
|
# 0, 1, 2, 3
|
|
world_id: int
|
|
# Herta
|
|
short_name: str
|
|
|
|
@classmethod
|
|
def find_world_id(cls, world_id):
|
|
"""
|
|
Args:
|
|
world_id:
|
|
|
|
Returns:
|
|
MapWorld: MapWorld object or None
|
|
"""
|
|
for instance in cls.instances.values():
|
|
if instance.world_id == world_id:
|
|
return instance
|
|
return None
|
|
|
|
def __hash__(self) -> int:
|
|
return super().__hash__()
|
|
|
|
@cached_property
|
|
def is_Herta(self):
|
|
return self.short_name == 'Herta'
|
|
|
|
@cached_property
|
|
def is_Jarilo(self):
|
|
return self.short_name == 'Jarilo'
|
|
|
|
@cached_property
|
|
def is_Luofu(self):
|
|
return self.short_name == 'Luofu'
|
|
|
|
@cached_property
|
|
def is_Penacony(self):
|
|
return self.short_name == 'Penacony'
|