Refactor JSON card generation to allow for more card types
Rather than trying all settings and using what exists, declare what should exist (via calling appropriate functions), per card type
This commit is contained in:
parent
e96795030a
commit
8e3ab9e43e
@ -88,16 +88,6 @@ const tag_replacements = {
|
|||||||
"<svs>": "", // Small vertical spacer
|
"<svs>": "", // Small vertical spacer
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: handle investigator cards
|
|
||||||
const card_types = {
|
|
||||||
"AHLCG-Event-Default": "event",
|
|
||||||
"AHLCG-Skill-Default": "skill",
|
|
||||||
"AHLCG-Asset-Default": "asset",
|
|
||||||
// TODO: actually handle enemy weaknesses
|
|
||||||
"AHLCG-WeaknessEnemy-Default": "enemy",
|
|
||||||
"AHLCG-WeaknessTreachery-Default": "treachery",
|
|
||||||
};
|
|
||||||
|
|
||||||
function int_or_null(inp) {
|
function int_or_null(inp) {
|
||||||
if (inp == 'None') {
|
if (inp == 'None') {
|
||||||
return null;
|
return null;
|
||||||
@ -118,6 +108,8 @@ function replaceAll(str, search, replace) {
|
|||||||
return str.split(search).join(replace);
|
return str.split(search).join(replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function UnsupportedComponentError() {}
|
||||||
|
|
||||||
function build_card(component, pack_code, cycle_prefix, copies) {
|
function build_card(component, pack_code, cycle_prefix, copies) {
|
||||||
function substitute_tags(str) {
|
function substitute_tags(str) {
|
||||||
str = str.trim();
|
str = str.trim();
|
||||||
@ -129,36 +121,54 @@ function build_card(component, pack_code, cycle_prefix, copies) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function common_data() {
|
||||||
const code = cycle_prefix + leftPad(String(component.settings.get('CollectionNumber')), 3, '0');
|
const code = cycle_prefix + leftPad(String(component.settings.get('CollectionNumber')), 3, '0');
|
||||||
|
|
||||||
const card_data = {
|
return {
|
||||||
code: String(code),
|
|
||||||
deck_limit: 2, // TODO: could be derived?
|
|
||||||
flavor: substitute_tags(String(component.settings.get('Flavor'))),
|
|
||||||
illustrator: String(component.settings.get('Artist')),
|
|
||||||
is_unique: component.settings.getBoolean('Unique'),
|
|
||||||
name: substitute_tags(String(component.getName())),
|
name: substitute_tags(String(component.getName())),
|
||||||
pack_code: String(pack_code),
|
pack_code: String(pack_code),
|
||||||
position: int_or_null(component.settings.get('CollectionNumber')),
|
|
||||||
quantity: copies,
|
quantity: copies,
|
||||||
//restrictions: null, // TODO
|
|
||||||
// TODO: should also handle "Victory" field
|
// "Game Text" tab
|
||||||
|
traits: substitute_tags(String(component.settings.get('Traits'))),
|
||||||
text: substitute_tags(String(
|
text: substitute_tags(String(
|
||||||
component.settings.get('Keywords') + '\n' + component.settings.get('Rules'))),
|
component.settings.get('Keywords') + '\n' + component.settings.get('Rules'))),
|
||||||
traits: substitute_tags(String(component.settings.get('Traits'))),
|
flavor: substitute_tags(String(component.settings.get('Flavor'))),
|
||||||
type_code: card_types[component.getFrontTemplateKey()],
|
// TODO: "Victory" field
|
||||||
xp: int_or_null(component.settings.get('Level')),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// "Collection" tab
|
||||||
|
code: String(code),
|
||||||
|
position: int_or_null(component.settings.get('CollectionNumber')),
|
||||||
|
|
||||||
|
// "Portraits" tab
|
||||||
|
illustrator: String(component.settings.get('Artist')),
|
||||||
|
//restrictions: null, // TODO
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_unique() {
|
||||||
|
if (component.settings.getBoolean('Unique')) {
|
||||||
|
return { is_unique: true };
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function health_and_sanity() {
|
||||||
|
const card_data = {};
|
||||||
const raw_health = component.settings.get('Stamina');
|
const raw_health = component.settings.get('Stamina');
|
||||||
if (raw_health && raw_health != 'None' && raw_health != '-') {
|
if (raw_health != 'None' && raw_health != '-') {
|
||||||
card_data.health = int_or_null(raw_health);
|
card_data.health = int_or_null(raw_health);
|
||||||
}
|
}
|
||||||
const raw_sanity = component.settings.get('Sanity');
|
const raw_sanity = component.settings.get('Sanity');
|
||||||
if (raw_sanity && raw_sanity != 'None' && raw_sanity != '-') {
|
if (raw_sanity != 'None' && raw_sanity != '-') {
|
||||||
card_data.sanity = int_or_null(raw_sanity);
|
card_data.sanity = int_or_null(raw_sanity);
|
||||||
}
|
}
|
||||||
|
return card_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function skill_icons() {
|
||||||
|
const card_data = {};
|
||||||
const skills = {
|
const skills = {
|
||||||
Agility: 0,
|
Agility: 0,
|
||||||
Intellect: 0,
|
Intellect: 0,
|
||||||
@ -178,59 +188,166 @@ function build_card(component, pack_code, cycle_prefix, copies) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const raw_cost = component.settings.get('ResourceCost');
|
return card_data;
|
||||||
if (raw_cost) {
|
|
||||||
card_data.cost = int_or_null(raw_cost);
|
|
||||||
}
|
|
||||||
|
|
||||||
const raw_slot = component.settings.get('Slot');
|
|
||||||
if (raw_slot && raw_slot != 'None') {
|
|
||||||
card_data.slot = renameSlot(String(raw_slot));
|
|
||||||
const raw_slot2 = component.settings.get('Slot2');
|
|
||||||
if (raw_slot2 && raw_slot2 != 'None') {
|
|
||||||
card_data.slot += '. ' + renameSlot(String(raw_slot2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const subtitle = component.settings.get('Subtitle');
|
|
||||||
if (subtitle && subtitle != '') {
|
|
||||||
card_data.subname = String(subtitle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function faction() {
|
||||||
const faction = component.settings.get('CardClass');
|
const faction = component.settings.get('CardClass');
|
||||||
if (faction) {
|
|
||||||
if (faction == 'Weakness') {
|
if (faction == 'Weakness') {
|
||||||
card_data.subtype_code = "weakness";
|
return {
|
||||||
}
|
faction_code: "neutral",
|
||||||
else if (faction == 'Basic Weakness') {
|
subtype_code: "weakness",
|
||||||
card_data.subtype_code = "basicweakness";
|
};
|
||||||
}
|
} else if (faction == 'BasicWeakness') {
|
||||||
else {
|
return {
|
||||||
card_data.faction_code = String(faction).toLowerCase();
|
faction_code: "neutral",
|
||||||
|
subtype_code: "basicweakness",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const card_data = { faction_code: String(faction).toLowerCase() };
|
||||||
|
|
||||||
const faction2 = component.settings.get('CardClass2');
|
const faction2 = component.settings.get('CardClass2');
|
||||||
if (faction2 && faction2 != 'None') {
|
if (faction2 && faction2 != 'None') {
|
||||||
card_data.faction2_code = String(faction2).toLowerCase();
|
card_data.faction2_code = String(faction2).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return card_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card_types[component.getFrontTemplateKey()] == 'enemy') {
|
function player_card_common() {
|
||||||
// TODO: "weakness" or "basicweakness"
|
return Object.assign(
|
||||||
card_data.subtype_code = "basicweakness";
|
{
|
||||||
|
deck_limit: 2, // TODO: could be derived?
|
||||||
|
xp: int_or_null(component.settings.get('Level')),
|
||||||
|
},
|
||||||
|
skill_icons(),
|
||||||
|
faction()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse out some keywords into their own fields
|
function cost() {
|
||||||
|
return { cost: int_or_null(component.settings.get('ResourceCost')) };
|
||||||
|
}
|
||||||
|
|
||||||
// order by keys
|
function slots() {
|
||||||
const ordered_card_data = Object.keys(card_data).sort().reduce(
|
const card_data = {};
|
||||||
|
const raw_slot = component.settings.get('Slot');
|
||||||
|
if (raw_slot != 'None') {
|
||||||
|
card_data.slot = renameSlot(String(raw_slot));
|
||||||
|
const raw_slot2 = component.settings.get('Slot2');
|
||||||
|
if (raw_slot2 != 'None') {
|
||||||
|
card_data.slot += '. ' + renameSlot(String(raw_slot2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return card_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function subtitle() {
|
||||||
|
const subtitle = component.settings.get('Subtitle');
|
||||||
|
if (subtitle != '') {
|
||||||
|
return { subname: String(subtitle) };
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function treachery_subtype() {
|
||||||
|
switch (String(component.settings.get('Subtype'))) {
|
||||||
|
// TODO: should "StoryWeakness" be different?
|
||||||
|
case 'StoryWeakness':
|
||||||
|
case 'Weakness':
|
||||||
|
return { subtype_code: "weakness" };
|
||||||
|
case 'BasicWeakness':
|
||||||
|
return { subtype_code: "basicweakness" };
|
||||||
|
default:
|
||||||
|
throw "Unknown Treachery Subtype:" + String(component.settings.get('Subtype'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enemy() {
|
||||||
|
let subtype;
|
||||||
|
switch (component.settings.get('Subtype')) {
|
||||||
|
case "Basic Weakness":
|
||||||
|
subtype = "basicweakness";
|
||||||
|
break;
|
||||||
|
case "Weakness":
|
||||||
|
// TODO: should these be different?
|
||||||
|
case "Investigator Weakness":
|
||||||
|
case "Story Weakness":
|
||||||
|
subtype = "weakness";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
subtype_code: subtype,
|
||||||
|
// TODO: "per investigator" health
|
||||||
|
health: int_or_null(component.settings.get('Health')),
|
||||||
|
horror: int_or_null(component.settings.get('Horror')),
|
||||||
|
attack: int_or_null(component.settings.get('Attack')),
|
||||||
|
damage: int_or_null(component.settings.get('Damage')),
|
||||||
|
damage: int_or_null(component.settings.get('Damage')),
|
||||||
|
evade: int_or_null(component.settings.get('Evade')),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function order_by_keys(card_data) {
|
||||||
|
return Object.keys(card_data).sort().reduce(
|
||||||
function(obj, key) {
|
function(obj, key) {
|
||||||
obj[key] = card_data[key];
|
obj[key] = card_data[key];
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return ordered_card_data;
|
// TODO: parse out some keywords into their own fields
|
||||||
|
|
||||||
|
println(String(component.getFrontTemplateKey()));
|
||||||
|
switch (String(component.getFrontTemplateKey())) {
|
||||||
|
case "AHLCG-Event-Default":
|
||||||
|
return order_by_keys(Object.assign(
|
||||||
|
{ type_code: "event" },
|
||||||
|
common_data(),
|
||||||
|
player_card_common(),
|
||||||
|
cost()
|
||||||
|
));
|
||||||
|
case "AHLCG-Skill-Default":
|
||||||
|
return order_by_keys(Object.assign(
|
||||||
|
{ type_code: "skill" },
|
||||||
|
common_data(),
|
||||||
|
player_card_common()
|
||||||
|
));
|
||||||
|
case "AHLCG-Asset-Default":
|
||||||
|
println("asdf");
|
||||||
|
return order_by_keys(Object.assign(
|
||||||
|
{ type_code: "asset" },
|
||||||
|
common_data(),
|
||||||
|
player_card_common(),
|
||||||
|
cost(),
|
||||||
|
subtitle(),
|
||||||
|
is_unique(),
|
||||||
|
health_and_sanity(),
|
||||||
|
slots()
|
||||||
|
));
|
||||||
|
case "AHLCG-WeaknessEnemy-Default":
|
||||||
|
return order_by_keys(Object.assign(
|
||||||
|
{ type_code: "enemy", },
|
||||||
|
common_data(),
|
||||||
|
is_unique(),
|
||||||
|
enemy()
|
||||||
|
));
|
||||||
|
case "AHLCG-WeaknessTreachery-Default":
|
||||||
|
return order_by_keys(Object.assign(
|
||||||
|
{ type_code: "treachery", },
|
||||||
|
common_data(),
|
||||||
|
treachery_subtype()
|
||||||
|
));
|
||||||
|
default:
|
||||||
|
println("asdfasdfasdf");
|
||||||
|
throw new UnsupportedComponentError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportCard(component, file) {
|
function exportCard(component, file) {
|
||||||
@ -335,10 +452,20 @@ function run() {
|
|||||||
for (let child of children) {
|
for (let child of children) {
|
||||||
try {
|
try {
|
||||||
let component = ResourceKit.getGameComponentFromFile(child.file);
|
let component = ResourceKit.getGameComponentFromFile(child.file);
|
||||||
if (component.getFrontTemplateKey() in card_types) {
|
|
||||||
printf("Generating JSON/PNG for '%s'...\n", child);
|
|
||||||
let copies = copyCount(copies_list, child.baseName);
|
let copies = copyCount(copies_list, child.baseName);
|
||||||
let card_data = build_card(component, pack_code, cycle_prefix, copies);
|
let card_data;
|
||||||
|
try {
|
||||||
|
card_data = build_card(component, pack_code, cycle_prefix, copies);
|
||||||
|
} catch (ex) {
|
||||||
|
println(ex);
|
||||||
|
if (ex instanceof UnsupportedComponentError) {
|
||||||
|
println("Skipping unsupported component: " + component.getName());
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Generating JSON/PNG for '%s'...\n", child);
|
||||||
cards.push(card_data);
|
cards.push(card_data);
|
||||||
|
|
||||||
let export_dir = new File(deck_task.file, 'export');
|
let export_dir = new File(deck_task.file, 'export');
|
||||||
@ -348,7 +475,6 @@ function run() {
|
|||||||
export_dir.mkdir();
|
export_dir.mkdir();
|
||||||
exportCard(component, target_file);
|
exportCard(component, target_file);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
println(ex);
|
println(ex);
|
||||||
println('Error while processing ' + child.name + ', skipping file');
|
println('Error while processing ' + child.name + ', skipping file');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user