def gather_dcsc_properties(species_cls: ExportTableItem, *, alt=False, report=False) -> DinoCharacterStatusComponent: ''' Gather combined DCSC properties from a species, respecting CharacterStatusComponentPriority. ''' assert species_cls.asset and species_cls.asset.loader if not inherits_from(species_cls, PDC_CLS): raise ValueError("Supplied export should be a species character class") loader: AssetLoader = species_cls.asset.loader dcscs: List[Tuple[float, ExportTableItem]] = list() proxy: DinoCharacterStatusComponent = get_proxy_for_type(DCSC_CLS, loader) with ue_parsing_context(properties=True): # Gather DCSCs as we traverse from UObject back towards this species class for cls_name in find_parent_classes(species_cls, include_self=True): if not cls_name.startswith('/Game'): continue asset: UAsset = loader[cls_name] for dcsc_export in _get_dcscs_for_species(asset): # Calculate the priority of this DCSC pri_prop = get_property(dcsc_export, "CharacterStatusComponentPriority") if pri_prop is None: dcsc_cls = loader.load_related( dcsc_export.klass.value).default_export pri_prop = get_property( dcsc_cls, "CharacterStatusComponentPriority") pri = 0 if pri_prop is None else float(pri_prop) if report: print( f'DCSC from {asset.assetname} = {dcsc_export.fullname} (pri {pri_prop} = {pri})' ) dcscs.append((pri, dcsc_export)) # Order the DCSCs by CharacterStatusComponentPriority value, descending # Python's sort is stable, so it will maintain the gathered order of exports with identical priorities (e.g. Deinonychus) dcscs.sort(key=lambda p: p[0]) # Collect properties from each DCSC in order props: Dict[str, Dict[int, UEBase]] = defaultdict( lambda: defaultdict(lambda: None)) # type: ignore if dcscs: extract_properties_from_export(dcscs[-1][1], props, skip_top=alt, recurse=True, report=False) proxy.update(props) return proxy
def gather_properties_internal(asset: UAsset, props: PriorityPropDict, dcscs: List[Tuple[int, ExportTableItem]], dcsc, report=False, depth=0): assert asset and asset.loader if report: indent = '| ' * depth print(indent + asset.name) parent = ark.tree.get_parent_of_export(asset.default_class) if parent and parent.asset.assetname != asset.assetname and not ark.tree.export_inherits_from( parent, dcsc): # Recurse upwards before collecting properties on the way back down parentpkg = parent.asset gather_properties_internal(parentpkg, props, dcscs, dcsc, report=report, depth=depth + 1) if report: print( f'{indent}gathering props from {asset.default_export and asset.default_export.fullname}' ) extract_properties_from_export(asset.default_export, props) # Gather properties from sub-components for subcomponent in ark.asset.findSubComponentExports(asset): if report: print(f'{indent}| subcomponent: {subcomponent.fullname}') if ark.tree.export_inherits_from(subcomponent, dcsc): pri = clean_value( get_property(subcomponent, "CharacterStatusComponentPriority")) if pri is None: dcsc_cls = asset.loader.load_related( subcomponent.klass.value).default_export pri = clean_value( get_property(dcsc_cls, "CharacterStatusComponentPriority")) if report: print(f'{indent}| (postponing dcsc: priority={pri})') pri = pri or 0 dcscs.append((pri, subcomponent)) else: if report: print(f'{indent}| (gather properties)') extract_properties_from_export(subcomponent, props) return props