aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jan.tuomi@eficode.com>2019-07-02 20:46:09 +0300
committerJan Tuomi <jan.tuomi@eficode.com>2019-07-02 20:46:09 +0300
commit5cc965ed427fc1ae1b53da0ea6cf9af4f4525b87 (patch)
tree4ef3d83469459560948a32f5adcd29588ef333fd
Initial commit
-rw-r--r--.gitignore3
-rw-r--r--index.js130
-rw-r--r--package-lock.json13
-rw-r--r--package.json16
4 files changed, 162 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3520bb3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+node_modules/
+out/
+.vscode/
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..7c46c84
--- /dev/null
+++ b/index.js
@@ -0,0 +1,130 @@
+const builder = require('xmlbuilder');
+const fs = require('fs');
+
+const inputFilename = process.argv[2];
+
+if (!inputFilename) {
+ console.log('USAGE: script.js inputfile.json');
+ process.exit(1);
+}
+
+const inputString = fs.readFileSync(inputFilename, { encoding: 'UTF-8' });
+
+const inputData = JSON.parse(inputString);
+
+const printableNumber = n => (n > 0) ? "+" + n : n;
+
+const replaceSpecialValuesInActionText = (text) => {
+ text = text.replace(/\{@hit (\d+?)\}/g, (match, p1) => printableNumber(p1))
+ text = text.replace(/\{@h\}(\d+?)/g, '$1');
+ text = text.replace(/\{@damage (.*?)\}/g, '$1');
+ text = text.replace(/\{@dc (\d+?)\}/g, 'DC $1');
+ text = text.replace(/\{@condition (\w+)\}/g, '$1');
+ text = text.replace(/\{@skill (\w+)\}/g, '$1');
+ text = text.replace(/\{@atk (.+?)\}/g, (match, p1) => {
+ p1 = p1.replace(/mw/g, 'Melee Weapon Attack');
+ p1 = p1.replace(/ms/g, 'Melee Spell Attack');
+ p1 = p1.replace(/rw/g, 'Ranged Weapon Attack');
+ p1 = p1.replace(/rs/g, 'Ranged Spell Attack');
+ p1 = p1.replace(/\,\s*/g, ' or ');
+ return `${p1}:`;
+ });
+ return text;
+};
+
+const xml = builder.create('root')
+ .ele('compendium', { version: '5' })
+
+const parseToXML = (obj) => {
+ const monster = xml.ele('monster');
+
+ monster.ele('name', obj.name)
+ monster.ele('size', obj.size)
+ monster.ele('type', obj.type)
+ monster.ele('source', obj.source)
+ monster.ele('alignment', obj.alignment && obj.alignment.length ? obj.alignment.join('') : null)
+ monster.ele('ac', obj.ac && obj.ac.length ? obj.ac[0].ac : null)
+ monster.ele('hp', `${obj.hp.average} (${obj.hp.formula})`)
+ monster.ele('cr', obj.cr)
+ monster.ele('passive', obj.passive)
+ monster.ele('str', obj.str)
+ monster.ele('dex', obj.dex)
+ monster.ele('con', obj.con)
+ monster.ele('int', obj.int)
+ monster.ele('wis', obj.wis)
+ monster.ele('cha', obj.cha)
+ monster.ele('languages', obj.languages && obj.languages.length
+ ? obj.languages.join(', ')
+ : null
+ );
+ monster.ele('senses', obj.senses && obj.senses.length
+ ? obj.senses.join(', ')
+ : null
+ );
+ monster.ele('immune', obj.immune && obj.immune.length
+ ? obj.immune.join(', ')
+ : null
+ );
+
+ monster.ele('speed', obj.speed && Object.keys(obj.speed).map((key) => {
+ const type = key == 'walk' ? '' : key;
+ return `${type} ${obj.speed[key]} ft.`;
+ }).join(', '));
+
+ monster.ele('save', obj.save && Object.keys(obj.save).map((key) => {
+ return `${type} ${obj.save[key]}`;
+ }).join(', '));
+
+ monster.ele('skill', obj.skill && Object.keys(obj.skill).map((key) => {
+ return `${key} ${obj.skill[key]}`;
+ }).join(', '));
+
+ obj.trait && obj.trait.forEach((trait) => {
+ const e = monster.ele('trait');
+ e.ele('name', trait.name);
+
+ trait.entries.forEach((entry) => {
+ const text = replaceSpecialValuesInActionText(entry);
+ e.ele('text', text);
+ });
+ });
+
+ obj.legendary && obj.legendary.forEach((legendary) => {
+ const e = monster.ele('legendary');
+ e.ele('name', legendary.name);
+
+ legendary.entries.forEach((entry) => {
+ const text = replaceSpecialValuesInActionText(entry);
+ e.ele('text', text);
+ });
+ });
+
+ obj.action && obj.action.forEach((action) => {
+ const e = monster.ele('action');
+ e.ele('name', action.name);
+
+ action.entries.forEach((entry) => {
+ const text = replaceSpecialValuesInActionText(entry);
+ e.ele('text', text);
+ });
+ })
+}
+
+const processInputData = () => {
+ if (inputData.length) { // array
+ inputData.forEach((obj) => {
+ parseToXML(obj);
+ });
+ } else {
+ parseToXML(inputData);
+ }
+}
+
+processInputData();
+
+xml.end({
+ pretty: true,
+ newline: '\n',
+});
+
+console.log(xml.toString());
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..f67cc22
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,13 @@
+{
+ "name": "5eTools-to-DnDAppFile",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "xmlbuilder": {
+ "version": "13.0.2",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
+ "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..a780b54
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "5eTools-to-DnDAppFile",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "bin": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "xmlbuilder": "^13.0.2"
+ }
+}