implemented Arena (game text are missing)

This commit is contained in:
Faraphel 2022-08-13 12:16:37 +02:00
parent 8eda2b4f3d
commit a51d6f2173
11 changed files with 129 additions and 41 deletions

View file

@ -49,7 +49,7 @@ class Window(AbstractPreviewWindow):
self.text_track_format.delete(1.0, tkinter.END) self.text_track_format.delete(1.0, tkinter.END)
# insert all the tracks representation # insert all the tracks representation
for track in self.mod_config.get_all_tracks(ignore_filter=True): for track in self.mod_config.get_all_arenas_tracks(ignore_filter=True):
try: try:
track_repr = track.repr_format( track_repr = track.repr_format(
self.mod_config, self.entry_template_input.get() self.mod_config, self.entry_template_input.get()

View file

@ -65,7 +65,7 @@ class Window(AbstractPreviewWindow):
self.text_track_format.delete(1.0, tkinter.END) self.text_track_format.delete(1.0, tkinter.END)
# insert all the tracks representation # insert all the tracks representation
for track in self.mod_config.get_all_tracks(ignore_filter=True): for track in self.mod_config.get_all_arenas_tracks(ignore_filter=True):
self.text_track_format.insert(tkinter.END, f"{track}\n") self.text_track_format.insert(tkinter.END, f"{track}\n")
self.text_track_format.configure(state=tkinter.DISABLED) self.text_track_format.configure(state=tkinter.DISABLED)
@ -83,7 +83,7 @@ class Window(AbstractPreviewWindow):
return_lambda=True, lambda_args=["track"] return_lambda=True, lambda_args=["track"]
) )
for track in self.mod_config.get_all_tracks(ignore_filter=True): for track in self.mod_config.get_all_arenas_tracks(ignore_filter=True):
value: bool = template_func(track) is True value: bool = template_func(track) is True
self.text_track_select.insert(tkinter.END, f"{value}\n") self.text_track_select.insert(tkinter.END, f"{value}\n")

View file

@ -49,7 +49,7 @@ class Window(AbstractPreviewWindow):
template = self.entry_template_input.get() template = self.entry_template_input.get()
# insert all the tracks representation # insert all the tracks representation
for track in self.mod_config.get_all_tracks( for track in self.mod_config.get_all_arenas_tracks(
ignore_filter=True, ignore_filter=True,
sorting_template=template if template else None sorting_template=template if template else None
): ):

View file

View file

