Slot is now a dataclass instead of a simple typehint (should now allow support for the abbreviated slot like LC, MMM, ...)

This commit is contained in:
Faraphel 2022-08-18 23:04:01 +02:00
parent 3bfcfe53e4
commit 49c8353252
7 changed files with 173 additions and 67 deletions

View file

@ -95,6 +95,7 @@
"RAISED": "raised", "RAISED": "raised",
"CANNOT_FIND_TOOL": "Can't find tool", "CANNOT_FIND_TOOL": "Can't find tool",
"IN_TOOLS_DIRECTORY": "in the tools directory.", "IN_TOOLS_DIRECTORY": "in the tools directory.",
"CANNOT_EXTRACT_A_DIRECTORY": "Can't extract a directory" "CANNOT_EXTRACT_A_DIRECTORY": "Can't extract a directory",
"CANNOT_FIND_SLOT": "Can't find slot"
} }
} }

View file

@ -96,6 +96,7 @@
"RAISED": "à levé", "RAISED": "à levé",
"CANNOT_FIND_TOOL": "Impossible de trouver l'outil", "CANNOT_FIND_TOOL": "Impossible de trouver l'outil",
"IN_TOOLS_DIRECTORY": "dans le dossier des outils.", "IN_TOOLS_DIRECTORY": "dans le dossier des outils.",
"CANNOT_EXTRACT_A_DIRECTORY": "Impossible d'extraire un dossier" "CANNOT_EXTRACT_A_DIRECTORY": "Impossible d'extraire un dossier",
"CANNOT_FIND_SLOT": "Impossible de trouver le slot"
} }
} }

View file

