7th-saga/data/parse-enemies.js
2021-02-21 20:37:37 -08:00

103 lines
2.5 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const {spells} = require('../web/static/spells');
const spellMap = spells.reduce((map, spell) => {
map[spell.name] = spell;
return map;
}, {});
const contents = fs.readFileSync(path.join(__dirname, 'docs', 'enemies.txt'), {
encoding: 'utf8',
});
const pieces = contents.split('*'.repeat(60));
const regexExecOrDie = (regex, piece) => {
const match = regex.exec(piece);
if (!match) {
throw new Error(`piece did not match regex ${regex.toString()} (${piece})`);
}
return match[1];
}
const enemies = [];
let currentEnemy;
for (let i = 0; i < pieces.length; i++) {
const piece = pieces[i].trim();
const match = /^\*(.+?)\s+Exp:\s*(\d+)\s*Gold:\s*(\d+)\s*Class:\s*(\d)/.exec(piece);
if (match) {
console.log('found enemy: ' + match[1]);
currentEnemy = {
name: match[1],
exp: Number(match[2]),
gold: Number(match[3]),
cls: Number(match[4]),
resistance: {},
spells: [],
drops: {},
};
enemies.push(currentEnemy);
} else if (/^Stats/.test(piece)) {
if (!currentEnemy) {
throw new Error('parsing error: no currentEnemy for stats');
}
const normalized = piece
.replace(/^Stats.*/m, '')
.replace(/^-+[-\s]+$/m, '')
.replace(/\s+/g, ' ')
.split(' ')
.filter(Boolean);
for (let j = 0; j < normalized.length; j++) {
const item = normalized[j];
switch (item) {
case 'MaxHP':
currentEnemy.hp = Number(normalized[++j]);
break;
case 'MaxMP':
currentEnemy.mp = Number(normalized[++j]);
break;
case 'Speed':
case 'Guard':
case 'Magic':
case 'Power':
currentEnemy[item.toLowerCase()] = Number(normalized[++j]);
break;
case 'Thunder':
case 'Fire':
case 'Ice':
case 'Vacuum':
case 'Debuff':
currentEnemy.resistance[item.toLowerCase()] = isNaN(Number(normalized[++j])) ?
null :
Number(normalized[j]);
break;
default:
if (spellMap[item]) {
currentEnemy.spells.push(item);
} else if (item !== '(None)') {
try {
const [numerator, denonimator] = normalized[++j].split('/');
currentEnemy.drops[item] = Number(numerator) / Number(denonimator);
} catch (e) {
console.log(e);
console.log(normalized);
console.log(item);
console.log(require('util').inspect(currentEnemy, false, null, true));
throw e;
}
}
break;
}
}
} else {
console.log('piece did not match: ' + piece);
}
}
fs.writeFileSync(path.join(__dirname, 'enemies.json'), JSON.stringify(enemies, null, ' '));