Fix appendages parsing to handle multiple appendages

This commit is contained in:
Yaroslav (Ice) Sheremet
2026-02-01 19:02:11 +02:00
parent 119a9ce62c
commit d034ef44cc
3 changed files with 112 additions and 15 deletions

View File

@@ -298,9 +298,86 @@ function decodeSimpleTag(label, tag, descriptions) {
};
}
// Decode a single appendage
function decodeSingleAppendage(appendage) {
const baseDescription = TAG_DESCRIPTIONS.appendages.base[appendage.baseType];
if (!baseDescription) {
return appendage.baseType;
}
// If no modifiers, return base description
if (!appendage.modifiers || appendage.modifiers.length === 0) {
return baseDescription;
}
// Check for modifier
const modifier = appendage.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$/, '');
}
value = value.replace(/{type}/g, singular);
value = value.replace(/{plural}/g, plural.charAt(0).toUpperCase() + plural.slice(1));
return value;
}
return baseDescription;
}
// Decode appendages
function decodeAppendages(appendages) {
// Get base description
// Handle new multi-appendage structure
if (appendages.appendages && Array.isArray(appendages.appendages)) {
const decodedAppendages = appendages.appendages.map((app, index) => {
const decoded = decodeSingleAppendage(app);
// Lowercase the first letter for all items after the first
if (index > 0 && decoded) {
return decoded.charAt(0).toLowerCase() + decoded.slice(1);
}
return decoded;
});
// Combine with commas and "and"
let value;
if (decodedAppendages.length === 1) {
value = decodedAppendages[0];
} else if (decodedAppendages.length === 2) {
value = decodedAppendages.join(' and ');
} else {
const lastAppendage = decodedAppendages.pop();
value = decodedAppendages.join(', ') + ', and ' + lastAppendage;
}
return {
label: 'Appendages',
value: value,
tag: appendages.raw
};
}
// Legacy support for old structure
const baseDescription = TAG_DESCRIPTIONS.appendages.base[appendages.baseType];
if (!baseDescription) {