BallanceBlenderHelper/bbp_ng/UTIL_naming_convension.py

604 lines
23 KiB
Python
Raw Normal View History

import bpy
2023-12-06 17:16:31 +08:00
import typing, enum, re
from . import UTIL_functions
2023-11-26 12:57:49 +08:00
from . import PROP_virtools_group
#region Rename Error Reporter
class _RenameErrorType(enum.IntEnum):
ERROR = enum.auto()
WARNING = enum.auto()
INFO = enum.auto()
class _RenameErrorItem():
mErrType: _RenameErrorType
mDescription: str
def __init__(self, err_t: _RenameErrorType, description: str):
self.mErrType = err_t
self.mDescription = description
class RenameErrorReporter():
"""
A basic 'rename error report' using simple prints in console.
This object can be used as a context manager.
It supports multiple levels of 'substeps' - you shall always enter at least one substep (because level 0
has only one single step, representing the whole 'area' of the progress stuff).
You should give the object renaming of substeps each time you enter a new one.
Leaving a substep automatically steps by one the parent level.
```
with RenameErrorReporter() as reporter:
progress.enter_object(obj)
# process for object with reporter
reporter.add_error('fork!')
progress.leave_object()
```
"""
mAllObjCounter: int
mFailedObjCounter: int
2023-11-26 12:57:49 +08:00
mErrList: list[_RenameErrorItem]
2023-11-29 21:35:15 +08:00
mOldName: str
mHasError: bool
2023-11-26 12:57:49 +08:00
def __init__(self):
self.mAllObjCounter = 0
self.mFailedObjCounter = 0
2023-11-26 12:57:49 +08:00
self.mErrList = []
2023-11-29 21:35:15 +08:00
self.mOldName = ""
self.mHasError = False
2023-11-26 12:57:49 +08:00
def add_error(self, description: str):
self.mHasError = True
2023-11-26 12:57:49 +08:00
self.mErrList.append(_RenameErrorItem(_RenameErrorType.ERROR, description))
def add_warning(self, description: str):
self.mErrList.append(_RenameErrorItem(_RenameErrorType.WARNING, description))
def add_info(self, description: str):
self.mErrList.append(_RenameErrorItem(_RenameErrorType.INFO, description))
def get_all_objs_count(self) -> int: return self.mAllObjCounter
def get_failed_objs_count(self) -> int: return self.mFailedObjCounter
def __enter__(self):
# print console report header
print('============')
print('Rename Report')
print('------------')
# return self as context
return self
def __exit__(self, exc_type, exc_value, traceback):
# print console report tail
print('------------')
print(f'All / Failed - {self.mAllObjCounter} / {self.mFailedObjCounter}')
print('============')
# reset variables
self.mAllObjCounter = 0
self.mFailedObjCounter = 0
def enter_object(self, obj: bpy.types.Object) -> None:
# inc all counter
self.mAllObjCounter += 1
2023-11-29 21:35:15 +08:00
# assign old name
self.mOldName = obj.name
def leave_object(self, obj:bpy.types.Object) -> None:
2023-11-29 21:35:15 +08:00
# if error list is empty, no need to report
if len(self.mErrList) == 0: return
# inc failed if necessary
if self.mHasError:
self.mFailedObjCounter += 1
2023-11-29 21:35:15 +08:00
# output header
# if new name is different with old name, output both of them
new_name: str = obj.name
if self.mOldName == new_name:
print(f'For object "{new_name}"')
else:
print(f'For object "{new_name}" (Old name: "{self.mOldName}")')
# output error list with indent
2023-11-26 12:57:49 +08:00
for item in self.mErrList:
print('\t' + RenameErrorReporter.__erritem_to_string(item))
2023-11-29 21:35:15 +08:00
# clear error list for next object
2023-11-26 12:57:49 +08:00
self.mErrList.clear()
self.mHasError = False
2023-11-26 12:57:49 +08:00
@staticmethod
def __errtype_to_string(err_v: _RenameErrorType) -> str:
match(err_v):
case _RenameErrorType.ERROR: return 'ERROR'
case _RenameErrorType.WARNING: return 'WARN'
case _RenameErrorType.INFO: return 'INFO'
case _: raise UTIL_functions.BBPException("Unknown error type.")
@staticmethod
def __erritem_to_string(item: _RenameErrorItem) -> str:
return f'[{RenameErrorReporter.__errtype_to_string(item.mErrType)}]\t{item.mDescription}'
2023-11-26 12:57:49 +08:00
#endregion
#region Naming Convention Used Types
2023-11-29 22:12:04 +08:00
class BallanceObjectType(enum.IntEnum):
2023-11-26 12:57:49 +08:00
COMPONENT = enum.auto()
FLOOR = enum.auto()
RAIL = enum.auto()
WOOD = enum.auto()
STOPPER = enum.auto()
LEVEL_START = enum.auto()
LEVEL_END = enum.auto()
CHECKPOINT = enum.auto()
RESETPOINT = enum.auto()
DEPTH_CUBE = enum.auto()
SKYLAYER = enum.auto()
DECORATION = enum.auto()
2023-11-29 22:12:04 +08:00
class BallanceObjectInfo():
mBasicType: BallanceObjectType
2023-11-26 12:57:49 +08:00
## Only available for COMPONENT basic type
mComponentType: str | None
## Only available for COMPONENT, CHECKPOINT, RESETPOINT basic type
# For COMPONENT, it indicate which sector this component belong to.
# For CHECKPOINT, RESETPOINT, it indicate the index of this object.
# In CHECKPOINT, RESETPOINT mode, the sector actually is the suffix number of these objects' name. So checkpoint starts with 1, not 0.
mSector: int | None
2023-11-29 22:12:04 +08:00
def __init__(self, basic_type: BallanceObjectType):
2023-11-26 12:57:49 +08:00
self.mBasicType = basic_type
@classmethod
def create_from_component(cls, comp_type: str, sector: int):
2023-11-29 22:12:04 +08:00
inst = cls(BallanceObjectType.COMPONENT)
2023-11-26 12:57:49 +08:00
inst.mComponentType = comp_type
inst.mSector = sector
return inst
@classmethod
def create_from_checkpoint(cls, sector: int):
2023-11-29 22:12:04 +08:00
inst = cls(BallanceObjectType.CHECKPOINT)
2023-11-26 12:57:49 +08:00
inst.mSector = sector
return inst
@classmethod
def create_from_resetpoint(cls, sector: int):
2023-11-29 22:12:04 +08:00
inst = cls(BallanceObjectType.RESETPOINT)
2023-11-26 12:57:49 +08:00
inst.mSector = sector
return inst
@classmethod
2023-11-29 22:12:04 +08:00
def create_from_others(cls, basic_type: BallanceObjectType):
2023-11-26 12:57:49 +08:00
return cls(basic_type)
#endregion
#region Naming Convention Declaration
2023-12-06 17:16:31 +08:00
_g_BlcNormalComponents: set[str] = set((
2023-12-15 21:57:50 +08:00
"P_Extra_Life",
"P_Extra_Point",
"P_Trafo_Paper",
"P_Trafo_Stone",
"P_Trafo_Wood",
"P_Ball_Paper",
"P_Ball_Stone",
"P_Ball_Wood",
"P_Box",
"P_Dome",
"P_Modul_01",
"P_Modul_03",
"P_Modul_08",
"P_Modul_17",
"P_Modul_18",
"P_Modul_19",
"P_Modul_25",
"P_Modul_26",
"P_Modul_29",
"P_Modul_30",
"P_Modul_34",
"P_Modul_37",
"P_Modul_41"
2023-12-06 17:16:31 +08:00
))
_g_BlcUniqueComponents: set[str] = set((
2023-12-15 21:57:50 +08:00
"PS_Levelstart",
"PE_Levelende",
"PC_Checkpoints",
"PR_Resetpoints"
2023-12-06 17:16:31 +08:00
))
_g_BlcFloor: set[str] = set((
2023-12-15 21:57:50 +08:00
"Sound_HitID_01",
"Sound_RollID_01"
2023-12-06 17:16:31 +08:00
))
_g_BlcWood: set[str] = set((
2023-12-15 21:57:50 +08:00
"Sound_HitID_02",
"Sound_RollID_02"
2023-12-06 17:16:31 +08:00
))
class VirtoolsGroupConvention():
2023-12-06 17:16:31 +08:00
cRegexGroupSector: typing.ClassVar[re.Pattern] = re.compile('^Sector_(0[1-8]|[1-9][0-9]{1,2}|9)$')
cRegexComponent: typing.ClassVar[re.Pattern] = re.compile('^(' + '|'.join(_g_BlcNormalComponents) + ')_(0[1-9]|[1-9][0-9])_.*$')
cRegexPC: typing.ClassVar[re.Pattern] = re.compile('^PC_TwoFlames_(0[1-7])$')
cRegexPR: typing.ClassVar[re.Pattern] = re.compile('^PR_Resetpoint_(0[1-8])$')
2023-11-26 12:57:49 +08:00
@staticmethod
def __get_pcpr_from_name(name: str, reporter: RenameErrorReporter | None) -> BallanceObjectInfo | None:
regex_result = VirtoolsGroupConvention.cRegexPC.match(name)
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_checkpoint(
int(regex_result.group(1))
)
regex_result = VirtoolsGroupConvention.cRegexPR.match(name)
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_resetpoint(
int(regex_result.group(1))
)
if reporter: reporter.add_error("PC_Checkpoints or PR_Resetpoints detected. But couldn't get sector from name.")
2023-11-29 21:35:15 +08:00
return None
2023-12-06 17:16:31 +08:00
@staticmethod
def __get_sector_from_groups(gps: typing.Iterator[str]) -> int | None:
# this counter is served for stupid
# multi-sector-grouping accident.
counter: int = 0
last_matched_sector: int = 0
for i in gps:
regex_result = VirtoolsGroupConvention.cRegexGroupSector.match(i)
2023-12-06 17:16:31 +08:00
if regex_result is not None:
last_matched_sector = int(regex_result.group(1))
counter += 1
if counter != 1: return None
else: return last_matched_sector
@staticmethod
def parse_from_object(obj: bpy.types.Object, reporter: RenameErrorReporter | None) -> BallanceObjectInfo | None:
2023-12-06 17:16:31 +08:00
# create visitor
with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp:
# if no group, we should consider it is decoration or skylayer
if gp.get_count() == 0:
if obj.name == 'SkyLayer': return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER)
else: return BallanceObjectInfo.create_from_others(BallanceObjectType.DECORATION)
# try to filter unique elements first
inter_gps: set[str] = gp.intersect_groups(_g_BlcUniqueComponents)
if len(inter_gps) == 1:
# get it
match((tuple(inter_gps))[0]):
2023-12-15 21:57:50 +08:00
case 'PS_Levelstart':
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.LEVEL_START)
2023-12-15 21:57:50 +08:00
case 'PE_Levelende':
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.LEVEL_END)
2023-12-15 21:57:50 +08:00
case 'PC_Checkpoints' | 'PR_Resetpoints':
2023-12-06 17:16:31 +08:00
# these type's data should be gotten from its name
return VirtoolsGroupConvention.__get_pcpr_from_name(obj.name, reporter)
2023-12-06 17:16:31 +08:00
case _:
if reporter: reporter.add_error("The match of Unique Component lost.")
return None
elif len(inter_gps) != 0:
if reporter: reporter.add_error("A Multi-grouping Unique Component.")
return None
# distinguish normal elements
inter_gps = gp.intersect_groups(_g_BlcNormalComponents)
if len(inter_gps) == 1:
# get it
# now try get its sector
gotten_elements: str = (tuple(inter_gps))[0]
gotten_sector: int | None = VirtoolsGroupConvention.__get_sector_from_groups(gp.iterate_groups())
2023-12-06 17:16:31 +08:00
if gotten_sector is None:
# fail to get sector
if reporter: reporter.add_error("Component detected. But couldn't get sector from CKGroup data.")
return None
return BallanceObjectInfo.create_from_component(
gotten_elements,
gotten_sector
)
elif len(inter_gps) != 0:
# must be a weird grouping, report it
if reporter: reporter.add_error("A Multi-grouping Component.")
return None
# distinguish road
2023-12-15 21:57:50 +08:00
if gp.contain_group('Phys_FloorRails'):
2023-12-06 17:16:31 +08:00
# rail
return BallanceObjectInfo.create_from_others(BallanceObjectType.RAIL)
2023-12-15 21:57:50 +08:00
elif gp.contain_group('Phys_Floors'):
2023-12-06 17:16:31 +08:00
# distinguish it between Floor and Wood
floor_result = gp.intersect_groups(_g_BlcFloor)
rail_result = gp.intersect_groups(_g_BlcWood)
if len(floor_result) > 0 and len(rail_result) == 0:
return BallanceObjectInfo.create_from_others(BallanceObjectType.FLOOR)
elif len(floor_result) == 0 and len(rail_result) > 0:
return BallanceObjectInfo.create_from_others(BallanceObjectType.WOOD)
else:
if reporter: reporter.add_warning("Can't distinguish object between Floors and Rails. Suppose it is Floors.")
return BallanceObjectInfo.create_from_others(BallanceObjectType.FLOOR)
2023-12-15 21:57:50 +08:00
elif gp.contain_group('Phys_FloorStopper'):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.STOPPER)
2023-12-15 21:57:50 +08:00
elif gp.contain_group('DepthTestCubes'):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.DEPTH_CUBE)
# no matched
if reporter: reporter.add_error("Group match lost.")
return None
2023-11-26 12:57:49 +08:00
@staticmethod
def set_to_object(obj: bpy.types.Object, info: BallanceObjectInfo, reporter: RenameErrorReporter | None) -> bool:
2023-12-06 17:16:31 +08:00
# create visitor
with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp:
# match by basic type
match(info.mBasicType):
case BallanceObjectType.DECORATION: pass # decoration do not need group
case BallanceObjectType.SKYLAYER: pass # sky layer do not need group
case BallanceObjectType.LEVEL_START:
2023-12-15 21:57:50 +08:00
gp.add_group('PS_Levelstart')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.LEVEL_END:
2023-12-15 21:57:50 +08:00
gp.add_group('PE_Levelende')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.CHECKPOINT:
2023-12-15 21:57:50 +08:00
gp.add_group('PC_Checkpoints')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.RESETPOINT:
2023-12-15 21:57:50 +08:00
gp.add_group('PR_Resetpoints')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.DEPTH_CUBE:
2023-12-15 21:57:50 +08:00
gp.add_group('PE_Levelende')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.FLOOR:
2023-12-15 21:57:50 +08:00
gp.add_group('Phys_Floors')
gp.add_group('Sound_HitID_01')
gp.add_group('Sound_RollID_01')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.RAIL:
2023-12-15 21:57:50 +08:00
gp.add_group('Phys_FloorRails')
gp.add_group('Sound_HitID_02')
gp.add_group('Sound_RollID_02')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.WOOD:
2023-12-15 21:57:50 +08:00
gp.add_group('Phys_Floors')
gp.add_group('Sound_HitID_03')
gp.add_group('Sound_RollID_03')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.STOPPER:
2023-12-15 21:57:50 +08:00
gp.add_group('Phys_FloorStopper')
2023-12-06 17:16:31 +08:00
case BallanceObjectType.COMPONENT:
# group into component type
# use typing.cast() to force linter accept it because None is impossible
gp.add_group(typing.cast(str, info.mComponentType))
2023-12-06 17:16:31 +08:00
# group to sector
if info.mSector == 9:
gp.add_group('Sector_9')
else:
gp.add_group(f'Sector_{info.mSector:0>2d}')
case _:
if reporter is not None:
reporter.add_error('No matched info.')
return False
return True
2023-11-26 12:57:49 +08:00
class YYCToolchainConvention():
2023-11-26 12:57:49 +08:00
@staticmethod
def parse_from_name(name: str, reporter: RenameErrorReporter | None) -> BallanceObjectInfo | None:
2023-12-06 17:16:31 +08:00
# check component first
regex_result = VirtoolsGroupConvention.cRegexComponent.match(name) # use vt one because they are same
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_component(
regex_result.group(1),
int(regex_result.group(2))
)
# check PC PR elements
regex_result = VirtoolsGroupConvention.cRegexPC.match(name) # use vt one because they are same
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_checkpoint(
int(regex_result.group(1))
)
regex_result = VirtoolsGroupConvention.cRegexPR.match(name) # use vt one because they are same
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_resetpoint(
int(regex_result.group(1))
)
# check other unique elements
if name == "PS_FourFlames_01":
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.LEVEL_START)
if name == "PE_Balloon_01":
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.LEVEL_END)
# process floors
if name.startswith("A_Floor"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.FLOOR)
if name.startswith("A_Rail"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.RAIL)
if name.startswith("A_Wood"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.WOOD)
if name.startswith("A_Stopper"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.STOPPER)
# process others
if name.startswith("DepthCubes"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.DEPTH_CUBE)
if name.startswith("D_"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.DECORATION)
if name == 'SkyLayer':
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER)
if reporter is not None:
reporter.add_error("Name match lost.")
2023-11-29 21:35:15 +08:00
return None
2023-11-26 12:57:49 +08:00
@staticmethod
def parse_from_object(obj: bpy.types.Object, reporter: RenameErrorReporter | None) -> BallanceObjectInfo | None:
return YYCToolchainConvention.parse_from_name(obj.name, reporter)
2023-11-26 12:57:49 +08:00
@staticmethod
def set_to_name(info: BallanceObjectInfo, reporter: RenameErrorReporter | None) -> str | None:
2023-12-06 17:16:31 +08:00
match(info.mBasicType):
case BallanceObjectType.DECORATION:
return 'D_'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.SKYLAYER:
return 'SkyLayer'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.LEVEL_START:
return 'PS_FourFlames_01'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.LEVEL_END:
return 'PE_Balloon_01'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.CHECKPOINT:
return f'PR_Resetpoint_{info.mSector:0>2d}'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.RESETPOINT:
return f'PC_TwoFlames_{info.mSector:0>2d}'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.DEPTH_CUBE:
return 'DepthCubes_'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.FLOOR:
return 'A_Floor_'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.RAIL:
return 'A_Rail_'
2024-01-06 23:51:11 +08:00
case BallanceObjectType.WOOD:
return 'A_Wood_'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.STOPPER:
return 'A_Stopper_'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.COMPONENT:
return '{}_{:0>2d}_'.format(
2023-12-06 17:16:31 +08:00
info.mComponentType, info.mSector)
case _:
if reporter is not None:
reporter.add_error('No matched info.')
return None
2023-12-06 17:16:31 +08:00
@staticmethod
def set_to_object(obj: bpy.types.Object, info: BallanceObjectInfo, reporter: RenameErrorReporter | None) -> bool:
expect_name: str | None = YYCToolchainConvention.set_to_name(info, reporter)
if expect_name is None: return False
obj.name = expect_name
2023-12-06 17:16:31 +08:00
return True
2023-11-26 12:57:49 +08:00
class ImengyuConvention():
2023-12-06 17:16:31 +08:00
cRegexComponent: typing.ClassVar[re.Pattern] = re.compile('^(' + '|'.join(_g_BlcNormalComponents) + '):[^:]*:([1-9]|[1-9][0-9])$')
cRegexPC: typing.ClassVar[re.Pattern] = re.compile('^PC_CheckPoint:([0-9]+)$')
cRegexPR: typing.ClassVar[re.Pattern] = re.compile('^PR_ResetPoint:([0-9]+)$')
2023-11-26 12:57:49 +08:00
@staticmethod
def parse_from_name(name: str, reporter: RenameErrorReporter | None) -> BallanceObjectInfo | None:
2023-12-06 17:16:31 +08:00
# check component first
regex_result = ImengyuConvention.cRegexComponent.match(name)
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_component(
regex_result.group(1),
int(regex_result.group(2))
)
# check PC PR elements
regex_result = ImengyuConvention.cRegexPC.match(name)
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_checkpoint(
int(regex_result.group(1))
)
regex_result = ImengyuConvention.cRegexPR.match(name)
2023-12-06 17:16:31 +08:00
if regex_result is not None:
return BallanceObjectInfo.create_from_resetpoint(
int(regex_result.group(1))
)
# check other unique elements
if name == "PS_LevelStart":
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.LEVEL_START)
if name == "PE_LevelEnd":
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.LEVEL_END)
# process floors
if name.startswith("S_Floors"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.FLOOR)
if name.startswith("S_FloorRails"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.RAIL)
if name.startswith("S_FloorWoods"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.WOOD)
if name.startswith("S_FloorStopper"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.STOPPER)
# process others
if name.startswith("DepthTestCubes"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.DEPTH_CUBE)
if name.startswith("O_"):
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.DECORATION)
if name == 'SkyLayer':
2023-12-06 17:16:31 +08:00
return BallanceObjectInfo.create_from_others(BallanceObjectType.SKYLAYER)
if reporter is not None:
reporter.add_error("Name match lost.")
2023-11-29 21:35:15 +08:00
return None
2023-11-26 12:57:49 +08:00
@staticmethod
def parse_from_object(obj: bpy.types.Object, reporter: RenameErrorReporter | None) -> BallanceObjectInfo | None:
return ImengyuConvention.parse_from_name(obj.name, reporter)
@staticmethod
def set_to_name(info: BallanceObjectInfo, oldname: str | None, reporter: RenameErrorReporter | None) -> str | None:
2023-12-06 17:16:31 +08:00
match(info.mBasicType):
case BallanceObjectType.DECORATION:
return 'O_'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.SKYLAYER:
return 'SkyLayer'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.LEVEL_START:
return 'PS_LevelStart'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.LEVEL_END:
return 'PE_LevelEnd'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.CHECKPOINT:
return f'PR_ResetPoint:{info.mSector:d}'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.RESETPOINT:
return f'PC_CheckPoint:{info.mSector:d}'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.DEPTH_CUBE:
return 'DepthTestCubes'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.FLOOR:
return 'S_Floors'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.RAIL:
return 'S_FloorWoods'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.WOOD:
return 'S_FloorRails'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.STOPPER:
return 'S_FloorStopper'
2023-12-06 17:16:31 +08:00
case BallanceObjectType.COMPONENT:
return '{}:{}:{:d}'.format(
info.mComponentType,
oldname.replace(':', '_') if oldname is not None else '',
info.mSector
)
2023-12-06 17:16:31 +08:00
case _:
if reporter is not None:
reporter.add_error('No matched info.')
return None
2023-12-06 17:16:31 +08:00
2023-11-26 12:57:49 +08:00
@staticmethod
def set_to_object(obj: bpy.types.Object, info: BallanceObjectInfo, reporter: RenameErrorReporter | None) -> bool:
expect_name: str | None = ImengyuConvention.set_to_name(info, obj.name, reporter)
if expect_name is None: return False
2023-11-26 12:57:49 +08:00
obj.name = expect_name
return True
2023-11-26 20:37:19 +08:00
2023-11-26 12:57:49 +08:00
#endregion