2021-09-14 13:04:29 -04:00
|
|
|
importPackage(arkham.project);
|
|
|
|
|
2021-09-07 22:53:27 -04:00
|
|
|
// TODO: should be defined in strange eons somewhere
|
2021-09-08 19:57:42 -04:00
|
|
|
const pack_code = "kyo_player";
|
|
|
|
const cycle_prefix = "42";
|
2021-09-07 22:53:27 -04:00
|
|
|
|
|
|
|
function renameSlot(slot) {
|
|
|
|
if (slot.startsWith('1 ')) {
|
|
|
|
return slot.slice(2);
|
|
|
|
}
|
|
|
|
else if (slot.startsWith('2 ')) {
|
|
|
|
return slot.slice(2) + ' x2';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return slot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-07 23:23:28 -04:00
|
|
|
const tag_replacements = {
|
|
|
|
"<gua>": "[guardian]",
|
|
|
|
"<see>": "[seeker]",
|
|
|
|
"<rog>": "[rogue]",
|
|
|
|
"<mys>": "[mystic]",
|
|
|
|
"<sur>": "[survivor]",
|
2021-09-08 12:42:00 -04:00
|
|
|
"<wil>": "[willpower]",
|
|
|
|
"<int>": "[intellect]",
|
|
|
|
"<com>": "[combat]",
|
2021-09-07 23:23:28 -04:00
|
|
|
"<agi>": "[agility]",
|
|
|
|
"<wild>": "[wild]",
|
|
|
|
"<sku>": "[skull]",
|
|
|
|
"<cul>": "[cultist]",
|
|
|
|
"<tab>": "[tablet]",
|
|
|
|
"<mon>": "[elder_thing]",
|
|
|
|
"<ble>": "[bless]",
|
|
|
|
"<cur>": "[curse]",
|
|
|
|
"<eld>": "[eldersign]",
|
|
|
|
"<ten>": "[auto_fail]",
|
|
|
|
"<act>": "[action]",
|
|
|
|
"<fre>": "[free]",
|
|
|
|
"<rea>": "[reaction]",
|
2021-09-08 23:13:40 -04:00
|
|
|
"<for>": "<b>Forced</b>",
|
2021-09-07 23:23:28 -04:00
|
|
|
"<hau>": "<b>Haunted</b>",
|
|
|
|
"<obj>": "<b>Objective</b>",
|
|
|
|
"<pat>": "Patrol",
|
|
|
|
"<rev>": "<b>Revelation</b>",
|
|
|
|
"<uni>": "{Unique}", // TODO
|
|
|
|
"<per>": "[per_investigator]",
|
|
|
|
"<bul>": "- ",
|
|
|
|
"<squ>": "{Square}", // TODO
|
|
|
|
// TODO
|
|
|
|
"<bultab>": "", // Tab spacing for bullet sections
|
|
|
|
"<t>": "<b><i>", // Trait
|
|
|
|
"</t>": "</i></b>",
|
|
|
|
"<hs>": "", // Horizontal spacer
|
|
|
|
"<lvs>": "", // Large vertical spacer
|
|
|
|
"<vs>": "", // Vertical spacer
|
|
|
|
"<svs>": "", // Small vertical spacer
|
|
|
|
};
|
|
|
|
|
2021-09-07 22:53:27 -04:00
|
|
|
// 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",
|
|
|
|
};
|
|
|
|
|
2021-09-08 13:16:38 -04:00
|
|
|
function int_or_null(inp) {
|
|
|
|
if (inp == 'None') {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else if (inp == 'X') {
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return parseInt(inp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-08 17:12:58 -04:00
|
|
|
function leftPad(str, len, fill) {
|
|
|
|
return fill.repeat(Math.max(len - str.length, 0)) + str;
|
|
|
|
}
|
|
|
|
|
2021-09-08 20:08:36 -04:00
|
|
|
function replaceAll(str, search, replace) {
|
|
|
|
return str.split(search).join(replace);
|
|
|
|
}
|
|
|
|
|
2021-09-14 13:04:29 -04:00
|
|
|
function javaIteratorToJsGenerator(java_iter) {
|
|
|
|
while(java_iter.hasNext()) {
|
|
|
|
yield java_iter.next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function recurseAllChildren(parent) {
|
|
|
|
if (parent == null || !(parent instanceof Member)) {
|
|
|
|
error('missing parent, or parent is not a Member');
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let child in javaIteratorToJsGenerator(parent.iterator())) {
|
|
|
|
if (child.isFolder()) {
|
|
|
|
for (let sub_child in recurseAllChildren(child)) {
|
|
|
|
yield sub_child;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
yield child;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-08 14:22:37 -04:00
|
|
|
function build_card(component) {
|
|
|
|
function substitute_tags(str) {
|
2021-09-08 19:57:20 -04:00
|
|
|
str = str.trim();
|
2021-09-08 20:08:36 -04:00
|
|
|
str = replaceAll(str, "<fullname>", String(component.getName()));
|
2021-09-07 22:53:27 -04:00
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
for (let tag in tag_replacements) {
|
2021-09-08 20:08:36 -04:00
|
|
|
str = replaceAll(str, tag, tag_replacements[tag]);
|
2021-09-08 14:22:37 -04:00
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const code = cycle_prefix + leftPad(String(component.settings.get('CollectionNumber')), 3, '0');
|
2021-09-08 13:26:17 -04:00
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const card_data = {
|
2021-09-08 14:22:37 -04:00
|
|
|
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())),
|
|
|
|
pack_code: pack_code,
|
|
|
|
position: int_or_null(component.settings.get('CollectionNumber')),
|
|
|
|
quantity: 2, // TODO
|
|
|
|
//restrictions: null, // TODO
|
|
|
|
// TODO: should also handle "Victory" field
|
|
|
|
text: substitute_tags(String(
|
|
|
|
component.settings.get('Keywords') + '\n' + component.settings.get('Rules'))),
|
|
|
|
traits: substitute_tags(String(component.settings.get('Traits'))),
|
|
|
|
type_code: card_types[component.getFrontTemplateKey()],
|
|
|
|
xp: int_or_null(component.settings.get('Level')),
|
|
|
|
};
|
2021-09-08 13:03:02 -04:00
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const raw_health = component.settings.get('Stamina');
|
2021-09-08 22:39:13 -04:00
|
|
|
if (raw_health && raw_health != 'None' && raw_health != '-') {
|
2021-09-08 20:08:17 -04:00
|
|
|
card_data.health = int_or_null(raw_health);
|
|
|
|
}
|
2021-09-13 17:39:11 -04:00
|
|
|
const raw_sanity = component.settings.get('Sanity');
|
2021-09-08 22:39:13 -04:00
|
|
|
if (raw_sanity && raw_sanity != 'None' && raw_sanity != '-') {
|
2021-09-08 22:04:49 -04:00
|
|
|
card_data.sanity = int_or_null(raw_sanity);
|
2021-09-08 20:08:17 -04:00
|
|
|
}
|
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const skills = {
|
2021-09-08 14:40:20 -04:00
|
|
|
Agility: 0,
|
|
|
|
Intellect: 0,
|
|
|
|
Combat: 0,
|
|
|
|
Willpower: 0,
|
|
|
|
Wild: 0,
|
|
|
|
};
|
2021-09-13 17:39:11 -04:00
|
|
|
for (let i = 1; i<=6; i++) {
|
|
|
|
const skill_icon = component.settings.get('Skill' + i);
|
2021-09-08 14:40:20 -04:00
|
|
|
if (skill_icon in skills) {
|
|
|
|
skills[skill_icon] += 1;
|
|
|
|
}
|
|
|
|
}
|
2021-09-13 17:39:11 -04:00
|
|
|
for (let skill in skills) {
|
2021-09-08 14:40:20 -04:00
|
|
|
if (skills[skill] > 0) {
|
|
|
|
card_data["skill_" + skill.toLowerCase()] = skills[skill];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const raw_cost = component.settings.get('ResourceCost');
|
2021-09-08 14:22:37 -04:00
|
|
|
if (raw_cost) {
|
|
|
|
card_data.cost = int_or_null(raw_cost);
|
|
|
|
}
|
2021-09-07 23:22:39 -04:00
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const raw_slot = component.settings.get('Slot');
|
2021-09-08 19:48:27 -04:00
|
|
|
if (raw_slot && raw_slot != 'None') {
|
2021-09-08 14:22:37 -04:00
|
|
|
card_data.slot = renameSlot(String(raw_slot));
|
2021-09-13 17:39:11 -04:00
|
|
|
const raw_slot2 = component.settings.get('Slot2');
|
2021-09-08 14:22:37 -04:00
|
|
|
if (raw_slot2 && raw_slot2 != 'None') {
|
2021-09-08 14:57:26 -04:00
|
|
|
card_data.slot += '. ' + renameSlot(String(raw_slot2));
|
2021-09-08 14:22:37 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const subtitle = component.settings.get('Subtitle');
|
2021-09-08 14:22:37 -04:00
|
|
|
if (subtitle && subtitle != '') {
|
2021-09-08 14:46:26 -04:00
|
|
|
card_data.subname = String(subtitle);
|
2021-09-08 14:22:37 -04:00
|
|
|
}
|
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const faction = component.settings.get('CardClass');
|
2021-09-08 22:34:13 -04:00
|
|
|
if (faction) {
|
2021-09-08 22:38:27 -04:00
|
|
|
if (faction == 'Weakness') {
|
|
|
|
card_data.subtype_code = "weakness";
|
|
|
|
}
|
|
|
|
else if (faction == 'Basic Weakness') {
|
|
|
|
card_data.subtype_code = "basicweakness";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
card_data.faction_code = String(faction).toLowerCase();
|
2021-09-13 17:39:11 -04:00
|
|
|
const faction2 = component.settings.get('CardClass2');
|
2021-09-08 22:38:27 -04:00
|
|
|
if (faction2 && faction2 != 'None') {
|
|
|
|
card_data.faction2_code = String(faction2).toLowerCase();
|
|
|
|
}
|
2021-09-08 22:34:13 -04:00
|
|
|
}
|
2021-09-08 14:22:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (card_types[component.getFrontTemplateKey()] == 'enemy') {
|
|
|
|
// TODO: "weakness" or "basicweakness"
|
|
|
|
card_data.subtype_code = "basicweakness";
|
|
|
|
}
|
2021-09-07 22:53:27 -04:00
|
|
|
|
2021-09-08 14:22:37 -04:00
|
|
|
// TODO: parse out some keywords into their own fields
|
2021-09-07 22:53:27 -04:00
|
|
|
|
2021-09-08 21:31:38 -04:00
|
|
|
// order by keys
|
|
|
|
const ordered_card_data = Object.keys(card_data).sort().reduce(
|
|
|
|
function(obj, key) {
|
|
|
|
obj[key] = card_data[key];
|
|
|
|
return obj;
|
|
|
|
},
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
|
|
|
|
return ordered_card_data;
|
2021-09-08 14:22:37 -04:00
|
|
|
}
|
|
|
|
|
2021-09-13 17:39:11 -04:00
|
|
|
const cards = [];
|
2021-09-14 13:04:29 -04:00
|
|
|
for (let member in recurseAllChildren(Eons.getOpenProject())) {
|
|
|
|
try {
|
|
|
|
if (ProjectUtilities.matchExtension(member, "eon")) {
|
|
|
|
printf("Generating JSON for '%s'...\n", member);
|
|
|
|
let component = ResourceKit.getGameComponentFromFile(member.getFile());
|
|
|
|
if (component.getFrontTemplateKey() in card_types) {
|
|
|
|
let card_data = build_card(component);
|
|
|
|
cards.push(card_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (ex) {
|
|
|
|
println(ex);
|
|
|
|
println('Error while processing ' + member.name + ', skipping file');
|
|
|
|
Error.handleUncaught(ex);
|
|
|
|
}
|
2021-09-08 14:22:37 -04:00
|
|
|
}
|
2021-09-08 17:14:14 -04:00
|
|
|
|
|
|
|
cards.sort(function (a, b) {
|
|
|
|
return parseInt(a.code) - parseInt(b.code);
|
|
|
|
});
|
2021-09-08 14:22:37 -04:00
|
|
|
println(JSON.stringify(cards, null, 4));
|