@ -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 CustomTrack, DefaultTrack from source.mkw.Track import CustomTrack, DefaultTrack, Arena
import json import json
from source.mkw.OriginalTrack import OriginalTrack from source.mkw.OriginalTrack import OriginalTrack
@ -68,7 +68,7 @@ class ModConfig:
Representation of a mod Representation of a mod
""" """
__slots__ = ("name", "path", "nickname", "variant", "_tracks", "version", __slots__ = ("name", "path", "nickname", "variant", "_tracks", "arenas", "version",
"original_track_prefix", "swap_original_order", "keep_original_track", "original_track_prefix", "swap_original_order", "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",
@ -81,7 +81,7 @@ class ModConfig:
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_templates: dict[str, str] = None): tags_templates: dict[str, str] = None, arenas: list["Arena"] = 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 {}
@ -109,6 +109,8 @@ class ModConfig:
self.multiplayer_disable_if: str = multiplayer_disable_if if multiplayer_disable_if is not None else "False" self.multiplayer_disable_if: str = multiplayer_disable_if if multiplayer_disable_if is not None else "False"
self.lpar_template: str = lpar_template if lpar_template is not None else "normal.lpar" self.lpar_template: str = lpar_template if lpar_template is not None else "normal.lpar"
self.arenas: list["Arena"] = arenas if arenas is not None else []
self.original_track_prefix: bool = original_track_prefix if original_track_prefix is not None else True self.original_track_prefix: bool = original_track_prefix if original_track_prefix is not None else True
self.swap_original_order: bool = swap_original_order if swap_original_order is not None else True self.swap_original_order: bool = swap_original_order if swap_original_order is not None else True
self.keep_original_track: bool = keep_original_track if keep_original_track is not None else True self.keep_original_track: bool = keep_original_track if keep_original_track is not None else True
@ -133,7 +135,7 @@ class ModConfig:
kwargs = { kwargs = {
attr: config_dict.get(attr) attr: config_dict.get(attr)
for attr in cls.__slots__ for attr in cls.__slots__
if attr not in ["name", "_tracks", "tracks", "path", "macros", "messages"] if attr not in ["name", "_tracks", "tracks", "arenas", "path", "macros", "messages"]
# these keys are treated after or are reserved # these keys are treated after or are reserved
} }
@ -144,6 +146,7 @@ class ModConfig:
**kwargs, **kwargs,
tracks=[CustomTrack.from_dict(track) for track in config_dict.get("tracks", [])], tracks=[CustomTrack.from_dict(track) for track in config_dict.get("tracks", [])],
arenas=[Arena.from_dict(arena) for arena in config_dict.get("arenas", [])],
macros=macros, macros=macros,
messages=messages, messages=messages,
) )
@ -173,12 +176,12 @@ class ModConfig:
:return: the modconfig environment :return: the modconfig environment
""" """
return { return {
"mod_config": self, "mod_config": self,
"bmg_color_raw": bmg_color_raw, "bmg_color_raw": bmg_color_raw,
"bmg_color_text": bmg_color_text "bmg_color_text": bmg_color_text
} | ( } | (
base_env if base_env is not None else {} base_env if base_env is not None else {}
) )
def safe_eval(self, *args, env: dict[str, any] = None, **kwargs) -> any: def safe_eval(self, *args, env: dict[str, any] = None, **kwargs) -> any:
""" """
@ -201,6 +204,13 @@ class ModConfig:
""" """
return self.path.parent return self.path.parent
def get_all_arenas_tracks(self, *args, **kwargs) -> Generator["CustomTrack", None, None]:
"""
Same as get_all_tracks, but arenas are included
"""
yield from self.get_all_tracks(*args, **kwargs)
yield from self.arenas
def get_all_tracks(self, *args, **kwargs) -> Generator["CustomTrack", 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
@ -325,6 +335,14 @@ class ModConfig:
# get all the cup ctfile, use "-" for the template since the track's name are not used here # get all the cup ctfile, use "-" for the template since the track's name are not used here
ctfile += cup.get_ctfile(mod_config=self, template=template) ctfile += cup.get_ctfile(mod_config=self, template=template)
ctfile_override_property = "[SETUP-ARENA]\n"
for arena in self.arenas:
arena_definition, arena_override_property = arena.get_ctfile(mod_config=self, template=template)
ctfile += arena_definition
ctfile_override_property += arena_override_property
ctfile += ctfile_override_property
return ctfile return ctfile
def get_base_cticons(self) -> Generator[Image.Image, None, None]: def get_base_cticons(self) -> Generator[Image.Image, None, None]:
@ -416,7 +434,7 @@ class ModConfig:
return_lambda=True, lambda_args=["track"] return_lambda=True, lambda_args=["track"]
) )
for track in self.get_all_tracks(): for track in self.get_all_arenas_tracks():
track_file: Path = next( track_file: Path = next(
track_directory.rglob(f"{track.repr_format(self, self.track_file_template)}.*") track_directory.rglob(f"{track.repr_format(self, self.track_file_template)}.*")
) )

View file

@ -38,18 +38,6 @@ class AbstractTrack(ABC):
for _ in range(self.weight): for _ in range(self.weight):
yield self 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_templates[template_name], self.tags):
return mod_config.multiple_safe_eval(mod_config.tags_templates[template_name][tag], env={"tag": tag})
return default
@abstractmethod @abstractmethod
def repr_format(self, mod_config: "ModConfig", template: str) -> str: def repr_format(self, mod_config: "ModConfig", template: str) -> str:
""" """

60
source/mkw/Track/Arena.py Normal file
View file

