Files
cards-gen/src/generate_cards_mvp.py
T

250 lines
7.4 KiB
Python

import drawsvg as dw
import json
import os
from typing import cast
from pathlib import Path
from draw_functions import create_gold_icon, create_effects, draw_champion_shield
from card_types import Card, SkinData, SkinFile, Translation
from drawsvg.drawing import Drawing
from edit_card import finish_card
with open("src/data/translation_fr.json", encoding="utf-8") as f:
translation_fr: Translation = json.load(f)
with open("src/data/heron_skin.json", encoding="utf-8") as f:
all_skin_data: SkinFile = json.load(f)
cards: list[Card] = []
for p in Path("src/data/cards").glob("*.json"):
with open(p, encoding="utf-8") as f:
temp: list[Card] = json.load(f)["cards"]
cards.extend(temp)
# Params
x_width = 298
y_height = 417
border_width_x = 12
border_width_y = 17
x_internal_width = x_width - (border_width_x * 2)
border_upper_offset = 5
title_y_offset = 24
title_font_size = 19
title_font_size_small = 16
subtitle_font_size = 13
cost_right_offset = 38
background_colors = {
"blue": "lightblue",
"red": "lightcoral",
"yellow": "rgb(206, 182, 167)",
"green": "lightgreen",
"base": "lightgrey",
}
gradient_colors = {
"red": "red",
"blue": "blue",
"yellow": "yellow",
"green": "green",
"base": "gray",
}
icon_colors = {
"yellow": ["#ff9935", "#ffe744"],
"blue": ["#ff9935", "#ffe744"],
"red": ["#ff9935", "#ffe744"],
"green": ["#ff9935", "#ffe744"],
"base": ["#ff9935", "#ffe744"],
}
shadowFilter = dw.Filter(id="drop-shadow")
shadowFilter.append(dw.FilterItem("feDropShadow", dx=1, dy=1, stdDeviation=0))
# 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:
# Get card skin data
try:
card_skin_data = all_skin_data["cards"][str(card_data["id"])]
except KeyError:
print(
"Missing skin data for card id:", card_data["id"], "using default skin data"
)
card_skin_data = SkinData(
title=card_data["name"],
image_path="../../img/missing.png",
flavor_text_type=None,
)
# Check if card image really exists
if not Path(card_skin_data["image_path"].replace("../../", "")).absolute().exists():
print("Missing image for card id: ", card_data["id"], " , using default image")
card_skin_data["image_path"] = "../../img/missing.png"
# Create a new SVG drawing
output_dir = "output/" + all_skin_data["skin_name"]
os.makedirs(output_dir, exist_ok=True)
d = Drawing(
x_width,
y_height,
id="card" + str(card_data["id"]),
id_prefix=str(card_data.get("id")) + "_",
**{
"class": "card",
"xmlns:v-bind": "https://vuejs.org/guide/essentials/class-and-style.html",
"xmlns:v-on": "https://vuejs.org/guide/essentials/event-handling.html",
},
)
d.append(shadowFilter)
# Define linear colored gradient
gradient = dw.LinearGradient(
0, 0, 1, 0, gradientUnits="objectBoundingBox", id="grad1"
)
gradient.add_stop(0, gradient_colors[card_data["faction"]], opacity=1)
gradient.add_stop(1, gradient_colors[card_data["faction"]], opacity=0)
d.append_def(gradient)
# Define linear colored gradient for faction icon
gradient_faction_icon = dw.LinearGradient(
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(1, icon_colors[card_data["faction"]][1], opacity=1)
d.append_def(gradient_faction_icon)
# Draw card background
background = dw.Group(id="background")
background.append(
dw.Rectangle(
0,
0,
x_width,
y_height,
rx=15,
ry=18,
fill="black",
stroke="white",
stroke_width=1,
)
)
background.append(
dw.Rectangle(
border_width_x,
border_width_y - border_upper_offset,
x_internal_width,
y_height - border_width_y * 2 + border_upper_offset,
rx=0,
ry=0,
fill=background_colors[card_data["faction"]],
)
)
d.append(background)
# Draw title area
# dwg.add(dwg.rect(insert=(0, 0), size=(str(x_width) + 'px', '50px'), fill='white'))
title = dw.Group(id="title")
card_title = card_skin_data["title"]
if len(card_title) > 20:
temp_title_font_size = title_font_size_small
elif len(card_title) > 23:
temp_title_font_size = title_font_size_small - 2
else:
temp_title_font_size = title_font_size
title.append(
dw.Text(
card_title,
x=x_width / 2,
y=title_y_offset + border_width_y - border_upper_offset,
text_anchor="middle",
fill="black",
font_size=temp_title_font_size,
font_weight="bold",
font_family="Helvetica",
)
)
# Draw type area
card_type_text = translation_fr["card_type"].get(
card_data["card_type"], card_data["card_type"]
)
if card_skin_data.get("flavor_text_type") is not None:
card_type_text += ", " + str(card_skin_data["flavor_text_type"])
title.append(
dw.Text(
card_type_text,
font_size=subtitle_font_size,
x=x_width / 2,
y=title_y_offset + title_font_size + 10,
text_anchor="middle",
fill="black",
font_family="Helvetica",
)
)
d.append(title)
# Draw faction icon
d.append(
dw.Group(
children=[faction_icon],
transform=f"translate({border_width_x + 23 + 1},{border_width_y - border_upper_offset + 20 + 4 + 1})",
)
)
# Draw card cost
if card_data.get("cost") is not None:
d.append(
dw.Group(
children=[create_gold_icon(cast(int, card_data.get("cost")))],
transform=f"translate({x_width - cost_right_offset},{19 + border_width_y})",
)
)
# Draw image
d.append(dw.Rectangle(x=1, y=65, width=x_width-2, height=200))
d.append(
dw.Image(
x=0, y=65, width=x_width, height=200, path=card_skin_data["image_path"]
)
)
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=x_width-border_width_x, y=65-1, width=border_width_x-2, height=200+2))
# Draw effects
effects = card_data.get("effects")
if effects is not None:
effects = create_effects(effects=effects, height=135, width=x_internal_width)
d.append(
dw.Group(
effects,
transform=f"translate({border_width_x},{265})",
)
)
# If champion, draw champion shield with defense
if card_data["card_type"] == "champion":
shield = draw_champion_shield(card_data, border_width_x)
d.append(
dw.Group(
shield,
transform=f"translate({x_width-30},{y_height})",
)
)
# Save the SVG file
d.save_svg(
f"output/{all_skin_data['skin_name']}/{str(card_data['id']).zfill(3)}.svg"
)