1
0
Fork 0
mirror of https://github.com/ldericher/fftcgtool synced 2025-01-15 15:02:59 +00:00
This commit is contained in:
Jörn-Michael Miehe 2021-08-18 13:49:34 +02:00
parent 8360eb69b2
commit 81122f8de8
7 changed files with 68 additions and 56 deletions

View file

@ -5,7 +5,7 @@ from PIL import Image
from .cards import Cards from .cards import Cards
from .imageloader import ImageLoader from .imageloader import ImageLoader
from .utils import GRID, RESOLUTION, BOOK_YML_NAME from .utils import GRID, RESOLUTION, BOOK_YML_NAME, CARD_BACK_URL
class Book: class Book:
@ -18,10 +18,8 @@ class Book:
# all card face URLs # all card face URLs
urls = [f"https://fftcg.cdn.sewest.net/images/cards/full/{card.code}_{language}.jpg" for card in cards] urls = [f"https://fftcg.cdn.sewest.net/images/cards/full/{card.code}_{language}.jpg" for card in cards]
# card back URL (image by Aurik) # card back URL
urls.append( urls.append(CARD_BACK_URL)
"http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
)
# multi-threaded download # multi-threaded download
images = ImageLoader.load(urls, language, num_threads) images = ImageLoader.load(urls, language, num_threads)

View file

@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import json
import re import re
import yaml import yaml
@ -23,8 +22,6 @@ class Card(yaml.YAMLObject):
"": "Darkness" "": "Darkness"
} }
__ELEMENTS = "".join(__ELEMENTS_MAP.keys())
def __init__(self, code, elements, name, text): def __init__(self, code, elements, name, text):
self.__code = code self.__code = code
self.__elements = elements self.__elements = elements
@ -55,15 +52,15 @@ class Card(yaml.YAMLObject):
# place other letter and numerical cost symbols # place other letter and numerical cost symbols
text = re.sub(r"《([a-z0-9])》", sub_encircle, text, flags=re.IGNORECASE) text = re.sub(r"《([a-z0-9])》", sub_encircle, text, flags=re.IGNORECASE)
# place elemental cost symbols # place elemental cost symbols
text = re.sub(rf"《([{Card.__ELEMENTS}])》", sub_elements, text, flags=re.IGNORECASE) text = re.sub(rf"《([{''.join(Card.__ELEMENTS_MAP.keys())}])》", sub_elements, text, flags=re.IGNORECASE)
# place dull symbols # place dull symbols
text = text.replace("《ダル》", "[⤵]") text = text.replace("《ダル》", "[⤵]")
# replace formatting hints with brackets # replace formatting hints with brackets
text = re.sub(r"\[\[[a-z]\]\]([^\[]*?)\s*\[\[/\]\]\s*", r"[\1] ", text, flags=re.IGNORECASE) text = re.sub(r"\[\[[a-z]]]([^\[]*?)\s*\[\[/]]\s*", r"[\1] ", text, flags=re.IGNORECASE)
# place EX-BURST markers # place EX-BURST markers
text = re.sub(r"\[\[ex\]\]\s*EX BURST\s*\[\[/\]\]\s*", r"[EX BURST] ", text, flags=re.IGNORECASE) text = re.sub(r"\[\[ex]]\s*EX BURST\s*\[\[/]]\s*", r"[EX BURST] ", text, flags=re.IGNORECASE)
# place line breaks # place line breaks
text = re.sub(r"\s*\[\[br\]\]\s*", "\n\n", text, flags=re.IGNORECASE) text = re.sub(r"\s*\[\[br]]\s*", "\n\n", text, flags=re.IGNORECASE)
return cls( return cls(
code=Code(data["Code"]), code=Code(data["Code"]),
@ -75,9 +72,6 @@ class Card(yaml.YAMLObject):
def __str__(self) -> str: def __str__(self) -> str:
return f"'{self.__name}' ({'/'.join(self.__elements)}, {self.code})" return f"'{self.__name}' ({'/'.join(self.__elements)}, {self.code})"
def to_json(self) -> str:
return json.dumps(self, default=lambda o: o.__dict__)
# 6-048C # 6-048C
@property @property
def code(self) -> Code: def code(self) -> Code:

View file

@ -6,6 +6,22 @@ from .card import Card
class Cards(list[Card]): class Cards(list[Card]):
__API_URL = "https://fftcg.square-enix-games.com/de/get-cards" __API_URL = "https://fftcg.square-enix-games.com/de/get-cards"
def __init__(self, name):
super().__init__()
self.__name = name
def __str__(self) -> str:
return f"[{', '.join(str(card) for card in self)}]"
@property
def name(self) -> str:
return self.__name
@property
def file_name(self) -> str:
return self.name.lower().replace(" ", "_")
def _load(self, params: dict[str, any]): def _load(self, params: dict[str, any]):
# required params: # required params:
# text # text
@ -20,6 +36,3 @@ class Cards(list[Card]):
req = requests.post(Cards.__API_URL, json=params) req = requests.post(Cards.__API_URL, json=params)
self.clear() self.clear()
self.extend([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]]) self.extend([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]])
def __str__(self) -> str:
return "\n".join(str(card) for card in self)

