2021-08-20 22:16:38 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2021-08-16 23:35:57 +00:00
|
|
|
import json
|
2021-08-23 14:00:17 +00:00
|
|
|
import os
|
2021-08-16 23:35:57 +00:00
|
|
|
|
2021-08-20 22:16:38 +00:00
|
|
|
import requests
|
|
|
|
|
2021-08-16 23:35:57 +00:00
|
|
|
from .carddb import CardDB
|
2021-08-18 14:52:32 +00:00
|
|
|
from .cards import Cards
|
2021-08-16 23:35:57 +00:00
|
|
|
from .code import Code
|
2021-09-01 17:01:53 +00:00
|
|
|
from .language import Language
|
2021-08-23 14:00:17 +00:00
|
|
|
from .utils import CARD_BACK_URL, DECKS_DIR_NAME
|
2021-08-16 23:35:57 +00:00
|
|
|
|
|
|
|
|
2021-08-18 14:52:32 +00:00
|
|
|
class TTSDeck(Cards):
|
2021-09-03 00:46:04 +00:00
|
|
|
def __init__(self, codes: list[Code], name: str, description: str, face_down: bool):
|
2021-08-18 14:52:32 +00:00
|
|
|
super().__init__(name)
|
2021-08-18 11:49:34 +00:00
|
|
|
self.__description = description
|
2021-09-03 00:46:04 +00:00
|
|
|
self.__face_down = face_down
|
2021-08-18 11:49:34 +00:00
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
# get cards from carddb
|
2021-09-01 18:14:56 +00:00
|
|
|
carddb = CardDB()
|
2021-08-20 22:16:38 +00:00
|
|
|
self.extend([
|
|
|
|
carddb[code]
|
|
|
|
for code in codes
|
|
|
|
])
|
2021-08-18 14:52:32 +00:00
|
|
|
|
2021-08-20 22:16:38 +00:00
|
|
|
__FFDECKS_API_URL = "https://ffdecks.com/api/deck"
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def from_ffdecks_deck(cls, deck_id: str) -> TTSDeck:
|
2021-09-03 00:46:04 +00:00
|
|
|
# api request
|
2021-08-20 22:16:38 +00:00
|
|
|
req = requests.get(TTSDeck.__FFDECKS_API_URL, params={"deck_id": deck_id})
|
2021-09-03 00:46:04 +00:00
|
|
|
|
|
|
|
# pre-extract the used data
|
|
|
|
deck_cards = [{
|
|
|
|
"code": card["card"]["serial_number"],
|
|
|
|
"type": card["card"]["type"],
|
|
|
|
"cost": int(card["card"]["cost"]),
|
|
|
|
"count": int(card["quantity"]),
|
|
|
|
} for card in req.json()["cards"]]
|
|
|
|
|
|
|
|
# sort cards by type, then by cost
|
|
|
|
def by_type(data: dict[str, str | int]) -> int:
|
|
|
|
key_prios = {
|
|
|
|
"Forward": 1,
|
|
|
|
"Summon": 2,
|
|
|
|
"Monster": 3,
|
|
|
|
"Backup": 5,
|
|
|
|
}
|
|
|
|
|
|
|
|
if data["type"] in key_prios:
|
|
|
|
return key_prios[data["type"]]
|
|
|
|
else:
|
|
|
|
return 4
|
|
|
|
|
|
|
|
def by_cost(data: dict[str, str | int]) -> int:
|
|
|
|
return data["cost"]
|
|
|
|
|
|
|
|
deck_cards.sort(key=by_cost)
|
|
|
|
deck_cards.sort(key=by_type)
|
|
|
|
|
|
|
|
# ffdecks quirk: some full-art promos in database
|
|
|
|
replace_full_arts = {
|
|
|
|
# line format:
|
|
|
|
# full-art-id: normal id,
|
|
|
|
"PR-051": "11-083",
|
|
|
|
"PR-055": "11-062",
|
|
|
|
}
|
|
|
|
|
2021-09-03 01:12:22 +00:00
|
|
|
# replace with normal-art cards
|
2021-09-03 00:46:04 +00:00
|
|
|
for card in deck_cards:
|
|
|
|
if card["code"] in replace_full_arts:
|
|
|
|
card["code"] = replace_full_arts[card["code"]]
|
|
|
|
|
2021-08-20 22:16:38 +00:00
|
|
|
codes = [
|
2021-09-03 00:46:04 +00:00
|
|
|
# create list of code objects
|
|
|
|
Code(card["code"])
|
|
|
|
# for each card
|
|
|
|
for card in deck_cards
|
|
|
|
# repeat to meet count
|
|
|
|
for _ in range(card["count"])
|
2021-08-20 22:16:38 +00:00
|
|
|
]
|
|
|
|
|
2021-09-03 00:46:04 +00:00
|
|
|
# general metadata
|
|
|
|
name = f"{req.json()['name']}"
|
|
|
|
description = deck_id
|
|
|
|
|
|
|
|
# create deck object
|
|
|
|
return cls(codes, name, description, True)
|
2021-08-20 22:16:38 +00:00
|
|
|
|
2021-09-01 17:01:53 +00:00
|
|
|
def tts_object(self, language: Language) -> dict[str, any]:
|
2021-09-02 01:11:31 +00:00
|
|
|
carddb = CardDB()
|
|
|
|
|
2021-09-01 17:01:53 +00:00
|
|
|
# unique face urls used
|
|
|
|
unique_faces = set([
|
|
|
|
card[language].face
|
|
|
|
for card in self
|
|
|
|
])
|
|
|
|
|
|
|
|
# lookup for indices of urls
|
2021-09-02 01:11:31 +00:00
|
|
|
face_indices = {
|
2021-09-01 17:01:53 +00:00
|
|
|
url: i + 1
|
|
|
|
for i, url in enumerate(unique_faces)
|
|
|
|
}
|
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
# build the "CustomDeck" dictionary
|
2021-08-16 23:35:57 +00:00
|
|
|
custom_deck = {
|
2021-08-18 15:38:58 +00:00
|
|
|
str(i): {
|
2021-08-16 23:35:57 +00:00
|
|
|
"NumWidth": "10",
|
|
|
|
"NumHeight": "7",
|
2021-09-02 01:11:31 +00:00
|
|
|
"FaceURL": carddb.get_face_url(face),
|
2021-08-18 11:49:34 +00:00
|
|
|
"BackURL": CARD_BACK_URL,
|
2021-09-02 01:11:31 +00:00
|
|
|
} for face, i in face_indices.items()
|
2021-08-16 23:35:57 +00:00
|
|
|
}
|
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
# values both in main deck and each contained card
|
2021-08-16 23:35:57 +00:00
|
|
|
common_dict = {
|
|
|
|
"Transform": {
|
|
|
|
"scaleX": 2.17822933,
|
|
|
|
"scaleY": 1.0,
|
2021-08-23 20:03:13 +00:00
|
|
|
"scaleZ": 2.17822933,
|
|
|
|
"rotY": 180.0,
|
2021-08-16 23:35:57 +00:00
|
|
|
},
|
|
|
|
"Locked": False,
|
|
|
|
"Grid": True,
|
|
|
|
"Snap": True,
|
|
|
|
"Autoraise": True,
|
|
|
|
"Sticky": True,
|
|
|
|
"Tooltip": True,
|
|
|
|
"GridProjection": False,
|
|
|
|
}
|
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
# cards contained in deck
|
2021-08-16 23:35:57 +00:00
|
|
|
contained_objects = [
|
|
|
|
{
|
2021-09-01 17:01:53 +00:00
|
|
|
"Nickname": card[language].name,
|
|
|
|
"Description": card[language].text,
|
2021-09-02 01:11:31 +00:00
|
|
|
"CardID": 100 * face_indices[card[language].face] + card.index,
|
2021-08-16 23:35:57 +00:00
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
"Name": "Card",
|
2021-08-16 23:35:57 +00:00
|
|
|
"Hands": True,
|
|
|
|
"SidewaysCard": False,
|
2021-08-18 14:52:32 +00:00
|
|
|
} | common_dict for card in self
|
2021-08-16 23:35:57 +00:00
|
|
|
]
|
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
# extract the card ids
|
2021-08-16 23:35:57 +00:00
|
|
|
deck_ids = [
|
|
|
|
contained_object["CardID"]
|
|
|
|
for contained_object in contained_objects
|
|
|
|
]
|
|
|
|
|
2021-08-18 15:38:58 +00:00
|
|
|
# create the deck dictionary
|
2021-09-03 00:46:04 +00:00
|
|
|
deck_dict = {"ObjectStates": [
|
2021-08-16 23:35:57 +00:00
|
|
|
{
|
2021-08-18 14:52:32 +00:00
|
|
|
"Nickname": self.name,
|
2021-08-18 11:49:34 +00:00
|
|
|
"Description": self.__description,
|
2021-08-16 23:35:57 +00:00
|
|
|
"DeckIDs": deck_ids,
|
|
|
|
"CustomDeck": custom_deck,
|
|
|
|
"ContainedObjects": contained_objects,
|
2021-08-18 15:38:58 +00:00
|
|
|
|
|
|
|
"Name": "Deck",
|
|
|
|
"Hands": False,
|
|
|
|
"SidewaysCard": False,
|
2021-08-16 23:35:57 +00:00
|
|
|
} | common_dict
|
|
|
|
]}
|
|
|
|
|
2021-09-03 00:46:04 +00:00
|
|
|
if self.__face_down:
|
|
|
|
# flip the deck
|
|
|
|
deck_dict["ObjectStates"][0]["Transform"]["rotZ"] = 180.0
|
|
|
|
|
|
|
|
return deck_dict
|
|
|
|
|
2021-09-01 17:01:53 +00:00
|
|
|
def save(self, language: Language) -> None:
|
2021-08-18 15:38:58 +00:00
|
|
|
# only save if the deck contains cards
|
|
|
|
if self:
|
2021-08-23 14:00:17 +00:00
|
|
|
if not os.path.exists(DECKS_DIR_NAME):
|
|
|
|
os.mkdir(DECKS_DIR_NAME)
|
|
|
|
|
|
|
|
with open(os.path.join(DECKS_DIR_NAME, f"{self.file_name}.json"), "w") as file:
|
2021-09-01 17:01:53 +00:00
|
|
|
json.dump(self.tts_object(language), file, indent=2)
|