@ -9,7 +9,7 @@ class OriginalTrackNotFound(Exception):
super().__init__(_("CANNOT_FIND_ORIGINAL_TRACK", ' "', track_data, '" ')) super().__init__(_("CANNOT_FIND_ORIGINAL_TRACK", ' "', track_data, '" '))
@dataclass(init=True, slots=True, frozen=True) @dataclass(init=True, slots=True)
class OriginalTrack: class OriginalTrack:
""" """
An object representing one of the original track / arena of the game An object representing one of the original track / arena of the game
@ -17,64 +17,66 @@ class OriginalTrack:
name: str name: str
slot: Slot slot: Slot
nickname: str
def __post_init__(self):
if isinstance(self.slot, str): self.slot = Slot.get(normal=self.slot)
all_original_tracks: list[OriginalTrack] = [ all_original_tracks: list[OriginalTrack] = [
OriginalTrack(name="beginner_course", slot="T11", nickname="LC"), OriginalTrack(name="beginner_course", slot=Slot.get(normal="T11")),
OriginalTrack(name="farm_course", slot="T12", nickname="MMM"), OriginalTrack(name="farm_course", slot="T12"),
OriginalTrack(name="kinoko_course", slot="T13", nickname="MG"), OriginalTrack(name="kinoko_course", slot="T13"),
OriginalTrack(name="factory_course", slot="T14", nickname="TF"), OriginalTrack(name="factory_course", slot="T14"),
OriginalTrack(name="castle_course", slot="T21", nickname="MC"), OriginalTrack(name="castle_course", slot="T21"),
OriginalTrack(name="shopping_course", slot="T22", nickname="CM"), OriginalTrack(name="shopping_course", slot="T22"),
OriginalTrack(name="boardcross_course", slot="T23", nickname="DKS"), OriginalTrack(name="boardcross_course", slot="T23"),
OriginalTrack(name="truck_course", slot="T24", nickname="WGM"), OriginalTrack(name="truck_course", slot="T24"),
OriginalTrack(name="senior_course", slot="T31", nickname="DC"), OriginalTrack(name="senior_course", slot="T31"),
OriginalTrack(name="water_course", slot="T32", nickname="KC"), OriginalTrack(name="water_course", slot="T32"),
OriginalTrack(name="treehouse_course", slot="T33", nickname="MT"), OriginalTrack(name="treehouse_course", slot="T33"),
OriginalTrack(name="volcano_course", slot="T34", nickname="GV"), OriginalTrack(name="volcano_course", slot="T34"),
OriginalTrack(name="desert_course", slot="T41", nickname="DDR"), OriginalTrack(name="desert_course", slot="T41"),
OriginalTrack(name="ridgehighway_course", slot="T42", nickname="MH"), OriginalTrack(name="ridgehighway_course", slot="T42"),
OriginalTrack(name="koopa_course", slot="T43", nickname="BC"), OriginalTrack(name="koopa_course", slot="T43"),
OriginalTrack(name="rainbow_course", slot="T44", nickname="RR"), OriginalTrack(name="rainbow_course", slot="T44"),
# retro tracks # retro tracks
OriginalTrack(name="old_peach_gc", slot="T51", nickname="gPB"), OriginalTrack(name="old_peach_gc", slot="T51"),
OriginalTrack(name="old_falls_ds", slot="T52", nickname="dYF"), OriginalTrack(name="old_falls_ds", slot="T52"),
OriginalTrack(name="old_obake_sfc", slot="T53", nickname="sGV2"), OriginalTrack(name="old_obake_sfc", slot="T53"),
OriginalTrack(name="old_mario_64", slot="T54", nickname="nMR"), OriginalTrack(name="old_mario_64", slot="T54"),
OriginalTrack(name="old_sherbet_64", slot="T61", nickname="nSL"), OriginalTrack(name="old_sherbet_64", slot="T61"),
OriginalTrack(name="old_heyho_gba", slot="T62", nickname="gSGB"), OriginalTrack(name="old_heyho_gba", slot="T62"),
OriginalTrack(name="old_town_ds", slot="T63", nickname="dDS"), OriginalTrack(name="old_town_ds", slot="T63"),
OriginalTrack(name="old_waluigi_gc", slot="T64", nickname="gWS"), OriginalTrack(name="old_waluigi_gc", slot="T64"),
OriginalTrack(name="old_desert_ds", slot="T71", nickname="dDH"), OriginalTrack(name="old_desert_ds", slot="T71"),
OriginalTrack(name="old_koopa_gba", slot="T72", nickname="gBC3"), OriginalTrack(name="old_koopa_gba", slot="T72"),
OriginalTrack(name="old_donkey_64", slot="T73", nickname="nDKJP"), OriginalTrack(name="old_donkey_64", slot="T73"),
OriginalTrack(name="old_mario_gc", slot="T74", nickname="gMC"), OriginalTrack(name="old_mario_gc", slot="T74"),
OriginalTrack(name="old_mario_sfc", slot="T81", nickname="sMC3"), OriginalTrack(name="old_mario_sfc", slot="T81"),
OriginalTrack(name="old_garden_ds", slot="T82", nickname="dPG"), OriginalTrack(name="old_garden_ds", slot="T82"),
OriginalTrack(name="old_donkey_gc", slot="T83", nickname="gDKM"), OriginalTrack(name="old_donkey_gc", slot="T83"),
OriginalTrack(name="old_koopa_64", slot="T84", nickname="nBC"), OriginalTrack(name="old_koopa_64", slot="T84"),
# wii arena # wii arena
OriginalTrack(name="block_battle", slot="A11", nickname="aBP"), OriginalTrack(name="block_battle", slot="A11"),
OriginalTrack(name="venice_battle", slot="A12", nickname="aDP"), OriginalTrack(name="venice_battle", slot="A12"),
OriginalTrack(name="skate_battle", slot="A13", nickname="aFS"), OriginalTrack(name="skate_battle", slot="A13"),
OriginalTrack(name="casino_battle", slot="A14", nickname="aCCW"), OriginalTrack(name="casino_battle", slot="A14"),
OriginalTrack(name="sand_battle", slot="A15", nickname="aTD"), OriginalTrack(name="sand_battle", slot="A15"),
# retro arena # retro arena
OriginalTrack(name="old_battle4_sfc", slot="A21", nickname="asBC4"), OriginalTrack(name="old_battle4_sfc", slot="A21"),
OriginalTrack(name="old_battle3_gba", slot="A22", nickname="agBC3"), OriginalTrack(name="old_battle3_gba", slot="A22"),
OriginalTrack(name="old_matenro_64", slot="A23", nickname="anSS"), OriginalTrack(name="old_matenro_64", slot="A23"),
OriginalTrack(name="old_CookieLand_gc", slot="A24", nickname="agCL"), OriginalTrack(name="old_CookieLand_gc", slot="A24"),
OriginalTrack(name="old_House_ds", slot="A25", nickname="adTH"), OriginalTrack(name="old_House_ds", slot="A25"),
] ]