@ -0,0 +1,60 @@
from source.mkw import Slot, Tag
from source.mkw.Track.RealArenaTrack import RealArenaTrack
class ArenaForbiddenCustomAttribute(Exception):
def __init__(self, attribute_name: str):
super().__init__(f"Forbidden arena attribute : {attribute_name!r}")
class Arena(RealArenaTrack):
slot: Slot
music: Slot
special: Slot
tags: list[Tag]
def __init__(self, slot: Slot, music: Slot = None, special: Slot = None, tags: list[Tag] = None, **kwargs):
self.slot = slot
self.music = music if music is not None else slot
self.special = special if special is not None else slot
self.tags = tags if tags is not None else []
# 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 ArenaForbiddenCustomAttribute(key)
setattr(self, key, value)
def __repr__(self):
return f"<{self.__class__.__name__} name={getattr(self, 'name', '/')} tags={getattr(self, 'tags', '/')}>"
@classmethod
def from_dict(cls, arena_dict: dict[str, any]) -> "Arena":
return cls(**arena_dict)
def get_ctfile(self, mod_config: "ModConfig", template: str) -> (str, str):
"""
Return the ctfile for the arena and the redefinition of the slot property
:param mod_config: the mod_config object
:param template: the template of the track name
:return: the ctfile for the arena and the redefinition of the slot property
"""
name: str = self.repr_format(mod_config=mod_config, template=template)
filename = self.get_filename(mod_config=mod_config)
return (
(
f'A ' # category (A for arena)
f'{self.music}; ' # music
f'{self.slot}; ' # slot of the arena
f'0x00; ' # lecode flag
f'{filename!r}; ' # filename
f'{name!r}; ' # name of the track in the menu
f'{filename!r}\n' # unique identifier for each track
),
(
f"{self.slot} "
f"{self.special}\n"
)
)

View file

@ -1,9 +1,10 @@
from source.mkw.Track.AbstractTrack import AbstractTrack from source.mkw.Track.AbstractTrack import AbstractTrack
from source.mkw.Track.RealArenaTrack import RealArenaTrack
ModConfig: any ModConfig: any
class CustomTrack(AbstractTrack): class CustomTrack(RealArenaTrack, AbstractTrack):
""" """
Represent a custom track Represent a custom track
""" """
@ -18,21 +19,9 @@ class CustomTrack(AbstractTrack):
:return: Track :return: Track
""" """
if "group" in track_dict: if "group" in track_dict:
from source.mkw.TrackGroup import TrackGroup from source.mkw.Track.TrackGroup import TrackGroup
return TrackGroup.from_dict(track_dict) return TrackGroup.from_dict(track_dict)
return cls(**track_dict) return cls(**track_dict)
def repr_format(self, mod_config: "ModConfig", template: str) -> str:
return mod_config.multiple_safe_eval(
template,
env={
"track": self,
"get_tag_template": lambda *args, **kwargs: self.get_tag_template(mod_config, *args, **kwargs)
}
)
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: def is_new(self, mod_config: "ModConfig") -> bool:
return mod_config.safe_eval(mod_config.global_settings["replace_random_new"].value, env={"track": self}) is True return mod_config.safe_eval(mod_config.global_settings["replace_random_new"].value, env={"track": self}) is True

View file

@ -0,0 +1,31 @@
class RealArenaTrack:
"""
class shared between all arena and track class that represent a "real" track or arena
(For example, DefaultTrack is not considered a real track class)
"""
tags: list
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_templates[template_name], self.tags):
return mod_config.multiple_safe_eval(mod_config.tags_templates[template_name][tag], env={"tag": tag})
return default
def repr_format(self, mod_config: "ModConfig", template: str) -> str:
return mod_config.multiple_safe_eval(
template,
env={
"track": self,
"get_tag_template": lambda *args, **kwargs: self.get_tag_template(mod_config, *args, **kwargs)
}
)
def get_filename(self, mod_config: "ModConfig") -> str:
return self.repr_format(mod_config=mod_config, template=mod_config.track_file_template)

View file

@ -1,3 +1,5 @@
from source.mkw.Track.CustomTrack import CustomTrack from source.mkw.Track.CustomTrack import CustomTrack
from source.mkw.Track.DefaultTrack import DefaultTrack from source.mkw.Track.DefaultTrack import DefaultTrack
from source.mkw.Track.AbstractTrack import AbstractTrack from source.mkw.Track.AbstractTrack import AbstractTrack
from source.mkw.Track.TrackGroup import TrackGroup
from source.mkw.Track.Arena import Arena