Update decoder to use text from spec
This commit is contained in:
221
js/decoder.js
221
js/decoder.js
@@ -1,5 +1,23 @@
|
||||
// Dragon Code V2.6 Decoder - Converts parsed data to human-readable text
|
||||
|
||||
// Import dependencies for Node.js environment only
|
||||
// Browser: scripts loaded via <script> tags define globals automatically
|
||||
// Node.js: need to explicitly require dependencies
|
||||
try {
|
||||
if (typeof module !== 'undefined' && module.exports && typeof require === 'function') {
|
||||
// We're in Node.js (CommonJS environment)
|
||||
if (typeof TAG_DESCRIPTIONS === 'undefined') {
|
||||
TAG_DESCRIPTIONS = require('./tags-data.js').TAG_DESCRIPTIONS;
|
||||
}
|
||||
if (typeof resolveSpeciesCode === 'undefined') {
|
||||
resolveSpeciesCode = require('./species-data.js').resolveSpeciesCode;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Silently ignore - we're likely in a browser environment
|
||||
// where TAG_DESCRIPTIONS and resolveSpeciesCode are already loaded
|
||||
}
|
||||
|
||||
function decodeDragonCode(parsed) {
|
||||
const result = {
|
||||
species: [],
|
||||
@@ -53,15 +71,15 @@ function decodeDragonCode(parsed) {
|
||||
result.abilities.push(decodeBreath(tags.breath));
|
||||
}
|
||||
if (tags.magic) {
|
||||
result.abilities.push(decodeSimpleTag('Magic', tags.magic, TAG_DESCRIPTIONS.magic));
|
||||
result.abilities.push(decodeMagic(tags.magic));
|
||||
}
|
||||
if (tags.psyPower) {
|
||||
result.abilities.push(decodeSimpleTag('Psy-Power', tags.psyPower, TAG_DESCRIPTIONS.psyPower));
|
||||
result.abilities.push(decodePsyPower(tags.psyPower));
|
||||
}
|
||||
|
||||
// Life & Relationships
|
||||
if (tags.nativeLand) {
|
||||
result.life.push(decodeSimpleTag('Native-Land', tags.nativeLand, TAG_DESCRIPTIONS.nativeLand));
|
||||
result.life.push(decodeNativeLand(tags.nativeLand));
|
||||
}
|
||||
if (tags.mating) {
|
||||
result.life.push(decodeMating(tags.mating));
|
||||
@@ -282,42 +300,65 @@ function decodeSimpleTag(label, tag, descriptions) {
|
||||
|
||||
// Decode appendages
|
||||
function decodeAppendages(appendages) {
|
||||
const parts = [];
|
||||
// Get base description
|
||||
const baseDescription = TAG_DESCRIPTIONS.appendages.base[appendages.baseType];
|
||||
|
||||
appendages.parts.forEach(part => {
|
||||
const typeName = TAG_DESCRIPTIONS.appendages.types[part.type] || part.type;
|
||||
if (!baseDescription) {
|
||||
return {
|
||||
label: 'Appendages',
|
||||
value: appendages.baseType,
|
||||
tag: appendages.raw
|
||||
};
|
||||
}
|
||||
|
||||
let description = typeName;
|
||||
// If no modifiers, return base description
|
||||
if (!appendages.modifiers || appendages.modifiers.length === 0) {
|
||||
return {
|
||||
label: 'Appendages',
|
||||
value: baseDescription,
|
||||
tag: appendages.raw
|
||||
};
|
||||
}
|
||||
|
||||
// Handle count
|
||||
if (part.count) {
|
||||
description = `${part.count} ${typeName}`;
|
||||
} else if (part.modifiers.plus > 0) {
|
||||
description = `multiple ${typeName}`;
|
||||
// Check for modifier
|
||||
const modifier = appendages.modifiers[0];
|
||||
const modifierDescription = TAG_DESCRIPTIONS.appendages.modifiers[modifier];
|
||||
|
||||
if (modifierDescription) {
|
||||
// Replace placeholders in modifier description
|
||||
let value = modifierDescription;
|
||||
|
||||
// Determine singular and plural forms
|
||||
let singular = baseDescription.toLowerCase().replace(/^a pair of /, '').replace(/^a /, '');
|
||||
let plural = singular;
|
||||
|
||||
// Handle specific cases
|
||||
if (singular === 'legs' || singular === 'wings' || singular === 'arms') {
|
||||
// already plural
|
||||
} else if (singular === 'head') {
|
||||
plural = 'heads';
|
||||
singular = 'head';
|
||||
} else if (singular === 'tail') {
|
||||
plural = 'tails';
|
||||
singular = 'tail';
|
||||
} else if (singular.endsWith('limbs')) {
|
||||
plural = singular;
|
||||
singular = singular.replace(/s$/, '');
|
||||
}
|
||||
|
||||
// Handle modifiers
|
||||
if (part.modifiers.caret) {
|
||||
description = `retractable ${description}`;
|
||||
}
|
||||
if (part.modifiers.minus > 0) {
|
||||
description = `vestigial ${description}`;
|
||||
}
|
||||
if (part.modifiers.exclaim) {
|
||||
description = `unusual ${description}`;
|
||||
}
|
||||
value = value.replace(/{type}/g, singular);
|
||||
value = value.replace(/{plural}/g, plural.charAt(0).toUpperCase() + plural.slice(1));
|
||||
|
||||
// Add pair for common paired appendages
|
||||
if (['a', 'l', 'w', 'v'].includes(part.type) && !part.count && part.modifiers.plus === 0) {
|
||||
description = `pair of ${typeName}`;
|
||||
}
|
||||
|
||||
parts.push(description);
|
||||
});
|
||||
return {
|
||||
label: 'Appendages',
|
||||
value: value,
|
||||
tag: appendages.raw
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
label: 'Appendages',
|
||||
value: parts.join(', '),
|
||||
value: baseDescription,
|
||||
tag: appendages.raw
|
||||
};
|
||||
}
|
||||
@@ -487,12 +528,16 @@ function decodeMating(mating) {
|
||||
const modifierKey = getModifierString(mating.modifiers);
|
||||
let value = TAG_DESCRIPTIONS.mating[modifierKey] || 'Not specified';
|
||||
|
||||
if (mating.distant) {
|
||||
value += ' (distant from mate)';
|
||||
}
|
||||
|
||||
if (mating.count) {
|
||||
value += `, ${mating.count} mate${mating.count > 1 ? 's' : ''}`;
|
||||
value += ` (${mating.count} mate${mating.count > 1 ? 's' : ''})`;
|
||||
}
|
||||
|
||||
if (mating.separations) {
|
||||
value += `, ${mating.separations} separation${mating.separations > 1 ? 's' : ''}`;
|
||||
value += ` (${mating.separations} separation${mating.separations > 1 ? 's' : ''})`;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -524,22 +569,8 @@ function decodeOffspring(offspring) {
|
||||
|
||||
// Decode money
|
||||
function decodeMoney(money) {
|
||||
const dollarSigns = money.raw.match(/\$/g);
|
||||
const count = dollarSigns ? dollarSigns.length : 0;
|
||||
|
||||
let key = '';
|
||||
if (count === 3) key = '$$$';
|
||||
else if (count === 2) key = '$$';
|
||||
else if (count === 1) key = '$';
|
||||
|
||||
const minusSigns = money.raw.match(/-/g);
|
||||
const minusCount = minusSigns ? minusSigns.length : 0;
|
||||
|
||||
if (minusCount === 3) key = '---';
|
||||
else if (minusCount === 2) key = '--';
|
||||
else if (minusCount === 1) key = '-';
|
||||
|
||||
const value = TAG_DESCRIPTIONS.money[key] || TAG_DESCRIPTIONS.money[''];
|
||||
const modifierKey = getModifierString(money.modifiers);
|
||||
const value = TAG_DESCRIPTIONS.money[modifierKey] || TAG_DESCRIPTIONS.money[''];
|
||||
|
||||
return {
|
||||
label: 'Money',
|
||||
@@ -550,17 +581,30 @@ function decodeMoney(money) {
|
||||
|
||||
// Decode diet
|
||||
function decodeDiet(diet) {
|
||||
const typeNames = diet.types.map(t =>
|
||||
TAG_DESCRIPTIONS.diet.types[t] || t
|
||||
);
|
||||
|
||||
let value = typeNames.join(', ') || 'omnivore';
|
||||
|
||||
const modifierKey = getModifierString(diet.modifiers);
|
||||
const modifierDesc = TAG_DESCRIPTIONS.diet.modifiers[modifierKey];
|
||||
|
||||
let value = '';
|
||||
|
||||
// If we have a modifier description, use it
|
||||
if (modifierDesc) {
|
||||
value = `${modifierDesc} ${value}`;
|
||||
value = modifierDesc;
|
||||
}
|
||||
|
||||
// If we have diet types, add them
|
||||
if (diet.types.length > 0) {
|
||||
const typeNames = diet.types.map(t =>
|
||||
TAG_DESCRIPTIONS.diet.types[t] || t
|
||||
);
|
||||
|
||||
if (value) {
|
||||
value += ' - ' + typeNames.join(', ');
|
||||
} else {
|
||||
value = typeNames.join(', ');
|
||||
}
|
||||
} else if (!value) {
|
||||
// No modifiers and no types - default to normal
|
||||
value = TAG_DESCRIPTIONS.diet.modifiers[''];
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -576,7 +620,9 @@ function decodeTechnology(tech) {
|
||||
let value = TAG_DESCRIPTIONS.technology[modifierKey] || TAG_DESCRIPTIONS.technology[''];
|
||||
|
||||
if (tech.specialist) {
|
||||
value += `, specialist in ${tech.specialist}`;
|
||||
// Remove trailing period if present before adding specialist
|
||||
value = value.replace(/\.$/, '');
|
||||
value += `. Specialist in ${tech.specialist}`;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -586,6 +632,53 @@ function decodeTechnology(tech) {
|
||||
};
|
||||
}
|
||||
|
||||
// Decode native land
|
||||
function decodeNativeLand(nativeLand) {
|
||||
const value = TAG_DESCRIPTIONS.nativeLand[nativeLand.value] || nativeLand.value;
|
||||
|
||||
return {
|
||||
label: 'Native-Land',
|
||||
value: value,
|
||||
tag: nativeLand.raw
|
||||
};
|
||||
}
|
||||
|
||||
// Decode magic
|
||||
function decodeMagic(magic) {
|
||||
const modifierKey = getModifierString(magic.modifiers);
|
||||
let value = TAG_DESCRIPTIONS.magic[modifierKey] || TAG_DESCRIPTIONS.magic[''];
|
||||
|
||||
if (magic.specialist) {
|
||||
// Remove trailing period if present before adding specialist
|
||||
value = value.replace(/\.$/, '');
|
||||
value += `. Specialist in ${magic.specialist}`;
|
||||
}
|
||||
|
||||
return {
|
||||
label: 'Magic',
|
||||
value: value,
|
||||
tag: magic.raw
|
||||
};
|
||||
}
|
||||
|
||||
// Decode psy-power
|
||||
function decodePsyPower(psyPower) {
|
||||
const modifierKey = getModifierString(psyPower.modifiers);
|
||||
let value = TAG_DESCRIPTIONS.psyPower[modifierKey] || TAG_DESCRIPTIONS.psyPower[''];
|
||||
|
||||
if (psyPower.specialist) {
|
||||
// Remove trailing period if present before adding specialist
|
||||
value = value.replace(/\.$/, '');
|
||||
value += `. Specialist in ${psyPower.specialist}`;
|
||||
}
|
||||
|
||||
return {
|
||||
label: 'Psy-Power',
|
||||
value: value,
|
||||
tag: psyPower.raw
|
||||
};
|
||||
}
|
||||
|
||||
// Helper: Convert modifiers object to string key
|
||||
function getModifierString(modifiers) {
|
||||
let key = '';
|
||||
@@ -594,7 +687,7 @@ function getModifierString(modifiers) {
|
||||
if (modifiers.exclaim) {
|
||||
if (modifiers.plus === 3) return '+++!';
|
||||
if (modifiers.minus === 3) return '---!';
|
||||
// Exclamation alone (e.g., S!)
|
||||
// Exclamation alone (e.g., N!, U!)
|
||||
if (modifiers.plus === 0 && modifiers.minus === 0) return '!';
|
||||
}
|
||||
|
||||
@@ -605,9 +698,12 @@ function getModifierString(modifiers) {
|
||||
key = '-'.repeat(modifiers.minus);
|
||||
}
|
||||
|
||||
// Add special modifiers (but not if they're already the key)
|
||||
if (modifiers.question && key !== '!') {
|
||||
key += '?';
|
||||
// Add special modifiers
|
||||
if (modifiers.asterisk && key === '') {
|
||||
key = '*';
|
||||
}
|
||||
if (modifiers.question && key === '') {
|
||||
key = '?';
|
||||
}
|
||||
if (modifiers.tilde && key === '') {
|
||||
key = '~';
|
||||
@@ -618,6 +714,11 @@ function getModifierString(modifiers) {
|
||||
key = '/';
|
||||
}
|
||||
|
||||
// Special case for caret alone (N^)
|
||||
if (modifiers.caret && key === '') {
|
||||
key = '^';
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user