101
source/mkw/Slot.py Normal file
View file

@ -0,0 +1,101 @@
from dataclasses import dataclass
class SlotNotFound(Exception):
def __init__(self, slot_data: any):
super().__init__(_("CANNOT_FIND_SLOT", ' "', slot_data, '" '))
@dataclass(init=True, slots=True, frozen=True, repr=True)
class Slot:
"""
represent a game slot (arena, ...)
"""
normal: str # T11, T12, ...
abbreviation: str # LC, MMM, ...
def __str__(self) -> str: return self.normal
def __eq__(self, other) -> bool: return any(getattr(self, key) == other for key in self.__slots__)
all_slots: list[Slot] = [
Slot(normal="T11", abbreviation="LC"),
Slot(normal="T12", abbreviation="MMM"),
Slot(normal="T13", abbreviation="MG"),
Slot(normal="T14", abbreviation="TF"),
Slot(normal="T21", abbreviation="MC"),
Slot(normal="T22", abbreviation="CM"),
Slot(normal="T23", abbreviation="DKS"),
Slot(normal="T24", abbreviation="WGM"),
Slot(normal="T31", abbreviation="DC"),
Slot(normal="T32", abbreviation="KC"),
Slot(normal="T33", abbreviation="MT"),
Slot(normal="T34", abbreviation="GV"),
Slot(normal="T41", abbreviation="DDR"),
Slot(normal="T42", abbreviation="MH"),
Slot(normal="T43", abbreviation="BC"),
Slot(normal="T44", abbreviation="RR"),
# retro tracks
Slot(normal="T51", abbreviation="gPB"),
Slot(normal="T52", abbreviation="dYF"),
Slot(normal="T53", abbreviation="sGV2"),
Slot(normal="T54", abbreviation="nMR"),
Slot(normal="T61", abbreviation="nSL"),
Slot(normal="T62", abbreviation="gSGB"),
Slot(normal="T63", abbreviation="dDS"),
Slot(normal="T64", abbreviation="gWS"),
Slot(normal="T71", abbreviation="dDH"),
Slot(normal="T72", abbreviation="gBC3"),
Slot(normal="T73", abbreviation="nDKJP"),
Slot(normal="T74", abbreviation="gMC"),
Slot(normal="T81", abbreviation="sMC3"),
Slot(normal="T82", abbreviation="dPG"),
Slot(normal="T83", abbreviation="gDKM"),
Slot(normal="T84", abbreviation="nBC"),
# wii arena
Slot(normal="A11", abbreviation="aBP"),
Slot(normal="A12", abbreviation="aDP"),
Slot(normal="A13", abbreviation="aFS"),
Slot(normal="A14", abbreviation="aCCW"),
Slot(normal="A15", abbreviation="aTD"),
# retro arena
Slot(normal="A21", abbreviation="asBC4"),
Slot(normal="A22", abbreviation="agBC3"),
Slot(normal="A23", abbreviation="anSS"),
Slot(normal="A24", abbreviation="agCL"),
Slot(normal="A25", abbreviation="adTH"),
]
def get(**slot_datas) -> Slot:
"""
Get a original slot object from keys and its value
:param slot_datas: dictionary of track key and their value
:return: the corresponding slot
"""
try:
return next(filter(
lambda slot: all(getattr(slot, key) == value for key, value in slot_datas.items()),
all_slots
))
except StopIteration: raise SlotNotFound(slot_datas)
def find(value) -> Slot:
"""
Return a slot from any value of any key.
:param value: the value used to search the slot
:return: the corresponding slot
"""
try: return next(filter(lambda slot: slot == value, all_slots))
except StopIteration: raise SlotNotFound(value)

