forked from xziino/ff14-mitigator
Planner: Äquivalenz-Hinweise für fehlende Job-Abilities
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
84064669d3
commit
d585f3be5a
@ -417,6 +417,22 @@
|
|||||||
|
|
||||||
.ability-chip--other-job { opacity: 0.45; }
|
.ability-chip--other-job { opacity: 0.45; }
|
||||||
|
|
||||||
|
/* ── Equivalents hint ────────────────────────────────────────────────────────── */
|
||||||
|
.badge-with-hint {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-equiv-hint {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--red);
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 0 2px;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Folder Sidebar ──────────────────────────────────────────────────────────── */
|
/* ── Folder Sidebar ──────────────────────────────────────────────────────────── */
|
||||||
.folder-section { margin-bottom: 2px; }
|
.folder-section { margin-bottom: 2px; }
|
||||||
|
|
||||||
|
|||||||
@ -354,11 +354,18 @@ function renderMechanicListHtml(plan) {
|
|||||||
const icon = MITIG_ICONS[a.ability] ?? '';
|
const icon = MITIG_ICONS[a.ability] ?? '';
|
||||||
const label = a.job ? `${escHtml(a.job)} · ${escHtml(a.ability)}` : escHtml(a.ability);
|
const label = a.job ? `${escHtml(a.job)} · ${escHtml(a.ability)}` : escHtml(a.ability);
|
||||||
const title = isMissing ? `${escHtml(a.job)} nicht in Jobaufstellung` : '';
|
const title = isMissing ? `${escHtml(a.job)} nicht in Jobaufstellung` : '';
|
||||||
return `<span class="badge badge-assign ${cls}${isMissing ? ' badge-assign--missing-job' : ''}"${title ? ` title="${title}"` : ''}>
|
const suggestions = isMissing ? findEquivSuggestions(a.ability, activeJobSet) : [];
|
||||||
|
const badgeHtml = `<span class="badge badge-assign ${cls}${isMissing ? ' badge-assign--missing-job' : ''}"${title ? ` title="${title}"` : ''}>
|
||||||
${icon ? `<img class="badge-icon" src="${escHtml(icon)}" alt="">` : ''}
|
${icon ? `<img class="badge-icon" src="${escHtml(icon)}" alt="">` : ''}
|
||||||
${label}
|
${label}
|
||||||
<button class="badge-remove" data-mechanic-id="${escHtml(m.id)}" data-ability="${escHtml(a.ability)}" title="Entfernen">×</button>
|
<button class="badge-remove" data-mechanic-id="${escHtml(m.id)}" data-ability="${escHtml(a.ability)}" title="Entfernen">×</button>
|
||||||
</span>`;
|
</span>`;
|
||||||
|
const hintHtml = suggestions.map(s =>
|
||||||
|
`<span class="badge-equiv-hint">→ ${escHtml(s.ability)} (${escHtml(s.job)})?</span>`
|
||||||
|
).join('');
|
||||||
|
return suggestions.length > 0
|
||||||
|
? `<span class="badge-with-hint">${badgeHtml}${hintHtml}</span>`
|
||||||
|
: badgeHtml;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
@ -820,6 +827,29 @@ const MITIG_ICONS = {
|
|||||||
'Improvised Finish': 'assets/icons/mitigation/improvised-finish.png',
|
'Improvised Finish': 'assets/icons/mitigation/improvised-finish.png',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Groups of abilities that are functionally equivalent across different jobs.
|
||||||
|
// Used to suggest replacements when a job is missing from the composition.
|
||||||
|
const ABILITY_EQUIVALENTS = [
|
||||||
|
['Troubadour', 'Tactician', 'Shield Samba'],
|
||||||
|
['Sacred Soil', 'Kerachole'],
|
||||||
|
];
|
||||||
|
|
||||||
|
function findEquivSuggestions(abilityName, activeJobSet) {
|
||||||
|
const group = ABILITY_EQUIVALENTS.find(g => g.includes(abilityName));
|
||||||
|
if (!group) return [];
|
||||||
|
const suggestions = [];
|
||||||
|
for (const equiv of group) {
|
||||||
|
if (equiv === abilityName) continue;
|
||||||
|
for (const job of activeJobSet) {
|
||||||
|
if ((JOB_ABILITIES[job] ?? []).some(a => a.name === equiv)) {
|
||||||
|
suggestions.push({ ability: equiv, job });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
const ASSIGN_ORDER = { debuff: 0, buff: 1, shield: 2 };
|
const ASSIGN_ORDER = { debuff: 0, buff: 1, shield: 2 };
|
||||||
|
|
||||||
function sortedAssignments(assignments) {
|
function sortedAssignments(assignments) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user