diff --git a/card.svg b/card.svg index a48c712..048c4c5 100644 --- a/card.svg +++ b/card.svg @@ -1,2 +1,2 @@ -Rallier les TroupesAction, Charme455Mobilisez un champion. \ No newline at end of file +CaprisunAction, 20cl126 \ No newline at end of file diff --git a/lancersiz3.png b/img/skins/heron/010.png similarity index 100% rename from lancersiz3.png rename to img/skins/heron/010.png diff --git a/output/heron/010.svg b/output/heron/010.svg new file mode 100644 index 0000000..e9fb420 --- /dev/null +++ b/output/heron/010.svg @@ -0,0 +1,2 @@ + +Rallier les TroupesAction, Charme455Mobilisez un champion. \ No newline at end of file diff --git a/output/heron/013.svg b/output/heron/013.svg new file mode 100644 index 0000000..048c4c5 --- /dev/null +++ b/output/heron/013.svg @@ -0,0 +1,2 @@ + +CaprisunAction, 20cl126 \ No newline at end of file diff --git a/src/actual_card_data.json b/src/actual_card_data.json deleted file mode 100644 index b46b27c..0000000 --- a/src/actual_card_data.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "id": 10, - "role": "market", - "card_type": "action", - "faction": "yellow", - "name": "Rally the Troops", - "cost": 4, - "init_amount": 1, - "effects": [ - { - "effect": "heal", - "amount": 5 - }, - { - "effect": "damage", - "amount": 5 - }, - { - "effect": "prepare", - "amount": 1, - "effect_type": "faction_combo" - } - ] -} \ No newline at end of file diff --git a/src/actual_card_data_2.json b/src/actual_card_data_2.json deleted file mode 100644 index eea91db..0000000 --- a/src/actual_card_data_2.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "id": 13, - "role": "market", - "card_type": "action", - "faction": "yellow", - "name": "Taxation", - "cost": 1, - "init_amount": 3, - "effects": [ - { - "effect": "gold", - "amount": 2 - }, - { - "effect": "heal", - "amount": 6, - "effect_type": "faction_combo" - } - ] -} \ No newline at end of file diff --git a/src/data/cards_data.json b/src/data/cards_data.json new file mode 100644 index 0000000..8a9d32f --- /dev/null +++ b/src/data/cards_data.json @@ -0,0 +1,48 @@ +{ + "cards": [ + { + "id": 13, + "role": "market", + "card_type": "action", + "faction": "yellow", + "name": "Taxation", + "cost": 1, + "init_amount": 3, + "effects": [ + { + "effect": "gold", + "amount": 2 + }, + { + "effect": "heal", + "amount": 6, + "effect_type": "faction_combo" + } + ] + }, + { + "id": 10, + "role": "market", + "card_type": "action", + "faction": "yellow", + "name": "Rally the Troops", + "cost": 4, + "init_amount": 1, + "effects": [ + { + "effect": "heal", + "amount": 5 + }, + { + "effect": "damage", + "amount": 5 + }, + { + "effect": "prepare", + "amount": 1, + "effect_type": "faction_combo" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/card_data.json b/src/data/heron_skin.json similarity index 74% rename from src/card_data.json rename to src/data/heron_skin.json index e2d93a8..5aea6f8 100644 --- a/src/card_data.json +++ b/src/data/heron_skin.json @@ -1,8 +1,9 @@ { + "skin_name": "heron", "10": { "title": "Rallier les Troupes", "type": "Action, Charme", - "image_path": "lancersiz3.png" + "image_path": "img/skins/heron/010.png" }, "13": { "title": "Caprisun", diff --git a/src/generate_cards_mvp.py b/src/generate_cards_mvp.py index 8a63552..f9df416 100644 --- a/src/generate_cards_mvp.py +++ b/src/generate_cards_mvp.py @@ -1,75 +1,12 @@ -# import svgwrite -# from svgwrite import cm, mm, px - -# # Configuration des chemins vers les icônes -# icons = { -# 'degats': 'path/to/damage_icon.svg', -# 'or': 'path/to/gold_icon.svg', -# 'soin': 'path/to/heal_icon.svg' -# } - -# # Configuration des couleurs de fond -# background_colors = { -# 'bleue': 'lightblue', -# 'rouge': 'lightcoral', -# 'jaune': 'lightyellow', -# 'verte': 'lightgreen', -# 'sans': 'white' -# } - -# def generate_card_svg(name, description, color, effects, output_path): -# # Créer un dessin SVG -# dwg = svgwrite.Drawing(output_path, profile='tiny', size=(8*cm, 12*cm)) - -# # Ajouter un rectangle de fond -# dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill=background_colors[color])) - -# # Ajouter le titre de la carte -# dwg.add(dwg.text(name, insert=(0.5*cm, 1*cm), font_size="20px", fill='black')) - -# # Ajouter la description -# dwg.add(dwg.text(description, insert=(0.5*cm, 2*cm), font_size="12px", fill='black')) - -# # Ajouter les effets -# y_offset = 3*cm -# for effect in effects: -# if effect['type'] in icons: -# # Ajouter l'icône -# dwg.add(dwg.image(href=icons[effect['type']], insert=(0.5*cm, y_offset), size=(1*cm, 1*cm))) -# # Ajouter le texte de l'effet -# dwg.add(dwg.text(effect['text'], insert=(2*cm, y_offset + 0.75*cm), font_size="15px", fill='black')) -# else: -# # Ajouter le texte de l'effet sans icône -# dwg.add(dwg.text(effect['text'], insert=(0.5*cm, y_offset + 0.75*cm), font_size="15px", fill='black')) -# y_offset += 2*cm - -# # Sauvegarder le fichier SVG -# dwg.save() - -# # Exemple d'utilisation -# card_info = { -# 'name': 'Niko Incendiaire', -# 'description': 'Action, ghdj;spftgljh.-', -# 'color': 'bleue', -# 'effects': [ -# {'type': 'degats', 'text': '8 Dégâts'}, -# {'type': 'or', 'text': '5 Or'} -# ] -# } - -# output_path = 'niko_incendiaire.svg' -# generate_card_svg(**card_info, output_path=output_path) - -# print('Carte SVG générée avec succès!') - import svgwrite import json from typing import List +import os from draw import draw_effects_resources_for_row -with open('src/card_data.json') as f: +with open('src/data/heron_skin.json') as f: all_skin_data = json.load(f) # Params @@ -107,115 +44,100 @@ icon_colors = { 'yellow': ['#ff9935', '#ffe744'] } -# Load card data from JSON file -with open('src/actual_card_data.json') as f: - card_data = json.load(f) - -card_skin_data = all_skin_data[str(card_data['id'])] +with open('src/data/cards_data.json') as f: + cards: List = json.load(f)['cards'] -# Create a new SVG drawing -dwg = svgwrite.Drawing('card.svg', profile='tiny', size=(str(x_width) + 'px', str(y_height) + 'px')) +for card_data in cards: + # Get card skin data + card_skin_data = all_skin_data[str(card_data['id'])] -# Define linear colored gradient -gradient = dwg.linearGradient(start=(0, 0), end=(1, 0), id="grad1") -gradient.add_stop_color(0, gradient_colors[card_data['faction']], opacity=1) -gradient.add_stop_color(1, gradient_colors[card_data['faction']], opacity=0) -dwg.defs.add(gradient) + # Create a new SVG drawing + output_dir = 'output/' + all_skin_data['skin_name'] + os.makedirs(output_dir, exist_ok=True) + dwg = svgwrite.Drawing('output/' + all_skin_data['skin_name'] + '/' + str(card_data['id']).zfill(3) + '.svg', profile='tiny', size=(str(x_width) + 'px', str(y_height) + 'px')) -# Define linear colored gradient for faction icon -gradient_faction_icon = dwg.linearGradient(start=(0, 1), end=(0, 0), id="grad2") -gradient_faction_icon.add_stop_color(0, icon_colors[card_data['faction']][0], opacity=1) -gradient_faction_icon.add_stop_color(1, icon_colors[card_data['faction']][1], opacity=1) -dwg.defs.add(gradient_faction_icon) + # Define linear colored gradient + gradient = dwg.linearGradient(start=(0, 0), end=(1, 0), id="grad1") + gradient.add_stop_color(0, gradient_colors[card_data['faction']], opacity=1) + gradient.add_stop_color(1, gradient_colors[card_data['faction']], opacity=0) + dwg.defs.add(gradient) -# # Define a drop shadow filter -# filter_shadow = dwg.defs.add(dwg.filter(id='dropShadow')) -# filter_shadow.feGaussianBlur(in_='SourceAlpha', stdDeviation=3) -# filter_shadow.feOffset(dx=3, dy=3, result='offsetblur') -# filter_shadow.feFlood(flood_color='black', flood_opacity=0.5) -# filter_shadow.feComposite(in2='offsetblur', operator='in') -# filter_shadow.feMerge().feMergeNode(in_='SourceGraphic') + # Define linear colored gradient for faction icon + gradient_faction_icon = dwg.linearGradient(start=(0, 1), end=(0, 0), id="grad2") + gradient_faction_icon.add_stop_color(0, icon_colors[card_data['faction']][0], opacity=1) + gradient_faction_icon.add_stop_color(1, icon_colors[card_data['faction']][1], opacity=1) + dwg.defs.add(gradient_faction_icon) -# Draw card background -dwg.add(dwg.rect(insert=(0, 0), size=(str(x_width) + 'px', str(y_height) + 'px'), rx=15, ry=18, fill='black')) -dwg.add(dwg.rect(insert=(border_width_x, border_width_y - border_upper_offset), size=(str(x_width - border_width_x*2) + 'px', str(y_height - border_width_y*2 + border_upper_offset) + 'px'), rx=0, ry=0, fill=background_colors[card_data['faction']])) + # # Define a drop shadow filter + # filter_shadow = dwg.defs.add(dwg.filter(id='dropShadow')) + # filter_shadow.feGaussianBlur(in_='SourceAlpha', stdDeviation=3) + # filter_shadow.feOffset(dx=3, dy=3, result='offsetblur') + # filter_shadow.feFlood(flood_color='black', flood_opacity=0.5) + # filter_shadow.feComposite(in2='offsetblur', operator='in') + # filter_shadow.feMerge().feMergeNode(in_='SourceGraphic') -# Draw title area -# dwg.add(dwg.rect(insert=(0, 0), size=(str(x_width) + 'px', '50px'), fill='white')) -dwg.add(dwg.text(card_skin_data['title'], insert=(x_width/2, title_y_offset + border_width_y - border_upper_offset), text_anchor='middle', fill='black', font_size=str(title_font_size) + 'px', font_weight="bold", font_family='Helvetica')) + # Draw card background + dwg.add(dwg.rect(insert=(0, 0), size=(str(x_width) + 'px', str(y_height) + 'px'), rx=15, ry=18, fill='black')) + dwg.add(dwg.rect(insert=(border_width_x, border_width_y - border_upper_offset), size=(str(x_width - border_width_x*2) + 'px', str(y_height - border_width_y*2 + border_upper_offset) + 'px'), rx=0, ry=0, fill=background_colors[card_data['faction']])) -# Draw type area -dwg.add(dwg.text(card_skin_data['type'], insert=(x_width/2, title_y_offset + title_font_size + 10), text_anchor='middle', fill='black', font_size=str(subtitle_font_size) + 'px', font_family='Helvetica')) + # Draw title area + # dwg.add(dwg.rect(insert=(0, 0), size=(str(x_width) + 'px', '50px'), fill='white')) + dwg.add(dwg.text(card_skin_data['title'], insert=(x_width/2, title_y_offset + border_width_y - border_upper_offset), text_anchor='middle', fill='black', font_size=str(title_font_size) + 'px', font_weight="bold", font_family='Helvetica')) -# Draw faction icon -dwg.add(dwg.circle(center=(border_width_x + 23 + 1, border_width_y - border_upper_offset + 20 + 4 + 1), r=20, fill='black')) -dwg.add(dwg.circle(center=(border_width_x + 23, border_width_y - border_upper_offset + 20 + 4), r=20, fill='url(#grad2)')) -# dwg.add(dwg.image(card_data['faction_icon'], insert=(x_width - 30 - 15, 30 - 15), size=(30, 30))) + # Draw type area + dwg.add(dwg.text(card_skin_data['type'], insert=(x_width/2, title_y_offset + title_font_size + 10), text_anchor='middle', fill='black', font_size=str(subtitle_font_size) + 'px', font_family='Helvetica')) -# Draw cost circle -dwg.add(dwg.circle(center=(x_width - cost_right_offset + 2, 19 + border_width_y + 2), r=21, fill='rgb(202, 129, 25)')) -dwg.add(dwg.circle(center=(x_width - cost_right_offset, 19 + border_width_y), r=20, fill='yellow')) -dwg.add(dwg.text(str(card_data['cost']), insert=(x_width - cost_right_offset, 26 + border_width_y), text_anchor='middle', fill='black', font_size='24px', font_weight="bold", font_family='Helvetica')) + # Draw faction icon + dwg.add(dwg.circle(center=(border_width_x + 23 + 1, border_width_y - border_upper_offset + 20 + 4 + 1), r=20, fill='black')) + dwg.add(dwg.circle(center=(border_width_x + 23, border_width_y - border_upper_offset + 20 + 4), r=20, fill='url(#grad2)')) + # dwg.add(dwg.image(card_data['faction_icon'], insert=(x_width - 30 - 15, 30 - 15), size=(30, 30))) -# Draw image area -dwg.add(dwg.rect(insert=(0, 65), size=(str(x_width) + 'px', '200px'), fill='black')) -dwg.add(dwg.image(card_skin_data['image_path'], insert=(0, 65), size=(x_width, 200))) + # Draw cost circle + dwg.add(dwg.circle(center=(x_width - cost_right_offset + 2, 19 + border_width_y + 2), r=21, fill='rgb(202, 129, 25)')) + dwg.add(dwg.circle(center=(x_width - cost_right_offset, 19 + border_width_y), r=20, fill='yellow')) + dwg.add(dwg.text(str(card_data['cost']), insert=(x_width - cost_right_offset, 26 + border_width_y), text_anchor='middle', fill='black', font_size='24px', font_weight="bold", font_family='Helvetica')) -dwg.add(dwg.rect(insert=(border_width_x, 265), size=(str(30) + 'px', str(y_height - 265 - border_width_y) + 'px'), fill='url(#grad1)')) + # Draw image area + dwg.add(dwg.rect(insert=(0, 65), size=(str(x_width) + 'px', '200px'), fill='black')) + dwg.add(dwg.image(card_skin_data['image_path'], insert=(0, 65), size=(x_width, 200))) -# TODO: figure out nb of effects and adjust row_1_x_offset accordingly -def is_base_effect(array: List): - return not 'effect_type' in array.keys() or array['effect_type'] == 'champion_action' + dwg.add(dwg.rect(insert=(border_width_x, 265), size=(str(30) + 'px', str(y_height - 265 - border_width_y) + 'px'), fill='url(#grad1)')) -card_effects: List = card_data['effects'] -base_effects = list(filter(is_base_effect, card_effects)) -other_effects = list(filter(lambda x: not is_base_effect(x), card_effects)) -# card_effects = card_data['row_1'] -# row_1_nb_effects = len(card_data['row_1'].keys()) + # TODO: figure out nb of effects and adjust row_1_x_offset accordingly + def is_base_effect(array: List): + return not 'effect_type' in array.keys() or array['effect_type'] == 'champion_action' + + card_effects: List = card_data['effects'] + base_effects = list(filter(is_base_effect, card_effects)) + other_effects = list(filter(lambda x: not is_base_effect(x), card_effects)) + # card_effects = card_data['row_1'] + # row_1_nb_effects = len(card_data['row_1'].keys()) -# Draw row 1 stats -# for effect in base_effects: -# if effect.get('effect') == 'damage': -# # if card_effects.get('damage'): -# x_effect_pos = x_width/2 + row_1_x_offset + row_1_x_step*row_1_nb_effects_applied -# dwg.add(dwg.circle(center=(x_effect_pos, row_1_base_y + stats_radius), r=stats_radius, fill='red')) -# dwg.add(dwg.text(str(effect.get('amount')), insert=(x_effect_pos, row_1_base_y + stats_radius + 9), text_anchor='middle', fill='white', font_size='24px', font_weight="bold", font_family='Helvetica')) -# row_1_nb_effects_applied += 1 + # Draw row 1 stats + draw_effects_resources_for_row(dwg, base_effects, row_1_base_y, x_width) -# if effect.get('effect') == 'gold': -# x_effect_pos = x_width/2 + row_1_x_offset + row_1_x_step*row_1_nb_effects_applied -# dwg.add(dwg.circle(center=(x_effect_pos, row_1_base_y + stats_radius), r=stats_radius, fill='yellow')) -# dwg.add(dwg.text(str(effect.get('amount')), insert=(x_effect_pos, row_1_base_y + stats_radius + 9), text_anchor='middle', fill='black', font_size='24px', font_weight="bold", font_family='Helvetica')) -# row_1_nb_effects_applied += 1 + if other_effects: + # Draw row 1 to row 2 separator + dwg.add(dwg.line(start=(0 + row_1_to_2_separator_shorten_by, row_1_to_2_separator_y), end=(x_width - row_1_to_2_separator_shorten_by, row_1_to_2_separator_y), stroke='black', stroke_width=1)) -# if effect.get('effect') == 'heal': -# x_effect_pos = x_width/2 + row_1_x_offset + row_1_x_step*row_1_nb_effects_applied -# dwg.add(dwg.circle(center=(x_effect_pos, row_1_base_y + stats_radius), r=stats_radius, fill='green')) -# dwg.add(dwg.text(str(effect.get('amount')), insert=(x_effect_pos, row_1_base_y + stats_radius + 9), text_anchor='middle', fill='white', font_size='24px', font_weight="bold", font_family='Helvetica')) -# row_1_nb_effects_applied += 1 -draw_effects_resources_for_row(dwg, base_effects, row_1_base_y, x_width) + for effect in other_effects: + # TODO handle case where there is both faction combo and trash can + + if effect.get('effect_type') == 'faction_combo': + row_2_icon_x = border_width_x + 35 + row_2_icon_y = row_2_base_y - 5 + dwg.add(dwg.circle(center=(row_2_icon_x + 1, row_2_icon_y + 1), r=15, fill='black')) + dwg.add(dwg.circle(center=(row_2_icon_x, row_2_icon_y), r=15, fill='url(#grad2)')) + # Draw row 2 stats + draw_effects_resources_for_row(dwg, [effect], row_2_base_y - 25, x_width) + + # Draw row 2 effect text + effect_text_2 = "" + if effect.get('effect') == 'prepare': + effect_text_2 = "Mobilisez un champion." + dwg.add(dwg.text(effect_text_2, insert=(x_width/2, row_2_base_y), text_anchor='middle', fill='black', font_size=str(effect_text_size) + 'px', font_family='Helvetica')) -if other_effects: - # Draw row 1 to row 2 separator - dwg.add(dwg.line(start=(0 + row_1_to_2_separator_shorten_by, row_1_to_2_separator_y), end=(x_width - row_1_to_2_separator_shorten_by, row_1_to_2_separator_y), stroke='black', stroke_width=1)) - -for effect in other_effects: - # TODO handle case where there is both faction combo and trash can - - if effect.get('effect_type') == 'faction_combo': - row_2_icon_x = border_width_x + 35 - row_2_icon_y = row_2_base_y - 5 - dwg.add(dwg.circle(center=(row_2_icon_x + 1, row_2_icon_y + 1), r=15, fill='black')) - dwg.add(dwg.circle(center=(row_2_icon_x, row_2_icon_y), r=15, fill='url(#grad2)')) - # Draw row 2 stats - - # Draw row 2 effect text - effect_text_2 = "" - if effect.get('effect') == 'prepare': - effect_text_2 = "Mobilisez un champion." - dwg.add(dwg.text(effect_text_2, insert=(x_width/2, row_2_base_y), text_anchor='middle', fill='black', font_size=str(effect_text_size) + 'px', font_family='Helvetica')) - -# Save the SVG file -dwg.save() + # Save the SVG file + dwg.save()