View file

@ -1,7 +1,7 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Generator, TYPE_CHECKING from typing import Generator, TYPE_CHECKING
from source.mkw import Slot, Tag, ModConfig from source.mkw import Tag, ModConfig, Slot
from source.translation import translate as _ from source.translation import translate as _
if TYPE_CHECKING: if TYPE_CHECKING:
@ -14,14 +14,15 @@ class TrackForbiddenCustomAttribute(Exception):
class AbstractTrack(ABC): class AbstractTrack(ABC):
music: Slot music: Slot.Slot
special: Slot special: Slot.Slot
tags: list[Tag] tags: list[Tag]
weight: int weight: int
def __init__(self, music: Slot = "T11", special: Slot = "T11", tags: list[Tag] = None, weight: int = 1, **kwargs): def __init__(self, music: Slot.Slot = "T11", special: Slot.Slot = "T11",
self.music = music tags: list[Tag] = None, weight: int = 1, **kwargs):
self.special = special self.music = Slot.find(music)
self.special = Slot.find(special)
self.tags = tags if tags is not None else [] self.tags = tags if tags is not None else []
self.weight = weight self.weight = weight
@ -87,8 +88,8 @@ class AbstractTrack(ABC):
return ( return (
f'{category} ' # category (is the track hidden, visible, an arena, ...) f'{category} ' # category (is the track hidden, visible, an arena, ...)
f'{self.music}; ' # music f'{self.music.normal}; ' # music
f'{self.special}; ' # property of the tracks f'{self.special.normal}; ' # property of the tracks
f'{flags:#04x}; ' # lecode flags f'{flags:#04x}; ' # lecode flags
f'{filename!r}; ' # filename f'{filename!r}; ' # filename
f'{name!r}; ' # name of the track in the menu f'{name!r}; ' # name of the track in the menu

View file

@ -15,15 +15,16 @@ class ArenaForbiddenCustomAttribute(Exception):
class Arena(RealArenaTrack): class Arena(RealArenaTrack):
slot: Slot slot: Slot.Slot
music: Slot music: Slot.Slot
special: Slot special: Slot.Slot
tags: list[Tag] tags: list[Tag]
def __init__(self, slot: Slot, music: Slot = None, special: Slot = None, tags: list[Tag] = None, **kwargs): def __init__(self, slot: Slot.Slot, music: Slot.Slot = None, special: Slot.Slot = None,
self.slot = slot tags: list[Tag] = None, **kwargs):
self.music = music if music is not None else slot self.slot = Slot.find(slot)
self.special = special if special is not None else slot self.music = Slot.find(music if music is not None else slot)
self.special = Slot.find(special if special is not None else slot)
self.tags = tags if tags is not None else [] self.tags = tags if tags is not None else []
# others not mandatory attributes # others not mandatory attributes
@ -48,20 +49,20 @@ class Arena(RealArenaTrack):
""" """
name: str = self.repr_format(mod_config=mod_config, template=template) name: str = self.repr_format(mod_config=mod_config, template=template)
filename = self.get_filename(mod_config=mod_config) filename: str = self.get_filename(mod_config=mod_config)
return ( return (
( (
f'A ' # category (A for arena) f'A ' # category (A for arena)
f'{self.music}; ' # music f'{self.music.normal}; ' # music
f'{self.slot}; ' # slot of the arena f'{self.slot.normal}; ' # slot of the arena
f'0x00; ' # lecode flag f'0x00; ' # lecode flag
f'{filename!r}; ' # filename f'{filename!r}; ' # filename
f'{name!r}; ' # name of the track in the menu f'{name!r}; ' # name of the track in the menu
f'{filename!r}\n' # unique identifier for each track f'{filename!r}\n' # unique identifier for each track
), ),
( (
f"{self.slot} " f"{self.slot.normal} "
f"{self.special}\n" f"{self.special.normal}\n"
) )
) )

View file

@ -1,2 +1 @@
Tag = str Tag = str
Slot = str