View file

@ -8,34 +8,31 @@ from .ttsdeck import TTSDeck
class Opus(Cards): class Opus(Cards):
def __init__(self, opus_id: str): def __init__(self, opus_id: str):
super().__init__()
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if opus_id.isnumeric(): if opus_id.isnumeric():
self.__name = f"Opus {roman.toRoman(int(opus_id)).upper()}" name = f"Opus {opus_id}"
self.__number = opus_id self.__number = opus_id
self.__filename = f"opus_{opus_id}" params = {"set": [f"Opus {roman.toRoman(int(opus_id)).upper()}"]}
params = {"set": [self.__name]}
elif opus_id == "chaos": elif opus_id == "chaos":
self.__name = "Boss Deck Chaos" name = "Boss Deck Chaos"
self.__number = "B" self.__number = "B"
self.__filename = "boss_deck_chaos" params = {"set": [name]}
params = {"set": [self.__name]}
elif opus_id == "promo": elif opus_id == "promo":
self.__name = "Promo" name = "Promo"
self.__number = "PR" self.__number = "PR"
self.__filename = "promo"
params = {"rarity": ["pr"]} params = {"rarity": ["pr"]}
else: else:
self.__name = "?" name = "?"
self.__number = "?" self.__number = "?"
self.__filename = "?" self.__filename = "?"
params = {"set": "?"} params = {"set": "?"}
super().__init__(name)
self._load(params) self._load(params)
# remove reprints # remove reprints
@ -50,25 +47,21 @@ class Opus(Cards):
for card in self: for card in self:
logger.info(f"imported card {card}") logger.info(f"imported card {card}")
@property
def name(self) -> str:
return self.__name
@property @property
def number(self) -> str: def number(self) -> str:
return self.__number return self.__number
@property
def filename(self) -> str:
return self.__filename
@property @property
def elemental_decks(self) -> list[TTSDeck]: def elemental_decks(self) -> list[TTSDeck]:
if self.name in ["Promo", "Boss Deck Chaos"]: if self.name in ["Promo", "Boss Deck Chaos"]:
return [TTSDeck([ return [TTSDeck(
card.code [
for card in self card.code
])] for card in self
],
f"{self.name}",
f"All {self.name} Cards in elemental, then alphabetical order"
)]
else: else:
def element_filter(element: str): def element_filter(element: str):
@ -76,17 +69,21 @@ class Opus(Cards):
# simple cases: create lambdas for base elemental decks # simple cases: create lambdas for base elemental decks
base_elements = ["Fire", "Ice", "Wind", "Earth", "Lightning", "Water"] base_elements = ["Fire", "Ice", "Wind", "Earth", "Lightning", "Water"]
filters = [element_filter(elem) for elem in base_elements] filters = {elem: element_filter(elem) for elem in base_elements}
filters += [ filters |= {
# light/darkness elemental deck # light/darkness elemental deck
lambda card: card.elements == ["Light"] or card.elements == ["Darkness"], "Light/Darkness": lambda card: card.elements == ["Light"] or card.elements == ["Darkness"],
# multi element deck # multi element deck
lambda card: len(card.elements) > 1, "Multi": lambda card: len(card.elements) > 1,
] }
return [TTSDeck([ return [TTSDeck(
card.code [
for card in self card.code
if f(card) for card in self
]) for f in filters] if f(card)
],
f"{self.name} {elem}",
f"All {self.name} Cards with {elem} element in alphabetical order"
) for elem, f in filters.items()]

View file

@ -2,13 +2,17 @@ import json
from .carddb import CardDB from .carddb import CardDB
from .code import Code from .code import Code
from .utils import CARD_BACK_URL
class TTSDeck(list[dict[str, any]]): class TTSDeck(list[dict[str, any]]):
def __init__(self, codes: list[Code]): def __init__(self, codes: list[Code], name: str, description: str):
carddb = CardDB.get() carddb = CardDB.get()
super().__init__([carddb[code] for code in codes]) super().__init__([carddb[code] for code in codes])
self.__name = name
self.__description = description
def __str__(self) -> str: def __str__(self) -> str:
face_urls = list(set([entry["file"] for entry in self])) face_urls = list(set([entry["file"] for entry in self]))
@ -17,7 +21,7 @@ class TTSDeck(list[dict[str, any]]):
"NumWidth": "10", "NumWidth": "10",
"NumHeight": "7", "NumHeight": "7",
"FaceURL": url, "FaceURL": url,
"BackURL": "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/", "BackURL": CARD_BACK_URL,
} for i, url in enumerate(face_urls) } for i, url in enumerate(face_urls)
} }
@ -63,8 +67,8 @@ class TTSDeck(list[dict[str, any]]):
jsondict = {"ObjectStates": [ jsondict = {"ObjectStates": [
{ {
"Name": "Deck", "Name": "Deck",
"Nickname": "TODO Deck Name", "Nickname": self.__name,
"Description": "TODO Deck Description", "Description": self.__description,
"Hands": False, "Hands": False,
"SidewaysCard": False, "SidewaysCard": False,
@ -76,3 +80,6 @@ class TTSDeck(list[dict[str, any]]):
]} ]}
return json.dumps(jsondict, indent=2) return json.dumps(jsondict, indent=2)
def save(self, file_name: str) -> None:
pass

View file

@ -4,6 +4,8 @@ from .grid import Grid
GRID = Grid((10, 7)) # default in TTsim: 10 columns, 7 rows GRID = Grid((10, 7)) # default in TTsim: 10 columns, 7 rows
RESOLUTION = Grid((429, 600)) # default in TTsim: 480x670 pixels per card RESOLUTION = Grid((429, 600)) # default in TTsim: 480x670 pixels per card
BOOK_YML_NAME = "book.yml" BOOK_YML_NAME = "book.yml"
# card back URL (image by Aurik)
CARD_BACK_URL = "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
# functions # functions

View file

@ -41,12 +41,13 @@ def main() -> None:
# main program # main program
opus = fftcg.Opus(args.opus_id) opus = fftcg.Opus(args.opus_id)
book = fftcg.Book(opus, "eg", args.num_threads) book = fftcg.Book(opus, "eg", args.num_threads)
book.save(opus.filename) book.save(opus.file_name)
# create elemental decks for opus # load the current carddb
carddb = fftcg.CardDB.get() carddb = fftcg.CardDB.get()
carddb.load() carddb.load()
# create elemental decks for opus
for deck in opus.elemental_decks: for deck in opus.elemental_decks:
print(deck) print(deck)