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",
"CANNOT_FIND_TOOL": "Can't find tool",
"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é",
"CANNOT_FIND_TOOL": "Impossible de trouver l'outil",
"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, '" '))
@dataclass(init=True, slots=True, frozen=True)
@dataclass(init=True, slots=True)
class OriginalTrack:
"""
An object representing one of the original track / arena of the game
@ -17,64 +17,66 @@ class OriginalTrack:
name: str
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] = [
OriginalTrack(name="beginner_course", slot="T11", nickname="LC"),
OriginalTrack(name="farm_course", slot="T12", nickname="MMM"),
OriginalTrack(name="kinoko_course", slot="T13", nickname="MG"),
OriginalTrack(name="factory_course", slot="T14", nickname="TF"),
OriginalTrack(name="beginner_course", slot=Slot.get(normal="T11")),
OriginalTrack(name="farm_course", slot="T12"),
OriginalTrack(name="kinoko_course", slot="T13"),
OriginalTrack(name="factory_course", slot="T14"),
OriginalTrack(name="castle_course", slot="T21", nickname="MC"),
OriginalTrack(name="shopping_course", slot="T22", nickname="CM"),
OriginalTrack(name="boardcross_course", slot="T23", nickname="DKS"),
OriginalTrack(name="truck_course", slot="T24", nickname="WGM"),
OriginalTrack(name="castle_course", slot="T21"),
OriginalTrack(name="shopping_course", slot="T22"),
OriginalTrack(name="boardcross_course", slot="T23"),
OriginalTrack(name="truck_course", slot="T24"),
OriginalTrack(name="senior_course", slot="T31", nickname="DC"),
OriginalTrack(name="water_course", slot="T32", nickname="KC"),
OriginalTrack(name="treehouse_course", slot="T33", nickname="MT"),
OriginalTrack(name="volcano_course", slot="T34", nickname="GV"),
OriginalTrack(name="senior_course", slot="T31"),
OriginalTrack(name="water_course", slot="T32"),
OriginalTrack(name="treehouse_course", slot="T33"),
OriginalTrack(name="volcano_course", slot="T34"),
OriginalTrack(name="desert_course", slot="T41", nickname="DDR"),
OriginalTrack(name="ridgehighway_course", slot="T42", nickname="MH"),
OriginalTrack(name="koopa_course", slot="T43", nickname="BC"),
OriginalTrack(name="rainbow_course", slot="T44", nickname="RR"),
OriginalTrack(name="desert_course", slot="T41"),
OriginalTrack(name="ridgehighway_course", slot="T42"),
OriginalTrack(name="koopa_course", slot="T43"),
OriginalTrack(name="rainbow_course", slot="T44"),
# retro tracks
OriginalTrack(name="old_peach_gc", slot="T51", nickname="gPB"),
OriginalTrack(name="old_falls_ds", slot="T52", nickname="dYF"),
OriginalTrack(name="old_obake_sfc", slot="T53", nickname="sGV2"),
OriginalTrack(name="old_mario_64", slot="T54", nickname="nMR"),
OriginalTrack(name="old_peach_gc", slot="T51"),
OriginalTrack(name="old_falls_ds", slot="T52"),
OriginalTrack(name="old_obake_sfc", slot="T53"),
OriginalTrack(name="old_mario_64", slot="T54"),
OriginalTrack(name="old_sherbet_64", slot="T61", nickname="nSL"),
OriginalTrack(name="old_heyho_gba", slot="T62", nickname="gSGB"),
OriginalTrack(name="old_town_ds", slot="T63", nickname="dDS"),
OriginalTrack(name="old_waluigi_gc", slot="T64", nickname="gWS"),
OriginalTrack(name="old_sherbet_64", slot="T61"),
OriginalTrack(name="old_heyho_gba", slot="T62"),
OriginalTrack(name="old_town_ds", slot="T63"),
OriginalTrack(name="old_waluigi_gc", slot="T64"),
OriginalTrack(name="old_desert_ds", slot="T71", nickname="dDH"),
OriginalTrack(name="old_koopa_gba", slot="T72", nickname="gBC3"),
OriginalTrack(name="old_donkey_64", slot="T73", nickname="nDKJP"),
OriginalTrack(name="old_mario_gc", slot="T74", nickname="gMC"),
OriginalTrack(name="old_desert_ds", slot="T71"),
OriginalTrack(name="old_koopa_gba", slot="T72"),
OriginalTrack(name="old_donkey_64", slot="T73"),
OriginalTrack(name="old_mario_gc", slot="T74"),
OriginalTrack(name="old_mario_sfc", slot="T81", nickname="sMC3"),
OriginalTrack(name="old_garden_ds", slot="T82", nickname="dPG"),
OriginalTrack(name="old_donkey_gc", slot="T83", nickname="gDKM"),
OriginalTrack(name="old_koopa_64", slot="T84", nickname="nBC"),
OriginalTrack(name="old_mario_sfc", slot="T81"),
OriginalTrack(name="old_garden_ds", slot="T82"),
OriginalTrack(name="old_donkey_gc", slot="T83"),
OriginalTrack(name="old_koopa_64", slot="T84"),
# wii arena
OriginalTrack(name="block_battle", slot="A11", nickname="aBP"),
OriginalTrack(name="venice_battle", slot="A12", nickname="aDP"),
OriginalTrack(name="skate_battle", slot="A13", nickname="aFS"),
OriginalTrack(name="casino_battle", slot="A14", nickname="aCCW"),
OriginalTrack(name="sand_battle", slot="A15", nickname="aTD"),
OriginalTrack(name="block_battle", slot="A11"),
OriginalTrack(name="venice_battle", slot="A12"),
OriginalTrack(name="skate_battle", slot="A13"),
OriginalTrack(name="casino_battle", slot="A14"),
OriginalTrack(name="sand_battle", slot="A15"),
# retro arena
OriginalTrack(name="old_battle4_sfc", slot="A21", nickname="asBC4"),
OriginalTrack(name="old_battle3_gba", slot="A22", nickname="agBC3"),
OriginalTrack(name="old_matenro_64", slot="A23", nickname="anSS"),
OriginalTrack(name="old_CookieLand_gc", slot="A24", nickname="agCL"),
OriginalTrack(name="old_House_ds", slot="A25", nickname="adTH"),
OriginalTrack(name="old_battle4_sfc", slot="A21"),
OriginalTrack(name="old_battle3_gba", slot="A22"),
OriginalTrack(name="old_matenro_64", slot="A23"),
OriginalTrack(name="old_CookieLand_gc", slot="A24"),
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 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 _
if TYPE_CHECKING:
@ -14,14 +14,15 @@ class TrackForbiddenCustomAttribute(Exception):
class AbstractTrack(ABC):
music: Slot
special: Slot
music: Slot.Slot
special: Slot.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
def __init__(self, music: Slot.Slot = "T11", special: Slot.Slot = "T11",
tags: list[Tag] = None, weight: int = 1, **kwargs):
self.music = Slot.find(music)
self.special = Slot.find(special)
self.tags = tags if tags is not None else []
self.weight = weight
@ -87,8 +88,8 @@ class AbstractTrack(ABC):
return (
f'{category} ' # category (is the track hidden, visible, an arena, ...)
f'{self.music}; ' # music
f'{self.special}; ' # property of the tracks
f'{self.music.normal}; ' # music
f'{self.special.normal}; ' # property of the tracks
f'{flags:#04x}; ' # lecode flags
f'{filename!r}; ' # filename
f'{name!r}; ' # name of the track in the menu

View file

@ -15,15 +15,16 @@ class ArenaForbiddenCustomAttribute(Exception):
class Arena(RealArenaTrack):
slot: Slot
music: Slot
special: Slot
slot: Slot.Slot
music: Slot.Slot
special: Slot.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
def __init__(self, slot: Slot.Slot, music: Slot.Slot = None, special: Slot.Slot = None,
tags: list[Tag] = None, **kwargs):
self.slot = Slot.find(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 []
# others not mandatory attributes
@ -48,20 +49,20 @@ class Arena(RealArenaTrack):
"""
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 (
(
f'A ' # category (A for arena)
f'{self.music}; ' # music
f'{self.slot}; ' # slot of the arena
f'{self.music.normal}; ' # music
f'{self.slot.normal}; ' # 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"
f"{self.slot.normal} "
f"{self.special.normal}\n"
)
)

View file

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