diff --git a/rsi/helpers.py b/rsi/helpers.py deleted file mode 100644 index 95ac437..0000000 --- a/rsi/helpers.py +++ /dev/null @@ -1,8 +0,0 @@ -from typing import List, Optional - - -def state_name(name: str, selectors: Optional[List[str]] = None) -> str: - if selectors: - name += "+" + "+".join(sorted(selectors)) - - return name diff --git a/rsi/rsi.py b/rsi/rsi.py index 3838014..ed3c3a6 100644 --- a/rsi/rsi.py +++ b/rsi/rsi.py @@ -4,7 +4,6 @@ from typing import Dict, Tuple, Union, cast, TextIO, Any, List, Type, Optional from PIL import Image from .direction import Direction -from .helpers import state_name from .state import State RSI_LATEST_COMPATIBLE = 1 @@ -18,15 +17,15 @@ def __init__(self, size: Tuple[int, int]) -> None: self.license = None # type: Optional[str] self.copyright = None # type: Optional[str] - def get_state(self, name: str, selectors: Optional[List[str]] = None) -> Optional[State]: - return self.states.get(state_name(name, selectors)) + def get_state(self, name: str) -> Optional[State]: + return self.states.get(name) - def set_state(self, state: State, name: str, selectors: Optional[List[str]] = None) -> None: - self.states[state_name(name, selectors)] = state + def set_state(self, state: State, name: str) -> None: + self.states[name] = state - def new_state(self, directions: int, name: str, selectors: Optional[List[str]] = None) -> State: - newstate = State(name, selectors or [], self.size, directions) - self.set_state(newstate, name, selectors) + def new_state(self, directions: int, name: str) -> State: + newstate = State(name, self.size, directions) + self.set_state(newstate, name) return newstate def write(self, path: Union[str, Path], make_parent_dirs: bool = True) -> None: @@ -56,21 +55,14 @@ def write(self, path: Union[str, Path], make_parent_dirs: bool = True) -> None: for state in self.states.values(): statedict = {} # type: Dict[str, Any] statedict["name"] = state.name - if state.selectors: - statedict["select"] = state.selectors if state.flags: statedict["flags"] = state.flags statedict["directions"] = state.directions statedict["delays"] = state.delays - # Non-standard, but removed after the sort so the sort can use it while sorting. - statedict["fullname"] = state.full_name states.append(statedict) - states.sort(key=lambda x: x["fullname"]) - - for statedata in states: - del statedata["fullname"] + states.sort(key=lambda x: x["name"]) metajson["states"] = states @@ -105,7 +97,7 @@ def write(self, path: Union[str, Path], make_parent_dirs: bool = True) -> None: count += 1 # break - pngpath = path.joinpath(state.full_name + ".png") # type: Path + pngpath = path.joinpath(state.name + ".png") # type: Path image.save(pngpath, "PNG") @classmethod @@ -130,7 +122,7 @@ def open(cls, path: Union[str, Path]) -> "Rsi": for state in meta["states"]: newstate = rsi.new_state( - state["directions"], state["name"], state.get("select", [])) # type: State + state["directions"], state["name"]) # type: State if "flags" in state: newstate.flags = state["flags"] diff --git a/rsi/state.py b/rsi/state.py index bd19f8b..84cf22b 100644 --- a/rsi/state.py +++ b/rsi/state.py @@ -1,17 +1,12 @@ from typing import List, Tuple, Dict, Any from PIL import Image -from .helpers import state_name - class State(object): def __init__(self, name: str, - selectors: List[str], size: Tuple[int, int], directions: int = 1) -> None: self.name = name # type: str - self.selectors = selectors # type: List[str] - self.full_name = state_name(self.name, self.selectors) # type: str self.flags = {} # type: Dict[str, Any] self.size = size # type: Tuple[int, int] self.directions = directions # type: int diff --git a/spec/RSI.md b/spec/RSI.md index f4fc931..31ae733 100644 --- a/spec/RSI.md +++ b/spec/RSI.md @@ -22,16 +22,15 @@ Key | Meaning A state is a container for metadata for a specific sprite sheet. They store data related to their sprite sheet like delays of animations and directions. A state has an accompanying sprite sheet. -States have Two fields that can be used to distinguish them: +States have one field that can be used to distinguish them: Key | Meaning --- | ------- `name` | The name of the state. Can only contain lowercase alphabetic, numerical, and some special (`_-`) characters. -`select` | A list of strings. There will be a very specific list of selectors and these can not be used arbitrarily. Optional. -States cannot have all the same identifying values. A state with different flags and same name can thus exist, while two states with the same name and no flags will be incorrect. +States cannot have the same identifying value. Two states with the same name may not exist. -Other than identifiers, a state has two other fields in relation to the actual sprites as seen in game: +Other than the identifier, a state has two other fields in relation to the actual sprites as seen in game: Key | Meaning --- | ------- @@ -57,7 +56,7 @@ These directions are ordered (for layout in the `delays` field and ordering in t #### Sprite sheet -The PNG file accompanying a state is always the name of the state, with all selectors appended with plus characters, sorted alphabetically. For example, a state with name "hello" and selectors "x" and "y" would be `hello+x+y.png` on disk. +The PNG file accompanying a state is always the name of the state. For example, a state with name "hello" would be `hello.png` on disk. The file contains the individual states resolved with the directions and delays of the state. The size of the file is always a multiple of the RSI's `size`. Sprites are ordered from the top left to the bottom right, always going horizontally first. The amount of sprites per row or column is always made to be as equal as possible, favoring rows to be longer than columns if the amount of states is not able to be divided perfectly. @@ -81,7 +80,6 @@ Note that in practice the JSON writer probably writes the most compact JSON poss "states": [ { "name": "hello", - "select": [], "flags": {}, "directions": 4, "delays": [