Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BREAKING] option to use the card's set symbol rather than default symbol #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Trademark and copyright Wizards of the Coast 2022. Templates for this project in
* I have included a copy of the font in this repo which tweaks the asterisk symbol to match how it appears in the power / toughness of real cards,
* You can download the original from Wizards' website [here](https://magic.wizards.com/sites/all/themes/wiz_mtg/fonts/Beleren/Beleren2016-Bold.ttf),
* My custom Magic symbols font `NDPMTG.ttf`, included in the repo,
* [Keyrune](https://keyrune.andrewgioia.com/) and [Mana](https://mana.andrewgioia.com/), for the expansion symbol and transform symbols,
* [Mana](https://mana.andrewgioia.com/), for transform symbols,
* Relay Medium and Calibri.
* A standard installation of [Python 3](https://www.python.org/downloads/).

Expand All @@ -31,7 +31,7 @@ Trademark and copyright Wizards of the Coast 2022. Templates for this project in
* **Optional**: Copy the files from `/scripts/utils` to the `Scripts` folder in your Photoshop installation. For me, this was `C:\Program Files\Adobe\Adobe Photoshop CC 2018\Presets\Scripts`. Modify the paths in those files to point to the corresponding files in `/scripts`. This enables the use of a few utility scripts which are handy when making renders manually.

# FAQ
* *I want to change the set symbol to something else.* Head over to https://andrewgioia.github.io/Keyrune/cheatsheet.html - you can use any of these symbols for the set symbol for your cards. Copy the text of the symbol you want on the cheatsheet, then replace the expansion symbol character in quotations at the top of the file with the character you copied.
* *I want to customise the card's set symbol.* By default, the system draws the set symbol from `/scripts/icons/default.svg`, so if you'd like to use a different set symbol for all cards, you should replace this file with your desired one. The system also supports retrieving & using the set symbol for the card you're rendering - in `settings.jsx`, set `use_default_expansion_symbol` to `false`. The expansion symbol may not look 100% correct (as printed on real cards) due to inconsistencies in how set symbols are sized, positioned, and outlined on real cards.
* *I'm getting an error message saying that the Python call failed and `card.json` was not created.* This is a result of the Python command not executing properly on your computer. The error message contains a copy of the command the system attempted - copy this command and try running it from the command line to diagnose the issue. You may need to adjust the Python command defined in `settings.jsx` depending on how your computer's Python installation is configured. The default commands are:
* Windows: `python ...`
* macOS: `/usr/local/bin/python3 ...`
Expand Down
7 changes: 5 additions & 2 deletions scripts/constants.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

var json_file_path = "/scripts/card.json";
var image_file_path = "/scripts/card.jpg";
var icon_directory = "/scripts/icons/";
var default_icon_name = "default";
var dot_svg = ".svg";

// Card classes - finer grained than Scryfall layouts
var normal_class = "normal";
Expand All @@ -21,7 +24,6 @@ var basic_class = "basic";
var planar_class = "planar";
var token_class = "token";


// Layer names
var LayerNames = {
WHITE: "W",
Expand Down Expand Up @@ -91,7 +93,7 @@ var LayerNames = {
TYPE_LINE_ADVENTURE: "Typeline - Adventure",
MANA_COST: "Mana Cost",
MANA_COST_ADVENTURE: "Mana Cost - Adventure",
EXPANSION_SYMBOL: "Expansion Symbol",
EXPANSION_SYMBOL: "Expansion Symbol", // group name
COLOUR_INDICATOR: "Colour Indicator",
POWER_TOUGHNESS: "Power / Toughness",
FLIPSIDE_POWER_TOUGHNESS: "Flipside Power / Toughness",
Expand All @@ -117,6 +119,7 @@ var LayerNames = {
MUTATE_REFERENCE: "Mutate Reference",
PT_REFERENCE: "PT Adjustment Reference",
PT_TOP_REFERENCE: "PT Top Reference",
EXPANSION_REFERENCE: "Expansion Reference",

// planeswalker
FIRST_ABILITY: "First Ability",
Expand Down
33 changes: 24 additions & 9 deletions scripts/get_card_info.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import time
import sys
import json
from urllib import request, parse, error
import os
import sys
import time
from urllib import error, parse, request


def add_meld_info(card_json):
Expand Down Expand Up @@ -30,7 +31,7 @@ def add_meld_info(card_json):
# If the card specifies which set to retrieve the scan from, do that
try:
pipe_idx = card_name.index("$")
card_set = card_name[pipe_idx + 1:]
card_set = card_name[pipe_idx + 1 :]
card_name = card_name[0:pipe_idx]
print(f"Searching Scryfall for: {card_name}, set: {card_set}...", end="", flush=True)
card = request.urlopen(
Expand All @@ -39,17 +40,31 @@ def add_meld_info(card_json):

except ValueError:
print(f"Searching Scryfall for: {card_name}...", end="", flush=True)
card = request.urlopen(
f"https://api.scryfall.com/cards/named?fuzzy={parse.quote(card_name)}"
).read()
card = request.urlopen(f"https://api.scryfall.com/cards/named?fuzzy={parse.quote(card_name)}").read()
except error.HTTPError:
input("\nError occurred while attempting to query Scryfall. Press enter to exit.")

print(" and done! Saving JSON...", end="", flush=True)

card_json = add_meld_info(json.loads(card))
json_dump = json.dumps(card_json)
with open(sys.path[0] + "/card.json", 'w') as f:
with open(sys.path[0] + "/card.json", "w") as f:
json.dump(json_dump, f)

print(" and done!", flush=True)

set_code = card_json["set"].upper()
icons_folder = sys.path[0] + "/icons"
if not os.path.exists(icons_folder):
os.mkdir(icons_folder)
icon_path = icons_folder + f"/{set_code}.svg"
if not os.path.exists(icon_path):
try:
print(f"Searching Scryfall for the icon for the set: {set_code}...", end="", flush=True)
set_info = json.loads(request.urlopen(f"https://api.scryfall.com/sets/{set_code}").read())
request.urlretrieve(set_info["icon_svg_uri"], icon_path)

except error.HTTPError:
input("\nError occurred while attempting to query Scryfall. Press enter to exit.")
print(" and done!", flush=True)
else:
print(f"Icon for the set {set_code} already exists - not going to retrieve from Scryfall again.", flush=True)
66 changes: 61 additions & 5 deletions scripts/helpers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function align(align_type) {
desc.putReference(idnull, ref);
var idUsng = charIDToTypeID("Usng");
var idADSt = charIDToTypeID("ADSt");
var idAdCH = charIDToTypeID(align_type); // align type - "AdCV" for vertical, "AdCH" for horizontal
var idAdCH = charIDToTypeID(align_type);
desc.putEnumerated(idUsng, idADSt, idAdCH);
executeAction(idAlgn, desc, DialogModes.NO);
}
Expand All @@ -122,6 +122,38 @@ function align_horizontal() {
align("AdCH");
}

function align_left() {
/**
* Align the currently active layer to the left of the current selection.
*/

align("AdLf");
}

function align_right() {
/**
* Align the currently active layer to the right of the current selection.
*/

align("AdRg");
}

function align_top() {
/**
* Align the currently active layer to the top of the current selection.
*/

align("AdTp");
}

function align_bottom() {
/**
* Align the currently active layer to the bottom of the current selection.
*/

align("AdBt");
}

function frame_layer(layer, reference_layer) {
/**
* Scale a layer equally to the bounds of a reference layer, then centre the layer vertically and horizontally
Expand Down Expand Up @@ -220,9 +252,9 @@ function disable_active_vector_mask() {
set_active_vector_mask(false);
}

function apply_stroke(stroke_weight, stroke_colour) {
function apply_stroke(stroke_weight, stroke_colour, stroke_type) {
/**
* Applies an outer stroke to the active layer with the specified weight and colour.
* Applies a stroke to the active layer with the specified weight and colour at the specified position.
*/

idsetd = charIDToTypeID("setd");
Expand All @@ -248,7 +280,7 @@ function apply_stroke(stroke_weight, stroke_colour) {
desc610.putBoolean(idenab, true);
var idStyl = charIDToTypeID("Styl");
var idFStl = charIDToTypeID("FStl");
var idInsF = charIDToTypeID("OutF");
var idInsF = charIDToTypeID(stroke_type);
desc610.putEnumerated(idStyl, idFStl, idInsF);
idPntT = charIDToTypeID("PntT");
var idFrFl = charIDToTypeID("FrFl");
Expand Down Expand Up @@ -281,6 +313,30 @@ function apply_stroke(stroke_weight, stroke_colour) {
executeAction(idsetd, desc608, DialogModes.NO);
}

function apply_outer_stroke(stroke_weight, stroke_colour) {
/**
* Applies an outer stroke to the active layer with the specified weight and colour.
*/

apply_stroke(stroke_weight, stroke_colour, "OutF");
}

function apply_inner_stroke(stroke_weight, stroke_colour) {
/**
* Applies an inner stroke to the active layer with the specified weight and colour.
*/

apply_stroke(stroke_weight, stroke_colour, "InsF");
}

function apply_centre_stroke(stroke_weight, stroke_colour) {
/**
* Applies a centre stroke to the active layer with the specified weight and colour.
*/

apply_stroke(stroke_weight, stroke_colour, "CtrF");
}

function save_and_close(file_name, file_path) {
/**
* Saves the current document to the output folder (/out/) as a PNG and closes the document without saving.
Expand Down Expand Up @@ -478,4 +534,4 @@ function insert_scryfall_scan(image_url, file_path) {

var scryfall_scan = retrieve_scryfall_scan(image_url, file_path);
return paste_file_into_new_layer(scryfall_scan);
}
}
1 change: 1 addition & 0 deletions scripts/icons/default.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions scripts/layouts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ var BaseLayout = Class({
* At minimum, the extending class should set this.name, this.oracle_text, this.type_line, and this.mana_cost.
*/

this.set_code = this.scryfall.set;
this.rarity = this.scryfall.rarity;
this.artist = this.scryfall.artist;
this.colour_identity = this.scryfall.color_identity;
Expand Down
33 changes: 20 additions & 13 deletions scripts/templates.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var BaseTemplate = Class({

this.layout = layout;
this.file = file;
this.file_path = file_path;

this.load_template(file_path);

Expand Down Expand Up @@ -75,12 +76,12 @@ var BaseTemplate = Class({

return "";
},
load_template: function (file_path) {
load_template: function () {
/**
* Opens the template's PSD file in Photoshop.
*/

var template_path = file_path + "/templates/" + this.template_file_name() + ".psd"
var template_path = this.file_path + "/templates/" + this.template_file_name() + ".psd"
var template_file = new File(template_path);
try {
app.open(template_file);
Expand Down Expand Up @@ -204,9 +205,11 @@ var ChilliBaseTemplate = Class({
reference_layer = mana_cost,
),
new ExpansionSymbolField(
layer = expansion_symbol,
text_contents = expansion_symbol_character,
layer_group = expansion_symbol,
set_code = this.layout.set_code,
rarity = this.layout.rarity,
file_path = this.file_path,
justification = Justification.RIGHT,
),
new ScaledTextField(
layer = type_line_selected,
Expand All @@ -230,13 +233,13 @@ var ChilliBaseTemplate = Class({
enable_active_layer_mask();
docref.layers.getByName(LayerNames.HOLLOW_CROWN_SHADOW).visible = true;
},
paste_scryfall_scan: function (reference_layer, file_path, rotate) {
paste_scryfall_scan: function (reference_layer, rotate) {
/**
* Downloads the card's scryfall scan, pastes it into the document next to the active layer, and frames it to fill
* the given reference layer. Can optionally rotate the layer by 90 degrees (useful for planar cards).
*/

var layer = insert_scryfall_scan(this.layout.scryfall_scan, file_path);
var layer = insert_scryfall_scan(this.layout.scryfall_scan, this.file_path);
if (rotate === true) {
layer.rotate(90);
}
Expand Down Expand Up @@ -590,9 +593,11 @@ var ExpeditionTemplate = Class({
text_colour = get_text_layer_colour(name),
),
new ExpansionSymbolField(
layer = expansion_symbol,
text_contents = expansion_symbol_character,
layer_group = expansion_symbol,
set_code = this.scryfall.set_code,
rarity = this.layout.rarity,
file_path = this.file_path,
justification = Justification.RIGHT,
),
new ScaledTextField(
layer = type_line,
Expand Down Expand Up @@ -828,9 +833,11 @@ var IxalanTemplate = Class({
text_colour = get_text_layer_colour(name),
),
new ExpansionSymbolField(
layer = expansion_symbol,
text_contents = expansion_symbol_character,
layer_group = expansion_symbol,
set_code = this.scryfall.set_code,
rarity = this.layout.rarity,
file_path = this.file_path,
justification = Justification.CENTER,
),
new TextField(
layer = type_line,
Expand Down Expand Up @@ -1086,7 +1093,7 @@ var SagaTemplate = Class({

// paste scryfall scan
app.activeDocument.activeLayer = app.activeDocument.layers.getByName(LayerNames.TWINS);
this.paste_scryfall_scan(app.activeDocument.layers.getByName(LayerNames.SCRYFALL_SCAN_FRAME), file_path);
this.paste_scryfall_scan(app.activeDocument.layers.getByName(LayerNames.SCRYFALL_SCAN_FRAME));
},
rules_text_and_pt_layers: function (text_and_icons) {
var saga_text_group = text_and_icons.layers.getByName("Saga");
Expand Down Expand Up @@ -1209,7 +1216,7 @@ var PlaneswalkerTemplate = Class({

// paste scryfall scan
app.activeDocument.activeLayer = this.docref.layers.getByName(LayerNames.TEXTBOX);
this.paste_scryfall_scan(app.activeDocument.layers.getByName(LayerNames.SCRYFALL_SCAN_FRAME), file_path);
this.paste_scryfall_scan(app.activeDocument.layers.getByName(LayerNames.SCRYFALL_SCAN_FRAME));
},
enable_frame_layers: function () {
// twins and pt box
Expand Down Expand Up @@ -1317,7 +1324,7 @@ var PlanarTemplate = Class({

// paste scryfall scan
app.activeDocument.activeLayer = docref.layers.getByName(LayerNames.TEXTBOX);
this.paste_scryfall_scan(app.activeDocument.layers.getByName(LayerNames.SCRYFALL_SCAN_FRAME), file_path, true);
this.paste_scryfall_scan(app.activeDocument.layers.getByName(LayerNames.SCRYFALL_SCAN_FRAME), true);
},
enable_frame_layers: function () { },
});
Expand Down
Loading