mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-03 11:18:26 +02:00
started making a AbstractTrack class to implement more type of "track".
Removed get_suffix and get_prefix to replace them with get_tag_template and tags_template in mod_config.json
This commit is contained in:
parent
7d15d98999
commit
99287bbd56
9 changed files with 234 additions and 194 deletions
|
@ -33,62 +33,76 @@
|
||||||
},
|
},
|
||||||
"lpar_template": "{{ mode if (mode := ## SETTINGS_MODE ##) is not None else 'normal' }}.lpar",
|
"lpar_template": "{{ mode if (mode := ## SETTINGS_MODE ##) is not None else 'normal' }}.lpar",
|
||||||
|
|
||||||
"tags_prefix": {
|
"tags_templates": {
|
||||||
"MSRDS": "{{ bmg_color_text('green', tag) }}",
|
"prefix": {
|
||||||
"CTR": "{{ bmg_color_text('orange', tag) }}",
|
"MSRDS": "{{ bmg_color_text('green', tag) }}",
|
||||||
"CTTR": "{{ bmg_color_text('dark orange', tag) }}",
|
"CTR": "{{ bmg_color_text('orange', tag) }}",
|
||||||
"CNR": "{{ bmg_color_text('orange', tag) }}",
|
"CTTR": "{{ bmg_color_text('dark orange', tag) }}",
|
||||||
"DKR": "{{ bmg_color_text('dark red', tag) }}",
|
"CNR": "{{ bmg_color_text('orange', tag) }}",
|
||||||
"LCP": "{{ bmg_color_text('green', tag) }}",
|
"DKR": "{{ bmg_color_text('dark red', tag) }}",
|
||||||
"LEGO-R": "{{ bmg_color_text('light red', tag) }}",
|
"LCP": "{{ bmg_color_text('green', tag) }}",
|
||||||
"MP9": "{{ bmg_color_text('neon yellow', tag) }}",
|
"LEGO-R": "{{ bmg_color_text('light red', tag) }}",
|
||||||
"MSUSA": "{{ bmg_color_text('green', tag) }}",
|
"MP9": "{{ bmg_color_text('neon yellow', tag) }}",
|
||||||
"FZMV": "{{ bmg_color_text('yellow', tag) }}",
|
"MSUSA": "{{ bmg_color_text('green', tag) }}",
|
||||||
"KAR": "{{ bmg_color_text('green', tag) }}",
|
"FZMV": "{{ bmg_color_text('yellow', tag) }}",
|
||||||
"KO": "{{ bmg_color_text('dark orange', tag) }}",
|
"KAR": "{{ bmg_color_text('green', tag) }}",
|
||||||
"FZ": "{{ bmg_color_text('yellow', tag) }}",
|
"KO": "{{ bmg_color_text('dark orange', tag) }}",
|
||||||
"RV": "{{ bmg_color_text('white', tag) }}",
|
"FZ": "{{ bmg_color_text('yellow', tag) }}",
|
||||||
"SADX": "{{ bmg_color_text('dark blue', tag) }}",
|
"RV": "{{ bmg_color_text('white', tag) }}",
|
||||||
"SCR": "{{ bmg_color_text('yellow', tag) }}",
|
"SADX": "{{ bmg_color_text('dark blue', tag) }}",
|
||||||
"SH": "{{ bmg_color_text('pink', tag) }}",
|
"SCR": "{{ bmg_color_text('yellow', tag) }}",
|
||||||
"SM64": "{{ bmg_color_text('pink', tag) }}",
|
"SH": "{{ bmg_color_text('pink', tag) }}",
|
||||||
"SMB1": "{{ bmg_color_text('light red', tag) }}",
|
"SM64": "{{ bmg_color_text('pink', tag) }}",
|
||||||
"SMB2": "{{ bmg_color_text('red', tag) }}",
|
"SMB1": "{{ bmg_color_text('light red', tag) }}",
|
||||||
"SSBB": "{{ bmg_color_text('vivid red', tag) }}",
|
"SMB2": "{{ bmg_color_text('red', tag) }}",
|
||||||
"SMS": "{{ bmg_color_text('dark red', tag) }}",
|
"SSBB": "{{ bmg_color_text('vivid red', tag) }}",
|
||||||
"SMO": "{{ bmg_color_text('apple red', tag) }}",
|
"SMS": "{{ bmg_color_text('dark red', tag) }}",
|
||||||
"VVVVVV": "{{ bmg_color_text('azure', tag) }}",
|
"SMO": "{{ bmg_color_text('apple red', tag) }}",
|
||||||
"WF": "{{ bmg_color_text('green', tag) }}",
|
"VVVVVV": "{{ bmg_color_text('azure', tag) }}",
|
||||||
"WP": "{{ bmg_color_text('neon yellow 2', tag) }}",
|
"WF": "{{ bmg_color_text('green', tag) }}",
|
||||||
"Zelda OoT": "{{ bmg_color_text('green', tag) }}",
|
"WP": "{{ bmg_color_text('neon yellow 2', tag) }}",
|
||||||
"Zelda TP": "{{ bmg_color_text('green', tag) }}",
|
"Zelda OoT": "{{ bmg_color_text('green', tag) }}",
|
||||||
"Zelda WW": "{{ bmg_color_text('green', tag) }}",
|
"Zelda TP": "{{ bmg_color_text('green', tag) }}",
|
||||||
"PMWR": "{{ bmg_color_text('neon yellow 2', tag) }}",
|
"Zelda WW": "{{ bmg_color_text('green', tag) }}",
|
||||||
"SHR": "{{ bmg_color_text('green', tag) }}",
|
"PMWR": "{{ bmg_color_text('neon yellow 2', tag) }}",
|
||||||
"SK64": "{{ bmg_color_text('green', tag) }}",
|
"SHR": "{{ bmg_color_text('green', tag) }}",
|
||||||
"SMG": "{{ bmg_color_text('light red', tag) }}",
|
"SK64": "{{ bmg_color_text('green', tag) }}",
|
||||||
"Spyro 1": "{{ bmg_color_text('azure', tag) }}",
|
"SMG": "{{ bmg_color_text('light red', tag) }}",
|
||||||
"Switch": "{{ bmg_color_text('vivid red', tag) }}",
|
"Spyro 1": "{{ bmg_color_text('azure', tag) }}",
|
||||||
"Wii": "{{ bmg_color_text('azure', tag) }}",
|
"Switch": "{{ bmg_color_text('vivid red', tag) }}",
|
||||||
"3DS": "{{ bmg_color_text('light orange', tag) }}",
|
"Wii": "{{ bmg_color_text('azure', tag) }}",
|
||||||
"DS": "{{ bmg_color_text('white', tag) }}",
|
"3DS": "{{ bmg_color_text('light orange', tag) }}",
|
||||||
"GCN": "{{ bmg_color_text('azure', tag) }}",
|
"DS": "{{ bmg_color_text('white', tag) }}",
|
||||||
"GBA": "{{ bmg_color_text('dark blue', tag) }}",
|
"GCN": "{{ bmg_color_text('azure', tag) }}",
|
||||||
"N64": "{{ bmg_color_text('pink', tag) }}",
|
"GBA": "{{ bmg_color_text('dark blue', tag) }}",
|
||||||
"SNES": "{{ bmg_color_text('green', tag) }}",
|
"N64": "{{ bmg_color_text('pink', tag) }}",
|
||||||
"RMX": "{{ bmg_color_text('orange', tag) }}",
|
"SNES": "{{ bmg_color_text('green', tag) }}",
|
||||||
"MKT": "{{ bmg_color_text('dark orange', tag) }}",
|
"RMX": "{{ bmg_color_text('orange', tag) }}",
|
||||||
"GP": "{{ bmg_color_text('dark red', tag) }}",
|
"MKT": "{{ bmg_color_text('dark orange', tag) }}",
|
||||||
"UT": "{{ bmg_color_text('red', tag) }}",
|
"GP": "{{ bmg_color_text('dark red', tag) }}",
|
||||||
"GK2": "{{ bmg_color_text('green', tag) }}",
|
"UT": "{{ bmg_color_text('red', tag) }}",
|
||||||
"GK3": "{{ bmg_color_text('green', tag) }}",
|
"GK2": "{{ bmg_color_text('green', tag) }}",
|
||||||
"GK7": "{{ bmg_color_text('green', tag) }}",
|
"GK3": "{{ bmg_color_text('green', tag) }}",
|
||||||
"FGKR": "{{ bmg_color_text('dark orange', tag) }}"
|
"GK7": "{{ bmg_color_text('green', tag) }}",
|
||||||
|
"FGKR": "{{ bmg_color_text('dark orange', tag) }}"
|
||||||
|
},
|
||||||
|
"suffix": {
|
||||||
|
"Boost": "{{ bmg_color_text('orange', tag) }}"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"tags_suffix": {
|
"tags_cups": [
|
||||||
"Boost": "{{ bmg_color_text('orange', tag) }}"
|
"Switch",
|
||||||
},
|
"3DS",
|
||||||
"tags_cups": ["Switch", "3DS", "DS", "GCN", "GBA", "N64", "SNES", "MKT", "RMX", "DX", "GP"],
|
"DS",
|
||||||
|
"GCN",
|
||||||
|
"GBA",
|
||||||
|
"N64",
|
||||||
|
"SNES",
|
||||||
|
"MKT",
|
||||||
|
"RMX",
|
||||||
|
"DX",
|
||||||
|
"GP"
|
||||||
|
],
|
||||||
|
|
||||||
"track_file_template": "{{ getattr(track, 'sha1', '_') }}",
|
"track_file_template": "{{ getattr(track, 'sha1', '_') }}",
|
||||||
"multiplayer_disable_if": "getattr(track, 'warning', 0) >= 1",
|
"multiplayer_disable_if": "getattr(track, 'warning', 0) >= 1",
|
||||||
|
|
|
@ -9,7 +9,7 @@ from source.mkw import Tag
|
||||||
from source.mkw.Cup import Cup
|
from source.mkw.Cup import Cup
|
||||||
from source.mkw.MKWColor import bmg_color_text, bmg_color_raw
|
from source.mkw.MKWColor import bmg_color_text, bmg_color_raw
|
||||||
from source.mkw.ModSettings import AbstractModSettings
|
from source.mkw.ModSettings import AbstractModSettings
|
||||||
from source.mkw.Track import Track
|
from source.mkw.Track.CustomTrack import CustomTrack
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from source.mkw.OriginalTrack import OriginalTrack
|
from source.mkw.OriginalTrack import OriginalTrack
|
||||||
|
@ -68,20 +68,20 @@ class ModConfig:
|
||||||
Representation of a mod
|
Representation of a mod
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("name", "path", "nickname", "variant", "tags_prefix", "tags_suffix",
|
__slots__ = ("name", "path", "nickname", "variant", "default_track", "_tracks", "version",
|
||||||
"default_track", "_tracks", "version", "original_track_prefix", "swap_original_order",
|
"original_track_prefix", "swap_original_order", "keep_original_track",
|
||||||
"keep_original_track", "enable_random_cup", "tags_cups", "track_file_template",
|
"enable_random_cup", "tags_cups", "track_file_template",
|
||||||
"multiplayer_disable_if", "macros", "messages", "global_settings",
|
"multiplayer_disable_if", "macros", "messages", "global_settings",
|
||||||
"specific_settings", "lpar_template")
|
"specific_settings", "lpar_template", "tags_template")
|
||||||
|
|
||||||
def __init__(self, path: Path | str, name: str, nickname: str = None, version: str = None, variant: str = None,
|
def __init__(self, path: Path | str, name: str, nickname: str = None, version: str = None, variant: str = None,
|
||||||
tags_prefix: dict[Tag, str] = None, tags_suffix: dict[Tag, str] = None,
|
|
||||||
tags_cups: list[Tag] = None, default_track: "Track | TrackGroup" = None,
|
tags_cups: list[Tag] = None, default_track: "Track | TrackGroup" = None,
|
||||||
tracks: list["Track | TrackGroup"] = None, original_track_prefix: bool = None,
|
tracks: list["Track | TrackGroup"] = None, original_track_prefix: bool = None,
|
||||||
swap_original_order: bool = None, keep_original_track: bool = None, enable_random_cup: bool = None,
|
swap_original_order: bool = None, keep_original_track: bool = None, enable_random_cup: bool = None,
|
||||||
track_file_template: str = None, multiplayer_disable_if: str = None, macros: dict[str, str] = None,
|
track_file_template: str = None, multiplayer_disable_if: str = None, macros: dict[str, str] = None,
|
||||||
messages: dict[str, dict[str, str]] = None, global_settings: dict[str, dict[str, str]] = None,
|
messages: dict[str, dict[str, str]] = None, global_settings: dict[str, dict[str, str]] = None,
|
||||||
specific_settings: dict[str, dict[str, str]] = None, lpar_template: str = None):
|
specific_settings: dict[str, dict[str, str]] = None, lpar_template: str = None,
|
||||||
|
tags_template: dict[str, str] = None):
|
||||||
|
|
||||||
self.path = Path(path)
|
self.path = Path(path)
|
||||||
self.macros: dict = macros if macros is not None else {}
|
self.macros: dict = macros if macros is not None else {}
|
||||||
|
@ -100,8 +100,7 @@ class ModConfig:
|
||||||
self.version: str = version if version is not None else "v1.0.0"
|
self.version: str = version if version is not None else "v1.0.0"
|
||||||
self.variant: str = variant if variant is not None else "01"
|
self.variant: str = variant if variant is not None else "01"
|
||||||
|
|
||||||
self.tags_prefix: dict[Tag] = tags_prefix if tags_prefix is not None else {}
|
self.tags_template: dict[str, str] = tags_template if tags_template is not None else {}
|
||||||
self.tags_suffix: dict[Tag] = tags_suffix if tags_suffix is not None else {}
|
|
||||||
self.tags_cups: list[Tag] = tags_cups if tags_cups is not None else []
|
self.tags_cups: list[Tag] = tags_cups if tags_cups is not None else []
|
||||||
|
|
||||||
self.default_track: "Track | TrackGroup" = default_track if default_track is not None else None
|
self.default_track: "Track | TrackGroup" = default_track if default_track is not None else None
|
||||||
|
@ -145,8 +144,8 @@ class ModConfig:
|
||||||
|
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
|
||||||
default_track=Track.from_dict(config_dict.get("default_track", {})),
|
default_track=CustomTrack.from_dict(config_dict.get("default_track", {})),
|
||||||
tracks=[Track.from_dict(track) for track in config_dict.get("tracks", [])],
|
tracks=[CustomTrack.from_dict(track) for track in config_dict.get("tracks", [])],
|
||||||
macros=macros,
|
macros=macros,
|
||||||
messages=messages,
|
messages=messages,
|
||||||
)
|
)
|
||||||
|
@ -204,7 +203,7 @@ class ModConfig:
|
||||||
"""
|
"""
|
||||||
return self.path.parent
|
return self.path.parent
|
||||||
|
|
||||||
def get_all_tracks(self, *args, **kwargs) -> Generator["Track", None, None]:
|
def get_all_tracks(self, *args, **kwargs) -> Generator["CustomTrack", None, None]:
|
||||||
"""
|
"""
|
||||||
Same as get_tracks, but track group are divided into subtracks
|
Same as get_tracks, but track group are divided into subtracks
|
||||||
"""
|
"""
|
||||||
|
@ -425,7 +424,7 @@ class ModConfig:
|
||||||
)
|
)
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
def normalize_track(track: Track, track_file: Path):
|
def normalize_track(track: CustomTrack, track_file: Path):
|
||||||
SZSPath(track_file).normalize(
|
SZSPath(track_file).normalize(
|
||||||
autoadd_path,
|
autoadd_path,
|
||||||
destination_path / f"{track_file.stem}.szs",
|
destination_path / f"{track_file.stem}.szs",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from source.mkw.Patch.PatchOperation.BmgTxtEditor import AbstractLayer
|
from source.mkw.Patch.PatchOperation.BmgTxtEditor import AbstractLayer
|
||||||
from source.mkw.Track import Track
|
from source.mkw.Track.CustomTrack import CustomTrack
|
||||||
from source.wt import bmg
|
from source.wt import bmg
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class FormatOriginalTrackLayer(AbstractLayer):
|
||||||
break
|
break
|
||||||
else: tag = "Wii"
|
else: tag = "Wii"
|
||||||
|
|
||||||
patched_name = Track(
|
patched_name = CustomTrack(
|
||||||
name=name,
|
name=name,
|
||||||
tags=[tag]
|
tags=[tag]
|
||||||
).repr_format(
|
).repr_format(
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
from typing import Generator
|
|
||||||
|
|
||||||
from source.mkw import Tag, Slot
|
|
||||||
|
|
||||||
ModConfig: any
|
|
||||||
|
|
||||||
|
|
||||||
# representation of a custom track
|
|
||||||
class Track:
|
|
||||||
def __init__(self, special: Slot = None, music: Slot = None, tags: list[Tag] = None, weight: int = None, **kwargs):
|
|
||||||
self.special: Slot = special if special is not None else "T11"
|
|
||||||
self.music: Slot = music if music is not None else "T11"
|
|
||||||
self.tags: list[Tag] = tags if tags is not None else []
|
|
||||||
self.weight: int = weight if weight is not None else 1
|
|
||||||
|
|
||||||
# others not mandatory attributes
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
# if the attribute start with __, this is a magic attribute, and it should not be modified
|
|
||||||
if key.startswith("__"): continue
|
|
||||||
setattr(self, key, value)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"<Track name={getattr(self, 'name', '/')} tags={getattr(self, 'tags', '/')}>"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, track_dict: dict) -> "Track | TrackGroup":
|
|
||||||
"""
|
|
||||||
create a track from a dict, or create a track group is it is a group
|
|
||||||
:param track_dict: dict containing the track information
|
|
||||||
:return: Track
|
|
||||||
"""
|
|
||||||
if "group" in track_dict:
|
|
||||||
from source.mkw.TrackGroup import TrackGroup
|
|
||||||
return TrackGroup.from_dict(track_dict)
|
|
||||||
return cls(**track_dict)
|
|
||||||
|
|
||||||
def get_tracks(self) -> Generator["Track", None, None]:
|
|
||||||
"""
|
|
||||||
Get all the track elements
|
|
||||||
:return: track elements
|
|
||||||
"""
|
|
||||||
for _ in range(self.weight):
|
|
||||||
yield self
|
|
||||||
|
|
||||||
def repr_format(self, mod_config: "ModConfig", template: str) -> str:
|
|
||||||
"""
|
|
||||||
return the representation of the track from the format
|
|
||||||
:param template: template for the way the text will be represented
|
|
||||||
:param mod_config: configuration of the mod
|
|
||||||
:return: formatted representation of the track
|
|
||||||
"""
|
|
||||||
|
|
||||||
return mod_config.multiple_safe_eval(
|
|
||||||
template,
|
|
||||||
env={
|
|
||||||
"track": self,
|
|
||||||
"prefix": self.get_prefix(mod_config, ""),
|
|
||||||
"suffix": self.get_suffix(mod_config, "")
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_tag_template(self, mod_config: "ModConfig", templates: dict[str, str], default: any = None) -> any:
|
|
||||||
"""
|
|
||||||
Return the tag template found in templates. If not found, return default
|
|
||||||
:param mod_config: mod configuration
|
|
||||||
:param templates: template with all the tags and its replacement
|
|
||||||
:param default: default value if no tag template is found
|
|
||||||
:return: formatted representation of the tag
|
|
||||||
"""
|
|
||||||
for tag in filter(lambda tag: tag in templates, self.tags):
|
|
||||||
template: str = templates[tag]
|
|
||||||
return mod_config.multiple_safe_eval(template, env={"tag": tag})
|
|
||||||
return default
|
|
||||||
|
|
||||||
def get_prefix(self, mod_config: "ModConfig", default: any = None) -> any:
|
|
||||||
"""
|
|
||||||
return the prefix of the track
|
|
||||||
:param default: default value if no prefix is found
|
|
||||||
:param mod_config: mod configuration
|
|
||||||
:return: formatted representation of the track prefix
|
|
||||||
"""
|
|
||||||
return self.get_tag_template(mod_config, mod_config.tags_prefix, default)
|
|
||||||
|
|
||||||
def get_suffix(self, mod_config: "ModConfig", default: any = None) -> any:
|
|
||||||
"""
|
|
||||||
return the suffix of the track
|
|
||||||
:param default: default value if no suffix is found
|
|
||||||
:param mod_config: mod configuration
|
|
||||||
:return: formatted representation of the track suffix
|
|
||||||
"""
|
|
||||||
return self.get_tag_template(mod_config, mod_config.tags_suffix, default)
|
|
||||||
|
|
||||||
def is_new(self, mod_config: "ModConfig") -> bool:
|
|
||||||
"""
|
|
||||||
Return if the track should be considered as new for random selection
|
|
||||||
:param mod_config: mod configuration
|
|
||||||
:return: is the track new
|
|
||||||
"""
|
|
||||||
|
|
||||||
return mod_config.safe_eval(
|
|
||||||
mod_config.global_settings["replace_random_new"].value,
|
|
||||||
env={"track": self}
|
|
||||||
) is True
|
|
||||||
|
|
||||||
def get_ctfile(self, mod_config: "ModConfig", template: str, hidden: bool = False) -> str:
|
|
||||||
"""
|
|
||||||
return the ctfile of the track
|
|
||||||
:hidden: if the track is in a group
|
|
||||||
:template: format of the track's name
|
|
||||||
:return: ctfile
|
|
||||||
"""
|
|
||||||
name = repr(self.repr_format(mod_config=mod_config, template=template))
|
|
||||||
file_name = repr(self.repr_format(mod_config=mod_config, template=mod_config.track_file_template))
|
|
||||||
|
|
||||||
return (
|
|
||||||
f'{"H" if hidden else "T"} {self.music}; ' # track type
|
|
||||||
f'{self.special}; {(0x04 if hidden else 0) | (0x01 if self.is_new(mod_config) else 0):#04x}; ' # lecode flags
|
|
||||||
f'{file_name}; ' # filename
|
|
||||||
f'{name}; ' # name of the track in the menu
|
|
||||||
f'{file_name}\n' # unique identifier for each track
|
|
||||||
)
|
|
103
source/mkw/Track/AbstractTrack.py
Normal file
103
source/mkw/Track/AbstractTrack.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from typing import Generator
|
||||||
|
|
||||||
|
from source.mkw import Slot, Tag, ModConfig
|
||||||
|
|
||||||
|
|
||||||
|
class TrackForbiddenCustomAttribute(Exception):
|
||||||
|
def __init__(self, attribute_name: str):
|
||||||
|
super().__init__(f"Forbidden track attribute : {attribute_name!r}")
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractTrack(ABC):
|
||||||
|
music: Slot
|
||||||
|
special: Slot
|
||||||
|
tags: list[Tag]
|
||||||
|
weight: int
|
||||||
|
|
||||||
|
def __init__(self, music: Slot = "T11", special: Slot = "T11", tags: list[Tag] = None, weight: int = 1, **kwargs):
|
||||||
|
self.music = music
|
||||||
|
self.special = special
|
||||||
|
self.tags = tags if tags is not None else []
|
||||||
|
self.weight = weight
|
||||||
|
|
||||||
|
# others not mandatory attributes
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
# if the attribute start with __, this is a magic attribute, and it should not be modified
|
||||||
|
if "__" in key or hasattr(self, key): raise TrackForbiddenCustomAttribute(key)
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__} {id(self)}>"
|
||||||
|
|
||||||
|
def get_tracks(self) -> Generator["AbstractTrack", None, None]:
|
||||||
|
"""
|
||||||
|
Return all the track itself or the subtracks if available
|
||||||
|
:return: all the track itself or the subtracks if available
|
||||||
|
"""
|
||||||
|
for _ in range(self.weight):
|
||||||
|
yield self
|
||||||
|
|
||||||
|
def get_tag_template(self, mod_config: "ModConfig", template_name: str, default: any = None) -> any:
|
||||||
|
"""
|
||||||
|
Return the tag template found in templates. If not found, return default
|
||||||
|
:param mod_config: mod configuration
|
||||||
|
:param template_name: name of the template of the tags
|
||||||
|
:param default: default value if no tag template is found
|
||||||
|
:return: formatted representation of the tag
|
||||||
|
"""
|
||||||
|
for tag in filter(lambda tag: tag in mod_config.tags_template[template_name], self.tags):
|
||||||
|
return mod_config.multiple_safe_eval(mod_config.tags_template[template_name][tag], env={"tag": tag})
|
||||||
|
return default
|
||||||
|
|
||||||
|
def repr_format(self, mod_config: "ModConfig", template: str) -> str:
|
||||||
|
"""
|
||||||
|
return the representation of the track from the format
|
||||||
|
:param template: template for the way the text will be represented
|
||||||
|
:param mod_config: configuration of the mod
|
||||||
|
:return: formatted representation of the track
|
||||||
|
"""
|
||||||
|
return mod_config.multiple_safe_eval(template, env={"track": self, "get_tag_template": self.get_tag_template})
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_filename(self, mod_config: "ModConfig") -> str:
|
||||||
|
"""
|
||||||
|
Return the filename of the track
|
||||||
|
:param mod_config: the mod_config object
|
||||||
|
:return: the filename of the track
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def is_new(self, mod_config: "ModConfig") -> bool:
|
||||||
|
"""
|
||||||
|
Return if the track should be considered as new for random selection
|
||||||
|
:param mod_config: mod configuration
|
||||||
|
:return: is the track new
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def get_ctfile(self, mod_config: "ModConfig", template: str, hidden: bool = False) -> str:
|
||||||
|
"""
|
||||||
|
return the ctfile of the track
|
||||||
|
:hidden: if the track is in a group
|
||||||
|
:template: format of the track's name
|
||||||
|
:return: ctfile
|
||||||
|
"""
|
||||||
|
category: str = "H" if hidden else "T"
|
||||||
|
name: str = self.repr_format(mod_config=mod_config, template=template)
|
||||||
|
filename: str = self.get_filename(mod_config=mod_config)
|
||||||
|
flags: int = (
|
||||||
|
(0x04 if hidden else 0) |
|
||||||
|
(0x01 if self.is_new(mod_config) else 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
f'{category} ' # category (is the track hidden, visible, an arena, ...)
|
||||||
|
f'{self.music}; ' # music
|
||||||
|
f'{self.special}; ' # property of the tracks
|
||||||
|
f'{flags:#04x}; ' # lecode flags
|
||||||
|
f'{filename!r}; ' # filename
|
||||||
|
f'{name!r}; ' # name of the track in the menu
|
||||||
|
f'{filename!r}\n' # unique identifier for each track
|
||||||
|
)
|
35
source/mkw/Track/CustomTrack.py
Normal file
35
source/mkw/Track/CustomTrack.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
from source.mkw.Track.AbstractTrack import AbstractTrack
|
||||||
|
|
||||||
|
ModConfig: any
|
||||||
|
|
||||||
|
|
||||||
|
class CustomTrack(AbstractTrack):
|
||||||
|
"""
|
||||||
|
Represent a custom track
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__} name={getattr(self, 'name', '/')} tags={getattr(self, 'tags', '/')}>"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, track_dict: dict) -> "Track | TrackGroup":
|
||||||
|
"""
|
||||||
|
create a track from a dict, or create a track group is it is a group
|
||||||
|
:param track_dict: dict containing the track information
|
||||||
|
:return: Track
|
||||||
|
"""
|
||||||
|
if "group" in track_dict:
|
||||||
|
from source.mkw.TrackGroup import TrackGroup
|
||||||
|
return TrackGroup.from_dict(track_dict)
|
||||||
|
return cls(**track_dict)
|
||||||
|
|
||||||
|
def get_filename(self, mod_config: "ModConfig") -> str:
|
||||||
|
return self.repr_format(mod_config=mod_config, template=mod_config.track_file_template)
|
||||||
|
|
||||||
|
def is_new(self, mod_config: "ModConfig") -> bool:
|
||||||
|
"""
|
||||||
|
Return if the track should be considered as new for random selection
|
||||||
|
:param mod_config: mod configuration
|
||||||
|
:return: is the track new
|
||||||
|
"""
|
||||||
|
return mod_config.safe_eval(mod_config.global_settings["replace_random_new"].value, env={"track": self}) is True
|
9
source/mkw/Track/DefaultTrack.py
Normal file
9
source/mkw/Track/DefaultTrack.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from source.mkw.Track.AbstractTrack import AbstractTrack
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultTrack(AbstractTrack):
|
||||||
|
def get_filename(self, mod_config: "ModConfig") -> str:
|
||||||
|
return "beginner_course"
|
||||||
|
|
||||||
|
def is_new(self, mod_config: "ModConfig") -> bool:
|
||||||
|
return False
|
1
source/mkw/Track/__init__.py
Normal file
1
source/mkw/Track/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
from source.mkw.Track import CustomTrack, DefaultTrack, AbstractTrack
|
|
@ -28,11 +28,11 @@ class TrackGroup:
|
||||||
:param group_dict: dict containing the track information
|
:param group_dict: dict containing the track information
|
||||||
:return: TrackGroup or Track
|
:return: TrackGroup or Track
|
||||||
"""
|
"""
|
||||||
from source.mkw.Track import Track
|
from source.mkw.Track.CustomTrack import CustomTrack
|
||||||
|
|
||||||
if "group" not in group_dict: return Track.from_dict(group_dict)
|
if "group" not in group_dict: return CustomTrack.from_dict(group_dict)
|
||||||
return cls(
|
return cls(
|
||||||
tracks=[Track.from_dict(track) for track in group_dict["group"]],
|
tracks=[CustomTrack.from_dict(track) for track in group_dict["group"]],
|
||||||
tags=group_dict.get("tags"),
|
tags=group_dict.get("tags"),
|
||||||
name=group_dict.get("name"),
|
name=group_dict.get("name"),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue