Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fb1c77907 |
@@ -1,4 +1,3 @@
|
|||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||||
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
||||||
*.psd filter=lfs diff=lfs merge=lfs -text
|
|
||||||
|
|||||||
+1
-5
@@ -161,8 +161,4 @@ cython_debug/
|
|||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
typings/*
|
typings/*
|
||||||
output/*
|
output/*
|
||||||
|
|
||||||
.idea/*
|
|
||||||
|
|
||||||
src/convert/output/**/*
|
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+3
-1
@@ -1 +1,3 @@
|
|||||||
drawsvg==2.4.0
|
drawsvg==2.4.0
|
||||||
|
pillow==10.4.0
|
||||||
|
--extra-index-url=https://packagecloud.io/github/git-lfs/pypi/simple
|
||||||
@@ -14,7 +14,6 @@ class Translation(TypedDict):
|
|||||||
class SkinData(TypedDict):
|
class SkinData(TypedDict):
|
||||||
title: str
|
title: str
|
||||||
flavor_text_type: str | None
|
flavor_text_type: str | None
|
||||||
flavor_text_bottom: str | None
|
|
||||||
image_path: str
|
image_path: str
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
# TODO next steps
|
|
||||||
|
|
||||||
local file used to track next stuff to do
|
|
||||||
|
|
||||||
- Add details on Damage
|
|
||||||
- Add SVG image for heal
|
|
||||||
- Add bleeding-safe deadzone around PNG output for printing
|
|
||||||
- Different icons for factions?
|
|
||||||
- Add shadow on some pictures that do not cut well (as a skin option, transparent gradient)
|
|
||||||
- Fix larger names
|
|
||||||
- Fix 20
|
|
||||||
- Texte du Con Artist avec la bonne couleur; Pareil pour Kikuri
|
|
||||||
|
|
||||||
|
|
||||||
## Idées
|
|
||||||
|
|
||||||
- 69: demonic cloud -> darkness CSM
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
gtkbin = r'C:\Program Files\GTK3-Runtime Win64\bin'
|
|
||||||
add_dll_dir = getattr(os, 'add_dll_directory', None)
|
|
||||||
if callable(add_dll_dir):
|
|
||||||
add_dll_dir(gtkbin)
|
|
||||||
else:
|
|
||||||
os.environ['PATH'] = os.pathsep.join((gtkbin, os.environ['PATH']))
|
|
||||||
import cairosvg
|
|
||||||
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
folder = Path(r"C:\Users\Luka\Documents\dev\cards-gen\output\heron")
|
|
||||||
|
|
||||||
for svg_file in folder.glob("*.svg"):
|
|
||||||
print("Processing" + str(svg_file))
|
|
||||||
cairosvg.svg2png(
|
|
||||||
url=str(svg_file),
|
|
||||||
scale=3,
|
|
||||||
write_to=f'output/{str(svg_file.name).replace(".svg", ".png")}'
|
|
||||||
)
|
|
||||||
|
|
||||||
+25
-74
@@ -13,23 +13,22 @@
|
|||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"title": "Commandement",
|
"title": "Commandement",
|
||||||
"flavor_text_bottom": "Haniwas, à l'attaque! Go!",
|
|
||||||
"image_path": "../../img/skins/heron/003.png"
|
"image_path": "../../img/skins/heron/003.png"
|
||||||
},
|
},
|
||||||
"4": {
|
"4": {
|
||||||
"title": "Saki, Pégase de Guerre",
|
"title": "Saki, Pégase de Guerre",
|
||||||
"flavor_text_type": "Cowboy",
|
"flavor_text_type": "Cowboy",
|
||||||
"flavor_text_bottom": "Howdy, cowboy!",
|
|
||||||
"image_path": "../../img/skins/heron/004.png"
|
"image_path": "../../img/skins/heron/004.png"
|
||||||
},
|
},
|
||||||
"5": {
|
"5": {
|
||||||
"title": "Domination",
|
"title": "Domination",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/005.png"
|
"image_path": "../../img/skins/heron/005.png"
|
||||||
},
|
},
|
||||||
"6": {
|
"6": {
|
||||||
"title": "Raiden, le Juste",
|
"title": "Raiden, le Juste",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/006.png"
|
"image_path": "../../img/skins/heron/006.png"
|
||||||
},
|
},
|
||||||
"7": {
|
"7": {
|
||||||
@@ -45,7 +44,6 @@
|
|||||||
"9": {
|
"9": {
|
||||||
"title": "Dlanor A. Knox",
|
"title": "Dlanor A. Knox",
|
||||||
"flavor_text_type": "Inquisitrice",
|
"flavor_text_type": "Inquisitrice",
|
||||||
"flavor_text_bottom": "Dame Erika vous veut MORT.",
|
|
||||||
"image_path": "../../img/skins/heron/009.png"
|
"image_path": "../../img/skins/heron/009.png"
|
||||||
},
|
},
|
||||||
"10": {
|
"10": {
|
||||||
@@ -55,7 +53,7 @@
|
|||||||
},
|
},
|
||||||
"11": {
|
"11": {
|
||||||
"title": "Recrutement",
|
"title": "Recrutement",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/011.png"
|
"image_path": "../../img/skins/heron/011.png"
|
||||||
},
|
},
|
||||||
"12": {
|
"12": {
|
||||||
@@ -70,43 +68,42 @@
|
|||||||
},
|
},
|
||||||
"14": {
|
"14": {
|
||||||
"title": "Parole de Puissance",
|
"title": "Parole de Puissance",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/014.png"
|
"image_path": "../../img/skins/heron/014.png"
|
||||||
},
|
},
|
||||||
"15": {
|
"15": {
|
||||||
"title": "Madeline, Mercenaire",
|
"title": "Madeline, Mercenaire",
|
||||||
"flavor_text_type": "Guerrière",
|
"flavor_text_type": "Guerrière",
|
||||||
"flavor_text_bottom": "Salut, c'est Madeline! Dites,\n vous n'auriez pas vu Mauvier?",
|
|
||||||
"image_path": "../../img/skins/heron/015.png"
|
"image_path": "../../img/skins/heron/015.png"
|
||||||
},
|
},
|
||||||
"16": {
|
"16": {
|
||||||
"title": "Pot-de-Vin",
|
"title": "Pot-de-Vin",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/016.png"
|
"image_path": "../../img/skins/heron/016.png"
|
||||||
},
|
},
|
||||||
"17": {
|
"17": {
|
||||||
"title": "Menace de Mort",
|
"title": "Menace de Mort",
|
||||||
"flavor_text_type": "Pas gentil",
|
"flavor_text_type": "Takano",
|
||||||
"image_path": "../../img/skins/heron/017.png"
|
"image_path": "../../img/skins/heron/017.png"
|
||||||
},
|
},
|
||||||
"18": {
|
"18": {
|
||||||
"title": "Fourberie",
|
"title": "Fourberie",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/018.png"
|
"image_path": "../../img/skins/heron/018.png"
|
||||||
},
|
},
|
||||||
"19": {
|
"19": {
|
||||||
"title": "Niko Incendiaire",
|
"title": "Niko Incendiaire",
|
||||||
"flavor_text_type": "gfhd;spfgljh.-",
|
"flavor_text_type": "gfhd;spfgljh.-",
|
||||||
"image_path": "../../img/skins/heron/019.png"
|
"image_path": "../../img/skins/heron/019.gif"
|
||||||
},
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"title": "Tit job",
|
"title": "Tit job",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/020.png"
|
"image_path": "../../img/skins/heron/020.png"
|
||||||
},
|
},
|
||||||
"21": {
|
"21": {
|
||||||
"title": "Intimidation",
|
"title": "Intimidation",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/021.png"
|
"image_path": "../../img/skins/heron/021.png"
|
||||||
},
|
},
|
||||||
"22": {
|
"22": {
|
||||||
@@ -121,12 +118,12 @@
|
|||||||
},
|
},
|
||||||
"24": {
|
"24": {
|
||||||
"title": "Bénéfice",
|
"title": "Bénéfice",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/024.png"
|
"image_path": "../../img/skins/heron/024.png"
|
||||||
},
|
},
|
||||||
"25": {
|
"25": {
|
||||||
"title": "Jester, Maître Assassin",
|
"title": "Jester, Maître Assassin",
|
||||||
"flavor_text_bottom": "Son nom maintient les employés\nde la compagnie éveillés.",
|
|
||||||
"image_path": "../../img/skins/heron/025.png"
|
"image_path": "../../img/skins/heron/025.png"
|
||||||
},
|
},
|
||||||
"26": {
|
"26": {
|
||||||
@@ -142,7 +139,6 @@
|
|||||||
"28": {
|
"28": {
|
||||||
"title": "Cirno",
|
"title": "Cirno",
|
||||||
"flavor_text_type": "Baka",
|
"flavor_text_type": "Baka",
|
||||||
"flavor_text_bottom": "Dansu no chansu ni pankuna\nranbu de anta no mausu wa anguri\n nan chi ~yuu fanki!",
|
|
||||||
"image_path": "../../img/skins/heron/028.png"
|
"image_path": "../../img/skins/heron/028.png"
|
||||||
},
|
},
|
||||||
"29": {
|
"29": {
|
||||||
@@ -157,13 +153,12 @@
|
|||||||
},
|
},
|
||||||
"31": {
|
"31": {
|
||||||
"title": "Sombre Récompense",
|
"title": "Sombre Récompense",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/031.png"
|
"image_path": "../../img/skins/heron/031.png"
|
||||||
},
|
},
|
||||||
"32": {
|
"32": {
|
||||||
"title": "Bracken",
|
"title": "Bracken",
|
||||||
"flavor_text_type": "Entité",
|
"flavor_text_type": "Entité",
|
||||||
"flavor_text_bottom": "\"MAIS REND MON POTE\"",
|
|
||||||
"image_path": "../../img/skins/heron/032.png"
|
"image_path": "../../img/skins/heron/032.png"
|
||||||
},
|
},
|
||||||
"33": {
|
"33": {
|
||||||
@@ -178,7 +173,7 @@
|
|||||||
},
|
},
|
||||||
"35": {
|
"35": {
|
||||||
"title": "Trick-or-Treat!",
|
"title": "Trick-or-Treat!",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/035.png"
|
"image_path": "../../img/skins/heron/035.png"
|
||||||
},
|
},
|
||||||
"36": {
|
"36": {
|
||||||
@@ -218,7 +213,7 @@
|
|||||||
},
|
},
|
||||||
"43": {
|
"43": {
|
||||||
"title": "Panette, la Berserker",
|
"title": "Panette, la Berserker",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/043.png"
|
"image_path": "../../img/skins/heron/043.png"
|
||||||
},
|
},
|
||||||
"44": {
|
"44": {
|
||||||
@@ -243,7 +238,7 @@
|
|||||||
},
|
},
|
||||||
"48": {
|
"48": {
|
||||||
"title": "Don de la Nature",
|
"title": "Don de la Nature",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/048.png"
|
"image_path": "../../img/skins/heron/048.png"
|
||||||
},
|
},
|
||||||
"49": {
|
"49": {
|
||||||
@@ -253,22 +248,22 @@
|
|||||||
},
|
},
|
||||||
"50": {
|
"50": {
|
||||||
"title": "Impulsion Temporelle",
|
"title": "Impulsion Temporelle",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/050.png"
|
"image_path": "../../img/skins/heron/050.png"
|
||||||
},
|
},
|
||||||
"51": {
|
"51": {
|
||||||
"title": "Baiken, Samurai Slasher",
|
"title": "Baiken, Samurai Slasher",
|
||||||
"flavor_text_bottom": "Il n'y a pas de victoire ou défaite.\nJuste du savoir sur soi-même.",
|
|
||||||
"image_path": "../../img/skins/heron/051.png"
|
"image_path": "../../img/skins/heron/051.png"
|
||||||
},
|
},
|
||||||
"52": {
|
"52": {
|
||||||
"title": "Étincelle de Caine",
|
"title": "Étincelle de Caine",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/052.png"
|
"image_path": "../../img/skins/heron/052.png"
|
||||||
},
|
},
|
||||||
"53": {
|
"53": {
|
||||||
"title": "Forme de Loup",
|
"title": "Forme de Loup",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/053.png"
|
"image_path": "../../img/skins/heron/053.png"
|
||||||
},
|
},
|
||||||
"54": {
|
"54": {
|
||||||
@@ -283,75 +278,31 @@
|
|||||||
},
|
},
|
||||||
"56": {
|
"56": {
|
||||||
"title": "Live",
|
"title": "Live",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/056.png"
|
"image_path": "../../img/skins/heron/056.png"
|
||||||
},
|
},
|
||||||
"57": {
|
"57": {
|
||||||
"title": "Superkill",
|
"title": "Superkill",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/057.png"
|
"image_path": "../../img/skins/heron/057.png"
|
||||||
},
|
},
|
||||||
"58": {
|
"58": {
|
||||||
"title": "Kill",
|
"title": "Kill",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/058.png"
|
"image_path": "../../img/skins/heron/058.png"
|
||||||
},
|
},
|
||||||
"59": {
|
"59": {
|
||||||
"title": "Live Forever",
|
"title": "Live Forever",
|
||||||
|
|
||||||
"image_path": "../../img/skins/heron/059.png"
|
"image_path": "../../img/skins/heron/059.png"
|
||||||
},
|
},
|
||||||
"60": {
|
|
||||||
"title": "Collection de Bounty",
|
|
||||||
"image_path": "../../img/skins/heron/060.png"
|
|
||||||
},
|
|
||||||
"61": {
|
|
||||||
"title": "Dangereuse échappée",
|
|
||||||
"image_path": "../../img/skins/heron/061.png"
|
|
||||||
},
|
|
||||||
"62": {
|
|
||||||
"title": "Festival de Watanagashi",
|
|
||||||
"image_path": "../../img/skins/heron/062.png"
|
|
||||||
},
|
|
||||||
"63": {
|
|
||||||
"title": "Plus la même",
|
|
||||||
"image_path": "../../img/skins/heron/063.png"
|
|
||||||
},
|
|
||||||
"65": {
|
|
||||||
"title": "Starlight Convergence",
|
|
||||||
"image_path": "../../img/skins/heron/065.png"
|
|
||||||
},
|
|
||||||
"68": {
|
"68": {
|
||||||
"title": "Confisquer",
|
"title": "Confisquer",
|
||||||
"image_path": "../../img/skins/heron/068.png"
|
"image_path": "../../img/skins/heron/068.png"
|
||||||
},
|
},
|
||||||
"70": {
|
|
||||||
"title": "Jus de Prune",
|
|
||||||
"image_path": "../../img/skins/heron/070.png"
|
|
||||||
},
|
|
||||||
"71": {
|
"71": {
|
||||||
"title": "Rosser",
|
"title": "Rosser",
|
||||||
"image_path": "../../img/skins/heron/071.png"
|
"image_path": "../../img/skins/heron/071.png"
|
||||||
},
|
|
||||||
"72": {
|
|
||||||
"title": "Rakiie Swiftkick",
|
|
||||||
"image_path": "../../img/skins/heron/072.png"
|
|
||||||
},
|
|
||||||
"73": {
|
|
||||||
"title": "Trading Card",
|
|
||||||
"image_path": "../../img/skins/heron/073.png"
|
|
||||||
},
|
|
||||||
"74": {
|
|
||||||
"title": "Scout, Nain de DRG",
|
|
||||||
"image_path": "../../img/skins/heron/074.png"
|
|
||||||
},
|
|
||||||
"84": {
|
|
||||||
"title": "ULTRAKILL",
|
|
||||||
"image_path": "../../img/skins/heron/084.png"
|
|
||||||
},
|
|
||||||
"85": {
|
|
||||||
"title": "Ultralive",
|
|
||||||
"image_path": "../../img/skins/heron/085.png"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,11 @@
|
|||||||
{
|
{
|
||||||
"card_type":{
|
"card_type":{
|
||||||
"action":"Action",
|
"action":"Action",
|
||||||
"champion":"Champion",
|
"champion":"Champion"
|
||||||
"item": "Objet"
|
|
||||||
},
|
|
||||||
"colors":{
|
|
||||||
"red": "rouge",
|
|
||||||
"green": "verte",
|
|
||||||
"blue": "bleu",
|
|
||||||
"yellow": "jaune"
|
|
||||||
},
|
},
|
||||||
"numbers":{
|
"numbers":{
|
||||||
"1": "une",
|
"1": "une",
|
||||||
"2": "deux",
|
"2": "deux"
|
||||||
"3": "trois",
|
|
||||||
"4": "quatre"
|
|
||||||
},
|
},
|
||||||
"effects":{
|
"effects":{
|
||||||
"draw":"Piochez une carte.",
|
"draw":"Piochez une carte.",
|
||||||
@@ -29,32 +20,21 @@
|
|||||||
"restack_discarded_action":"Mettez une action de\nvotre défausse au dessus\nde votre pioche.",
|
"restack_discarded_action":"Mettez une action de\nvotre défausse au dessus\nde votre pioche.",
|
||||||
"make_discard":"L'adversaire ciblé%nse défausse d'une carte.",
|
"make_discard":"L'adversaire ciblé%nse défausse d'une carte.",
|
||||||
"draw_and_discard":"Vous pouvez piocher une carte, puis\n vous défausser d'une carte.",
|
"draw_and_discard":"Vous pouvez piocher une carte, puis\n vous défausser d'une carte.",
|
||||||
"draw_and_discard_times":"Vous pouvez piocher jusqu'à %a cartes,\ndéfaussez-vous ensuite d'autant de cartes.",
|
"draw_and_discard_times":"Vous pouvez piocher jusqu'à %a cartes,\ndéfaussez-vous ensuite d'autant de cartes",
|
||||||
"play_next_card_bought":"Mettez la prochaine carte dont\nvous faites l'acquisition ce tour-ci\n dans votre main.",
|
"play_next_card_bought":"Mettez la prochaine carte dont\nvous faites l'acquisition ce tour-ci\n dans votre main.",
|
||||||
"prepare":"Mobilisez un Champion.",
|
"prepare":"Mobilisez un Champion",
|
||||||
"prepare_all_champions":"Mobilisez vos Champions.",
|
"prepare_all_champions":"Mobilisez vos Champions.",
|
||||||
"prepare_another_champion":"Mobilisez un autre Champion.",
|
"prepare_another_champion":"Mobilisez un autre Champion.",
|
||||||
"cheaper_champions_passive":"Les Champions que vous achetez ce tour-ci\nvous coûtent 1 de moins.",
|
"cheaper_champions_passive":"Le prochain Champion que vous achetez\nvous coûte 1 de moins ce tour-ci.",
|
||||||
"cheaper_champion": "Le prochain Champion que vous achetez\nvous coûte 1 de moins.",
|
"control_opposing_champion_passive":"Prenez le contrôle d'un Champion\nennemi jusqu'à la fin du tour."
|
||||||
"control_opposing_champion_passive":"Prenez le contrôle d'un Champion\nennemi jusqu'à la fin du tour.",
|
|
||||||
"buy_for_free_amount":"Vous pouvez acquérir gratuitement\nune carte de coût %a ou moins.",
|
|
||||||
"damage_all_champions_amount":"Infligez %a dégats à tous\nles Champions adverses.",
|
|
||||||
"discard_x_and_draw_x":"Vous pouvez vous défausser de\nn'importe quel nombre de cartes\net en piocher autant.",
|
|
||||||
"buy_gem_for_free": "Obtenez une gemme de coût 2\n ou moins gratuitement."
|
|
||||||
},
|
},
|
||||||
"per":{
|
"per":{
|
||||||
"champion":"pour chaque Champion\nque vous avez en jeu.",
|
"champion":"pour chaque Champion\nque vous avez en jeu",
|
||||||
"other_champion":"pour chaque autre\nChampion que vous avez\nen jeu.",
|
"other_champion":"pour chaque autre Champion\nque vous avez en jeu",
|
||||||
"other_guard":"pour chaque autre\nGarde que vous avez en jeu.",
|
"other_guard":"pour chaque autre\nGarde que vous avez en jeu",
|
||||||
"other_card_of_same_faction":"pour chaque autre\n carte %c que vous avez\nen jeu.",
|
"other_card_of_same_faction":"pour chaque autre x\nque vous avez en jeu",
|
||||||
"champion_of_same_faction":"pour chaque \nChampion %c que vous\navez en jeu.",
|
"champion_of_same_faction":"pour chaque Champion x\nque vous avez en jeu",
|
||||||
"other_knife_played":"pour chaque autre Couteau\nque vous avez en jeu.",
|
"other_knife_played":"pour chaque autre Couteau\nque vous avez en jeu"
|
||||||
"stunned_champion": "pour chaque Champion\nassommé ce tour-ci."
|
|
||||||
},
|
|
||||||
"per_effect":{
|
|
||||||
"damage":"dégats",
|
|
||||||
"heal":"PV",
|
|
||||||
"gold":"$"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+52
-233
@@ -1,12 +1,10 @@
|
|||||||
from math import sin, cos, pi
|
from math import sin, cos, pi
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import drawsvg as dw
|
import drawsvg as dw
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
|
|
||||||
from card_types import Card, Effect, Translation, SkinData
|
from card_types import Card, Effect, Translation
|
||||||
|
|
||||||
stats_radius = 20
|
stats_radius = 20
|
||||||
effect_text_size = 14
|
effect_text_size = 14
|
||||||
@@ -28,7 +26,6 @@ def is_base_effect(effect: Effect):
|
|||||||
def create_icon(
|
def create_icon(
|
||||||
amount: int,
|
amount: int,
|
||||||
fill_circle: str,
|
fill_circle: str,
|
||||||
outline_circle: Optional[str] = None,
|
|
||||||
effect_id: str | None = None,
|
effect_id: str | None = None,
|
||||||
fill_text: str = "black",
|
fill_text: str = "black",
|
||||||
radius: float = stats_radius,
|
radius: float = stats_radius,
|
||||||
@@ -38,9 +35,7 @@ def create_icon(
|
|||||||
else:
|
else:
|
||||||
click_function = js_event_function(effect_id)
|
click_function = js_event_function(effect_id)
|
||||||
group = dw.Group(**{"class": "svg_resource_icon", "v-on:click": click_function})
|
group = dw.Group(**{"class": "svg_resource_icon", "v-on:click": click_function})
|
||||||
if outline_circle:
|
group.append(dw.Circle(cx=0, cy=0, r=radius, fill=fill_circle, x=0, y=0))
|
||||||
group.append(dw.Circle(cx=0, cy=0, r=radius, fill=outline_circle, x=0, y=0))
|
|
||||||
group.append(dw.Circle(cx=0, cy=0, r=radius-2, fill=fill_circle, x=0, y=0))
|
|
||||||
group.append(
|
group.append(
|
||||||
dw.Text(
|
dw.Text(
|
||||||
str(amount),
|
str(amount),
|
||||||
@@ -63,7 +58,6 @@ def create_damage_icon(
|
|||||||
amount,
|
amount,
|
||||||
radius=radius,
|
radius=radius,
|
||||||
fill_circle="red",
|
fill_circle="red",
|
||||||
outline_circle="black",
|
|
||||||
fill_text="white",
|
fill_text="white",
|
||||||
effect_id=effect_id,
|
effect_id=effect_id,
|
||||||
)
|
)
|
||||||
@@ -76,7 +70,6 @@ def create_heal_icon(
|
|||||||
amount,
|
amount,
|
||||||
radius=radius,
|
radius=radius,
|
||||||
fill_circle="green",
|
fill_circle="green",
|
||||||
outline_circle="black",
|
|
||||||
fill_text="white",
|
fill_text="white",
|
||||||
effect_id=effect_id,
|
effect_id=effect_id,
|
||||||
)
|
)
|
||||||
@@ -89,7 +82,6 @@ def create_gold_icon(
|
|||||||
amount,
|
amount,
|
||||||
radius=radius,
|
radius=radius,
|
||||||
fill_circle="yellow",
|
fill_circle="yellow",
|
||||||
outline_circle="goldenrod",
|
|
||||||
effect_id=effect_id,
|
effect_id=effect_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -221,13 +213,7 @@ resourceIcons = {
|
|||||||
# return group
|
# return group
|
||||||
|
|
||||||
|
|
||||||
def create_effect_text(
|
def create_effect_text(effects: list[Effect], height: float, width: int, has_mutex: bool = False):
|
||||||
card: Card,
|
|
||||||
effects: list[Effect],
|
|
||||||
height: float,
|
|
||||||
width: int,
|
|
||||||
has_mutex: bool = False,
|
|
||||||
):
|
|
||||||
group = []
|
group = []
|
||||||
|
|
||||||
effect_text = ""
|
effect_text = ""
|
||||||
@@ -237,15 +223,7 @@ def create_effect_text(
|
|||||||
effect_text += " "
|
effect_text += " "
|
||||||
per = e.get("per")
|
per = e.get("per")
|
||||||
if per is not None:
|
if per is not None:
|
||||||
print(e.get("effect"))
|
translation = f"+ {e.get('amount', '1')} {translation_fr.get('per').get(per)}"
|
||||||
translation = f"+ {e.get('amount', '1')} {translation_fr.get('per_effect').get(e.get('effect'))} {translation_fr.get('per').get(per)}"
|
|
||||||
translation = translation.replace(
|
|
||||||
"%c",
|
|
||||||
translation_fr.get("colors").get(
|
|
||||||
card.get("faction"), card.get("faction")
|
|
||||||
)
|
|
||||||
+ " ",
|
|
||||||
) # FIXME: card color is needed here
|
|
||||||
elif e.get("amount", 1) > 1:
|
elif e.get("amount", 1) > 1:
|
||||||
translation = (
|
translation = (
|
||||||
translation_fr.get("effects")
|
translation_fr.get("effects")
|
||||||
@@ -272,18 +250,6 @@ def create_effect_text(
|
|||||||
if len(effect_text) > 20:
|
if len(effect_text) > 20:
|
||||||
effect_text += "\n"
|
effect_text += "\n"
|
||||||
effect_text += translation
|
effect_text += translation
|
||||||
|
|
||||||
# Handle sub_effects
|
|
||||||
if len(e.get("sub_effects", [])) > 0:
|
|
||||||
effect_text += "\nSi vous le faites, gagnez "
|
|
||||||
for se in e.get("sub_effects"):
|
|
||||||
effect_text += (
|
|
||||||
str(se.get("amount", 1))
|
|
||||||
+ " "
|
|
||||||
+ translation_fr.get("per_effect").get(se.get("effect"))
|
|
||||||
)
|
|
||||||
effect_text += "."
|
|
||||||
|
|
||||||
if has_mutex and i is not len(effects) - 1:
|
if has_mutex and i is not len(effects) - 1:
|
||||||
effect_text += "\nou"
|
effect_text += "\nou"
|
||||||
|
|
||||||
@@ -321,35 +287,8 @@ def create_effect_text(
|
|||||||
|
|
||||||
return group
|
return group
|
||||||
|
|
||||||
def create_arrow():
|
|
||||||
return dw.Lines(7, 10,
|
|
||||||
7, -5,
|
|
||||||
-5, -5,
|
|
||||||
-5, -9,
|
|
||||||
-10, -2,
|
|
||||||
-5, 4,
|
|
||||||
-5, 0,
|
|
||||||
2, 0,
|
|
||||||
2, 10,
|
|
||||||
stroke='black', fill='white', close='true')
|
|
||||||
|
|
||||||
|
def create_effect_row(effects: list[Effect], type: str, height: int, width: int):
|
||||||
def create_faction_icon(faction: str, transform: str = None):
|
|
||||||
if faction == "yellow":
|
|
||||||
return dw.Lines(9, 0,
|
|
||||||
2, -2,
|
|
||||||
0, -5,
|
|
||||||
-2, -2,
|
|
||||||
-9, 0,
|
|
||||||
-2, 2,
|
|
||||||
0, 5,
|
|
||||||
2, 2,
|
|
||||||
stroke='grey', fill='white', close='true', transform=transform)
|
|
||||||
|
|
||||||
|
|
||||||
def create_effect_row(
|
|
||||||
card: Card, effects: list[Effect], type: str, height: int, width: int
|
|
||||||
):
|
|
||||||
group = dw.Group(**{"class": "svg_effect"})
|
group = dw.Group(**{"class": "svg_effect"})
|
||||||
has_icon = False
|
has_icon = False
|
||||||
if type == "faction_combo":
|
if type == "faction_combo":
|
||||||
@@ -359,13 +298,10 @@ def create_effect_row(
|
|||||||
cx=30,
|
cx=30,
|
||||||
cy=height / 2,
|
cy=height / 2,
|
||||||
r=15,
|
r=15,
|
||||||
fill=f'url(#grad2-{card["id"]})',
|
fill="url(#grad2)",
|
||||||
filter="url(#drop-shadow)",
|
filter="url(#drop-shadow)",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
subg = dw.Group(transform=f"translate({30},{height / 2})")
|
|
||||||
subg.append(create_faction_icon(faction="yellow"))
|
|
||||||
group.append(subg)
|
|
||||||
elif type == "suicide":
|
elif type == "suicide":
|
||||||
has_icon = True
|
has_icon = True
|
||||||
group.append(
|
group.append(
|
||||||
@@ -373,34 +309,10 @@ def create_effect_row(
|
|||||||
cx=30,
|
cx=30,
|
||||||
cy=height / 2,
|
cy=height / 2,
|
||||||
r=15,
|
r=15,
|
||||||
fill="url(#gradient_suicide)",
|
fill="black",
|
||||||
filter="url(#drop-shadow)",
|
filter="url(#drop-shadow)",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
group.append(
|
|
||||||
dw.Line(
|
|
||||||
sx=19,
|
|
||||||
sy=(height / 2) - 11,
|
|
||||||
ex=41,
|
|
||||||
ey=(height / 2) + 11,
|
|
||||||
stroke="black",
|
|
||||||
stroke_width=2,
|
|
||||||
stroke_dasharray='3,1',
|
|
||||||
stroke_opacity=0.3,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
group.append(
|
|
||||||
dw.Line(
|
|
||||||
sx=41,
|
|
||||||
sy=(height / 2) - 11,
|
|
||||||
ex=19,
|
|
||||||
ey=(height / 2) + 11,
|
|
||||||
stroke="black",
|
|
||||||
stroke_width=2,
|
|
||||||
stroke_dasharray='3,1',
|
|
||||||
stroke_opacity=0.3,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
elif type == "champion_action":
|
elif type == "champion_action":
|
||||||
has_icon = True
|
has_icon = True
|
||||||
@@ -409,24 +321,10 @@ def create_effect_row(
|
|||||||
cx=30,
|
cx=30,
|
||||||
cy=height / 2,
|
cy=height / 2,
|
||||||
r=15,
|
r=15,
|
||||||
fill="#444444",
|
|
||||||
filter="url(#drop-shadow)",
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
group.append(
|
|
||||||
dw.Circle(
|
|
||||||
cx=30,
|
|
||||||
cy=height / 2,
|
|
||||||
r=13,
|
|
||||||
fill="gray",
|
fill="gray",
|
||||||
filter="url(#drop-shadow)",
|
filter="url(#drop-shadow)",
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
subg = dw.Group(transform=f"translate({30},{height / 2})")
|
|
||||||
subg.append(create_arrow())
|
|
||||||
group.append(subg)
|
|
||||||
effect_with_icons = list(
|
effect_with_icons = list(
|
||||||
filter(lambda x: x.get("effect") in resourceIcons and not x.get("per"), effects)
|
filter(lambda x: x.get("effect") in resourceIcons and not x.get("per"), effects)
|
||||||
)
|
)
|
||||||
@@ -452,7 +350,7 @@ def create_effect_row(
|
|||||||
text_width = width - 70
|
text_width = width - 70
|
||||||
|
|
||||||
is_mutex = False
|
is_mutex = False
|
||||||
if "mutex" in effects[0]:
|
if 'mutex' in effects[0]:
|
||||||
print("mutex exists for a card")
|
print("mutex exists for a card")
|
||||||
is_mutex = True
|
is_mutex = True
|
||||||
|
|
||||||
@@ -462,34 +360,23 @@ def create_effect_row(
|
|||||||
if len(effect_with_icons) > 0:
|
if len(effect_with_icons) > 0:
|
||||||
icon_y_pos = icon_y_pos - 15
|
icon_y_pos = icon_y_pos - 15
|
||||||
group.append(
|
group.append(
|
||||||
dw.Group(
|
dw.Text(
|
||||||
[
|
"ou",
|
||||||
dw.Text(
|
font_size=14,
|
||||||
"ou",
|
x=width / 2,
|
||||||
font_size=14,
|
y=text_y_pos-19,
|
||||||
x=width / 2,
|
text_anchor="middle",
|
||||||
y=text_y_pos - 19,
|
fill="black",
|
||||||
text_anchor="middle",
|
font_family="Helvetica",
|
||||||
fill="black",
|
font_style="italic",
|
||||||
font_family="Helvetica",
|
|
||||||
font_style="italic",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
**{"v-bind:class": f"{{used:used_effects_indexes.length > 0}}"},
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
text_y_pos = text_y_pos + 7
|
text_y_pos = text_y_pos + 7
|
||||||
elif len(effect_with_text) > 1:
|
elif len (effect_with_text) > 1:
|
||||||
has_text_mutex = True
|
has_text_mutex = True
|
||||||
group.append(
|
group.append(
|
||||||
dw.Group(
|
dw.Group(
|
||||||
create_effect_text(
|
create_effect_text(effect_with_text, text_height, text_width, has_mutex=has_text_mutex),
|
||||||
card=card,
|
|
||||||
effects=effect_with_text,
|
|
||||||
height=text_height,
|
|
||||||
width=text_width,
|
|
||||||
has_mutex=has_text_mutex,
|
|
||||||
),
|
|
||||||
transform=f"translate({width / 2},{text_y_pos})",
|
transform=f"translate({width / 2},{text_y_pos})",
|
||||||
**{
|
**{
|
||||||
"class": "svg_effect",
|
"class": "svg_effect",
|
||||||
@@ -498,6 +385,8 @@ def create_effect_row(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
icon_radius = min(height / 3, stats_radius)
|
icon_radius = min(height / 3, stats_radius)
|
||||||
for [i, e] in enumerate(effect_with_icons):
|
for [i, e] in enumerate(effect_with_icons):
|
||||||
@@ -518,27 +407,18 @@ def create_effect_row(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if is_mutex and i != 0:
|
if is_mutex and i!=0:
|
||||||
group.append(
|
group.append(
|
||||||
dw.Group(
|
dw.Text(
|
||||||
[
|
"ou",
|
||||||
dw.Text(
|
# x=(width/2) - ((len(effect_with_icons) - 1) * icon_radius * 1.5) + icon_radius + 10,
|
||||||
"ou",
|
x=(width/2) - ((len(effect_with_icons) - 1) * icon_radius * 1.5) + icon_radius + 10 + ((i-1) * icon_radius * 3),
|
||||||
# x=(width/2) - ((len(effect_with_icons) - 1) * icon_radius * 1.5) + icon_radius + 10,
|
y=icon_y_pos + 3,
|
||||||
x=(width / 2)
|
text_anchor="middle",
|
||||||
- ((len(effect_with_icons) - 1) * icon_radius * 1.5)
|
fill="black",
|
||||||
+ icon_radius
|
font_size=12,
|
||||||
+ 10
|
font_family="Helvetica",
|
||||||
+ ((i - 1) * icon_radius * 3),
|
),
|
||||||
y=icon_y_pos + 3,
|
|
||||||
text_anchor="middle",
|
|
||||||
fill="black",
|
|
||||||
font_size=12,
|
|
||||||
font_family="Helvetica",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
**{"v-bind:class": f"{{used:used_effects_indexes.length > 0}}"},
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return group
|
return group
|
||||||
@@ -567,7 +447,7 @@ def generate_subeffect_index(effect: Effect):
|
|||||||
generate_subeffect_index(e)
|
generate_subeffect_index(e)
|
||||||
|
|
||||||
|
|
||||||
def create_effects(card: Card, effects: list[Effect], height: int, width: int, flavor_text: Optional[str]):
|
def create_effects(effects: list[Effect], height: int, width: int):
|
||||||
for [i, e] in enumerate(effects):
|
for [i, e] in enumerate(effects):
|
||||||
e["index"] = str(i)
|
e["index"] = str(i)
|
||||||
generate_subeffect_index(e)
|
generate_subeffect_index(e)
|
||||||
@@ -583,72 +463,18 @@ def create_effects(card: Card, effects: list[Effect], height: int, width: int, f
|
|||||||
effect_types = list(grouped_effects.keys())
|
effect_types = list(grouped_effects.keys())
|
||||||
|
|
||||||
if len(grouped_effects) == 1:
|
if len(grouped_effects) == 1:
|
||||||
if flavor_text is None:
|
group.append(
|
||||||
group.append(
|
create_effect_row(
|
||||||
create_effect_row(
|
grouped_effects[effect_types[0]], effect_types[0], height, width
|
||||||
card=card,
|
),
|
||||||
effects=grouped_effects[effect_types[0]],
|
)
|
||||||
type=effect_types[0],
|
|
||||||
height=height,
|
|
||||||
width=width,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
group.append(
|
|
||||||
dw.Line(sx=10, sy=90, ex=width - 10, ey=90, stroke="black", stroke_width=1)
|
|
||||||
)
|
|
||||||
group.append(
|
|
||||||
create_effect_row(
|
|
||||||
card=card,
|
|
||||||
effects=grouped_effects[effect_types[0]],
|
|
||||||
type=effect_types[0],
|
|
||||||
height=85,
|
|
||||||
width=width,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
font_width = 0.5
|
|
||||||
line_width = (
|
|
||||||
max(*[len(x) for x in flavor_text.split("\n")], len(flavor_text)) * font_width
|
|
||||||
)
|
|
||||||
# Take width in account
|
|
||||||
font_size = effect_text_size - 1
|
|
||||||
font_size = min(
|
|
||||||
font_size, (font_size * 3) - line_width, font_size * width / (line_width or 1)
|
|
||||||
)
|
|
||||||
# Take height in account
|
|
||||||
font_size = min((height) / (flavor_text.count("\n") or 1), font_size)
|
|
||||||
|
|
||||||
font_size = max(font_size, 11)
|
|
||||||
|
|
||||||
group.append(
|
|
||||||
dw.Group(
|
|
||||||
[
|
|
||||||
dw.Text(
|
|
||||||
text=flavor_text, # TODO: mettre en italique & gris
|
|
||||||
x=0,
|
|
||||||
y=(-font_size / 2) * flavor_text.count("\n"),
|
|
||||||
text_anchor="middle",
|
|
||||||
fill="black",
|
|
||||||
font_size=font_size,
|
|
||||||
font_style="italic",
|
|
||||||
font_family="Helvetica",
|
|
||||||
transform=f"translate({width / 2},{height - 73})"
|
|
||||||
)
|
|
||||||
],
|
|
||||||
transform=f"translate({0},{55})"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if len(grouped_effects) == 2:
|
if len(grouped_effects) == 2:
|
||||||
group.append(
|
group.append(
|
||||||
dw.Line(sx=10, sy=80, ex=width - 10, ey=80, stroke="black", stroke_width=1)
|
dw.Line(sx=10, sy=80, ex=width - 10, ey=80, stroke="black", stroke_width=1)
|
||||||
)
|
)
|
||||||
group.append(
|
group.append(
|
||||||
create_effect_row(
|
create_effect_row(
|
||||||
card=card,
|
grouped_effects[effect_types[0]], effect_types[0], 80, width
|
||||||
effects=grouped_effects[effect_types[0]],
|
|
||||||
type=effect_types[0],
|
|
||||||
height=80,
|
|
||||||
width=width,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -656,11 +482,10 @@ def create_effects(card: Card, effects: list[Effect], height: int, width: int, f
|
|||||||
dw.Group(
|
dw.Group(
|
||||||
[
|
[
|
||||||
create_effect_row(
|
create_effect_row(
|
||||||
card=card,
|
grouped_effects[effect_types[1]],
|
||||||
effects=grouped_effects[effect_types[1]],
|
effect_types[1],
|
||||||
type=effect_types[1],
|
height - 80,
|
||||||
height=height - 80,
|
width,
|
||||||
width=width,
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
transform=f"translate({0},{80})",
|
transform=f"translate({0},{80})",
|
||||||
@@ -676,11 +501,7 @@ def create_effects(card: Card, effects: list[Effect], height: int, width: int, f
|
|||||||
)
|
)
|
||||||
group.append(
|
group.append(
|
||||||
create_effect_row(
|
create_effect_row(
|
||||||
card=card,
|
grouped_effects[effect_types[0]], effect_types[0], 45, width
|
||||||
effects=grouped_effects[effect_types[0]],
|
|
||||||
type=effect_types[0],
|
|
||||||
height=45,
|
|
||||||
width=width,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -688,11 +509,10 @@ def create_effects(card: Card, effects: list[Effect], height: int, width: int, f
|
|||||||
dw.Group(
|
dw.Group(
|
||||||
[
|
[
|
||||||
create_effect_row(
|
create_effect_row(
|
||||||
card=card,
|
grouped_effects[effect_types[1]],
|
||||||
effects=grouped_effects[effect_types[1]],
|
effect_types[1],
|
||||||
type=effect_types[1],
|
45,
|
||||||
height=45,
|
width,
|
||||||
width=width,
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
transform=f"translate({0},{45})",
|
transform=f"translate({0},{45})",
|
||||||
@@ -703,11 +523,10 @@ def create_effects(card: Card, effects: list[Effect], height: int, width: int, f
|
|||||||
dw.Group(
|
dw.Group(
|
||||||
[
|
[
|
||||||
create_effect_row(
|
create_effect_row(
|
||||||
card=card,
|
grouped_effects[effect_types[2]],
|
||||||
effects=grouped_effects[effect_types[2]],
|
effect_types[2],
|
||||||
type=effect_types[2],
|
45,
|
||||||
height=45,
|
width,
|
||||||
width=width,
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
transform=f"translate({0},{90})",
|
transform=f"translate({0},{90})",
|
||||||
|
|||||||
+67
-73
@@ -1,5 +1,3 @@
|
|||||||
import base64
|
|
||||||
|
|
||||||
import drawsvg as dw
|
import drawsvg as dw
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@@ -10,9 +8,9 @@ from draw_functions import create_gold_icon, create_effects, draw_champion_shiel
|
|||||||
from card_types import Card, SkinData, SkinFile, Translation
|
from card_types import Card, SkinData, SkinFile, Translation
|
||||||
|
|
||||||
from drawsvg.drawing import Drawing
|
from drawsvg.drawing import Drawing
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from edit_card import finish_card
|
from edit_card import finish_card
|
||||||
from src.draw_functions import create_faction_icon
|
|
||||||
|
|
||||||
with open("src/data/translation_fr.json", encoding="utf-8") as f:
|
with open("src/data/translation_fr.json", encoding="utf-8") as f:
|
||||||
translation_fr: Translation = json.load(f)
|
translation_fr: Translation = json.load(f)
|
||||||
@@ -27,8 +25,6 @@ for p in Path("src/data/cards-json").glob("*.json"):
|
|||||||
cards.extend(temp)
|
cards.extend(temp)
|
||||||
|
|
||||||
# Params
|
# Params
|
||||||
embedded_images = False
|
|
||||||
|
|
||||||
x_width = 298
|
x_width = 298
|
||||||
y_height = 417
|
y_height = 417
|
||||||
border_width_x = 12
|
border_width_x = 12
|
||||||
@@ -46,7 +42,7 @@ cost_right_offset = 38
|
|||||||
background_colors = {
|
background_colors = {
|
||||||
"blue": "lightblue",
|
"blue": "lightblue",
|
||||||
"red": "lightcoral",
|
"red": "lightcoral",
|
||||||
"yellow": "rgb(247, 227, 175)",
|
"yellow": "rgb(206, 182, 167)",
|
||||||
"green": "lightgreen",
|
"green": "lightgreen",
|
||||||
"base": "lightgrey",
|
"base": "lightgrey",
|
||||||
}
|
}
|
||||||
@@ -61,31 +57,32 @@ gradient_colors = {
|
|||||||
|
|
||||||
icon_colors = {
|
icon_colors = {
|
||||||
"yellow": ["#ff9935", "#ffe744"],
|
"yellow": ["#ff9935", "#ffe744"],
|
||||||
"blue": ["#3399ff", "#aa44ff"],
|
"blue": ["#ff9935", "#ffe744"],
|
||||||
"red": ["#ff99ff", "#ffe744"],
|
"red": ["#ff9935", "#ffe744"],
|
||||||
"green": ["#009935", "#35dd35"],
|
"green": ["#ff9935", "#ffe744"],
|
||||||
"base": ["#8899aa", "#aa9988"],
|
"base": ["#ff9935", "#ffe744"],
|
||||||
}
|
}
|
||||||
|
|
||||||
fullscreen_card_ids = [56, 57, 58, 59, 84, 85]
|
|
||||||
|
|
||||||
|
|
||||||
shadowFilter = dw.Filter(id="drop-shadow")
|
shadowFilter = dw.Filter(id="drop-shadow")
|
||||||
shadowFilter.append(dw.FilterItem("feDropShadow", dx=1, dy=1, stdDeviation=0))
|
shadowFilter.append(dw.FilterItem("feDropShadow", dx=1, dy=1, stdDeviation=0))
|
||||||
# Draw faction icon
|
# Draw faction icon
|
||||||
|
faction_icon = dw.Group(id="faction_icon")
|
||||||
|
faction_icon.append(dw.Circle(cx=1, cy=1, r=20, fill="black", filter=shadowFilter))
|
||||||
|
faction_icon.append(
|
||||||
|
dw.Circle(
|
||||||
|
cx=0,
|
||||||
|
cy=0,
|
||||||
|
r=20,
|
||||||
|
fill="url(#grad2)",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
for card_data in cards:
|
for card_data in cards:
|
||||||
# Get card skin data
|
# Get card skin data
|
||||||
try:
|
try:
|
||||||
card_skin_data = all_skin_data["cards"][str(card_data["id"])]
|
card_skin_data = all_skin_data["cards"][str(card_data["id"])]
|
||||||
|
except KeyError:
|
||||||
if embedded_images:
|
|
||||||
with open(card_skin_data["image_path"].replace("../../", ""), "rb") as img:
|
|
||||||
b64 = base64.b64encode(img.read()).decode()
|
|
||||||
data_uri = f"data:image/png;base64,{b64}"
|
|
||||||
card_skin_data["image_path"] = data_uri
|
|
||||||
except KeyError as e:
|
|
||||||
print(
|
print(
|
||||||
"Missing skin data for card id:", card_data["id"], "using default skin data"
|
"Missing skin data for card id:", card_data["id"], "using default skin data"
|
||||||
)
|
)
|
||||||
@@ -95,9 +92,9 @@ for card_data in cards:
|
|||||||
flavor_text_type=None,
|
flavor_text_type=None,
|
||||||
)
|
)
|
||||||
# Check if card image really exists
|
# Check if card image really exists
|
||||||
# if not Path(card_skin_data["image_path"].replace("../../", "")).absolute().exists():
|
if not Path(card_skin_data["image_path"].replace("../../", "")).absolute().exists():
|
||||||
# print("Missing image for card id: ", card_data["id"], " , using default image")
|
print("Missing image for card id: ", card_data["id"], " , using default image")
|
||||||
# card_skin_data["image_path"] = "../../img/missing.png"
|
card_skin_data["image_path"] = "../../img/missing.png"
|
||||||
# Create a new SVG drawing
|
# Create a new SVG drawing
|
||||||
output_dir = "output/" + all_skin_data["skin_name"]
|
output_dir = "output/" + all_skin_data["skin_name"]
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
@@ -114,20 +111,6 @@ for card_data in cards:
|
|||||||
)
|
)
|
||||||
d.append(shadowFilter)
|
d.append(shadowFilter)
|
||||||
|
|
||||||
faction_icon = dw.Group(id="faction_icon")
|
|
||||||
faction_icon.append(dw.Circle(cx=1, cy=1, r=20, fill="black", filter=shadowFilter))
|
|
||||||
faction_icon.append(
|
|
||||||
dw.Circle(
|
|
||||||
cx=0,
|
|
||||||
cy=0,
|
|
||||||
r=20,
|
|
||||||
fill=f'url(#grad2-{card_data["id"]})',
|
|
||||||
)
|
|
||||||
)
|
|
||||||
faction_icon.append(
|
|
||||||
create_faction_icon("yellow", transform="scale(1.5)"),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Define linear colored gradient
|
# Define linear colored gradient
|
||||||
gradient = dw.LinearGradient(
|
gradient = dw.LinearGradient(
|
||||||
0, 0, 1, 0, gradientUnits="objectBoundingBox", id="grad1"
|
0, 0, 1, 0, gradientUnits="objectBoundingBox", id="grad1"
|
||||||
@@ -138,20 +121,12 @@ for card_data in cards:
|
|||||||
|
|
||||||
# Define linear colored gradient for faction icon
|
# Define linear colored gradient for faction icon
|
||||||
gradient_faction_icon = dw.LinearGradient(
|
gradient_faction_icon = dw.LinearGradient(
|
||||||
0, 1, 0, 0, gradientUnits="objectBoundingBox", id=f'grad2-{card_data["id"]}'
|
0, 1, 0, 0, gradientUnits="objectBoundingBox", id="grad2"
|
||||||
)
|
)
|
||||||
gradient_faction_icon.add_stop(0, icon_colors[card_data["faction"]][0], opacity=1)
|
gradient_faction_icon.add_stop(0, icon_colors[card_data["faction"]][0], opacity=1)
|
||||||
gradient_faction_icon.add_stop(1, icon_colors[card_data["faction"]][1], opacity=1)
|
gradient_faction_icon.add_stop(1, icon_colors[card_data["faction"]][1], opacity=1)
|
||||||
d.append_def(gradient_faction_icon)
|
d.append_def(gradient_faction_icon)
|
||||||
|
|
||||||
# Define linear colored gradient for suicide icon
|
|
||||||
gradient_suicide = dw.LinearGradient(
|
|
||||||
0, 1, 0, 0, gradientUnits="objectBoundingBox", id="gradient_suicide"
|
|
||||||
)
|
|
||||||
gradient_suicide.add_stop(0, "#8a8a8a", opacity=1)
|
|
||||||
gradient_suicide.add_stop(1, "#ddeedd", opacity=1)
|
|
||||||
d.append_def(gradient_suicide)
|
|
||||||
print(card_data)
|
|
||||||
# Draw card background
|
# Draw card background
|
||||||
background = dw.Group(id="background")
|
background = dw.Group(id="background")
|
||||||
background.append(
|
background.append(
|
||||||
@@ -221,14 +196,13 @@ for card_data in cards:
|
|||||||
)
|
)
|
||||||
d.append(title)
|
d.append(title)
|
||||||
|
|
||||||
# Draw faction icon if not a base card
|
# Draw faction icon
|
||||||
if card_data["faction"] != "base":
|
d.append(
|
||||||
d.append(
|
dw.Group(
|
||||||
dw.Group(
|
children=[faction_icon],
|
||||||
children=[faction_icon],
|
transform=f"translate({border_width_x + 23 + 1},{border_width_y - border_upper_offset + 20 + 4 + 1})",
|
||||||
transform=f"translate({border_width_x + 23 + 1},{border_width_y - border_upper_offset + 20 + 4 + 1})",
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
# Draw card cost
|
# Draw card cost
|
||||||
if card_data.get("cost") is not None:
|
if card_data.get("cost") is not None:
|
||||||
d.append(
|
d.append(
|
||||||
@@ -239,22 +213,45 @@ for card_data in cards:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Draw image
|
# Draw image
|
||||||
d.append(dw.Rectangle(x=1, y=65, width=x_width - 2, height=200))
|
image_area_width = x_width - (2 * border_width_x)
|
||||||
image_height = (
|
image_area_height = 200
|
||||||
200
|
d.append(dw.Rectangle(x=1, y=65, width=x_width - 2, height=image_area_height))
|
||||||
if card_data["id"] not in fullscreen_card_ids
|
image = Image.open(card_skin_data['image_path'].replace('../../', ''))
|
||||||
else y_height - 65 - border_width_y
|
image_natural_width, image_natural_height = image.size
|
||||||
)
|
image_ratio = image_natural_width / image_natural_height
|
||||||
d.append(
|
area_ratio = image_area_width / image_area_height
|
||||||
dw.Image(
|
print(image_natural_width)
|
||||||
x=border_width_x,
|
print(image_area_width)
|
||||||
y=65,
|
print(image_ratio)
|
||||||
width=x_width - (border_width_x * 2),
|
print(area_ratio)
|
||||||
height=image_height,
|
if image_ratio > area_ratio:
|
||||||
path=card_skin_data["image_path"],
|
# Wider image
|
||||||
preserveAspectRatio="xMidYMid slice",
|
scale = image_area_height / image_natural_height
|
||||||
)
|
new_width = image_natural_width * scale
|
||||||
|
translate_x = (image_area_width - new_width) / 2
|
||||||
|
transform = f"translate({translate_x}, 0) scale ({scale})"
|
||||||
|
print(transform)
|
||||||
|
else:
|
||||||
|
# Taller image
|
||||||
|
scale = image_area_width / image_natural_width
|
||||||
|
new_height = image_natural_height * scale
|
||||||
|
translate_y = (image_area_height - new_height) / 2
|
||||||
|
transform = f"translate(0, {translate_y}) scale({scale})"
|
||||||
|
|
||||||
|
card_image = dw.Image(
|
||||||
|
x=border_width_x,
|
||||||
|
y=65,
|
||||||
|
width=x_width - (border_width_x * 2),
|
||||||
|
height=200,
|
||||||
|
path=card_skin_data["image_path"],
|
||||||
|
**{
|
||||||
|
"object-fit": "cover",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
card_image.args['transform'] = transform
|
||||||
|
|
||||||
|
d.append(card_image)
|
||||||
d.append(dw.Rectangle(x=2, y=65 - 1, width=border_width_x - 2, height=200 + 2))
|
d.append(dw.Rectangle(x=2, y=65 - 1, width=border_width_x - 2, height=200 + 2))
|
||||||
# d.append(dw.Rectangle(x=0, y=65+1, width=1, height=200+2, fill='white'))
|
# d.append(dw.Rectangle(x=0, y=65+1, width=1, height=200+2, fill='white'))
|
||||||
d.append(
|
d.append(
|
||||||
@@ -269,14 +266,11 @@ for card_data in cards:
|
|||||||
# Draw effects
|
# Draw effects
|
||||||
effects = card_data.get("effects")
|
effects = card_data.get("effects")
|
||||||
if effects is not None:
|
if effects is not None:
|
||||||
effects_height = 265 if card_data["id"] not in fullscreen_card_ids else 220
|
effects = create_effects(effects=effects, height=135, width=x_internal_width)
|
||||||
effects = create_effects(
|
|
||||||
card=card_data, effects=effects, height=135, width=x_internal_width, flavor_text=card_skin_data["flavor_text_bottom"] if "flavor_text_bottom" in card_skin_data.keys() else None
|
|
||||||
)
|
|
||||||
d.append(
|
d.append(
|
||||||
dw.Group(
|
dw.Group(
|
||||||
effects,
|
effects,
|
||||||
transform=f"translate({border_width_x},{effects_height})",
|
transform=f"translate({border_width_x},{265})",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user