small role fix

This commit is contained in:
Akurosia Kamo 2026-06-09 23:04:30 +02:00
parent bcbf14eb81
commit d42bde81f6

View File

@ -150,6 +150,14 @@ function abilityIcon(ability) {
return MITIG_ICONS[ability] ?? actionMetaByName[ability]?.icon ?? '';
}
function actualAbilityIcon(actual) {
const actionId = String(actual?.actionId ?? actual?.extraAbilityGameID ?? '');
return abilityIcon(actual?.ability)
|| (actionId && actionMetaById[actionId]?.icon)
|| actionMetaByName[actual?.name]?.icon
|| '';
}
function abilityShieldText(ability) {
return actionMetaByName[ability]?.shield ?? '';
}
@ -3322,6 +3330,8 @@ function collectActualMitigations(event) {
ability,
name: mitigation.name ?? ability,
sourceJob,
actionId: mitigation.extraAbilityGameID ?? null,
extraAbilityGameID: mitigation.extraAbilityGameID ?? null,
appliedAt: Number.isFinite(Number(mitigation.appliedAt)) ? Number(mitigation.appliedAt) : null,
buffType: mitigation.buffType ?? abilityDefinition(ability)?.buffType ?? 'buff',
});
@ -3336,6 +3346,8 @@ function collectActualCasts(casts, actualFightStart) {
name: cast.name ?? cast.key,
sourceJob: JOB_FROM_TYPE[cast.sourcePlayerType] ?? '',
sourceName: cast.sourceName ?? '',
actionId: cast.extraAbilityGameID ?? null,
extraAbilityGameID: cast.extraAbilityGameID ?? null,
timestamp: Number(cast.timestamp) || 0,
rel: (Number(cast.timestamp) || 0) - actualFightStart,
buffType: cast.buffType ?? abilityDefinition(cast.key ?? cast.name)?.buffType ?? 'buff',
@ -3345,22 +3357,20 @@ function collectActualCasts(casts, actualFightStart) {
function actualMatchesAssignment(actual, assignment) {
if ((actual.ability ?? actual.name) !== assignment.ability) return false;
if (!assignment.job || !actual.sourceJob) return true;
return actual.sourceJob === assignment.job;
if (actual.sourceJob === assignment.job) return true;
return jobCanUseAbility(actual.sourceJob, assignment.ability);
}
function findCastForAssignment(actualCasts, consumedCasts, assignment, plannedStart, mechanicTime) {
function findCastForAssignment(actualCasts, assignment, plannedStart, mechanicTime) {
const durationMs = assignmentDurationSeconds(assignment) * 1000;
const earlyWindow = Math.max(15000, durationMs + 5000);
const lateWindow = Math.max(10000, mechanicTime - plannedStart + 5000);
const candidates = actualCasts
.map((actual, idx) => ({ actual, idx, delta: actual.rel - plannedStart }))
.filter(item => !consumedCasts.has(item.idx))
.filter(item => actualMatchesAssignment(item.actual, assignment))
.filter(item => item.delta >= -earlyWindow && item.delta <= lateWindow)
.sort((a, b) => Math.abs(a.delta) - Math.abs(b.delta));
const match = candidates[0] ?? null;
if (match) consumedCasts.add(match.idx);
return match;
return candidates[0] ?? null;
}
function findActualMechanic(planMechanic, actualEvents, used, actualFightStart) {
@ -3392,7 +3402,6 @@ function findActualMechanic(planMechanic, actualEvents, used, actualFightStart)
function comparePlanToAnalysis(plan, actualEvents, actualFightStart, actualCastEvents = []) {
const usedMechanics = new Set();
const actualCasts = collectActualCasts(actualCastEvents, actualFightStart);
const consumedCasts = new Set();
const rows = [];
const summary = { ok: 0, early: 0, late: 0, missing: 0, extra: 0, unmatched: 0, unknown: 0 };
@ -3409,7 +3418,7 @@ function comparePlanToAnalysis(plan, actualEvents, actualFightStart, actualCastE
const consumedActual = new Set();
const items = planned.map(assignment => {
const plannedStart = Number(assignment.sourceStart ?? assignmentStartMs(mechanic, assignment)) || 0;
const castMatch = findCastForAssignment(actualCasts, consumedCasts, assignment, plannedStart, mechanic.timestamp);
const castMatch = findCastForAssignment(actualCasts, assignment, plannedStart, mechanic.timestamp);
if (!castMatch) {
summary.missing += 1;
return { status: 'missing', assignment };
@ -3497,7 +3506,7 @@ function compareAssignmentChip(assignment, plan) {
}
function compareActualChip(actual, plan, status = 'extra', delta = null, note = '') {
const icon = abilityIcon(actual.ability);
const icon = actualAbilityIcon(actual);
const name = localizedAbilityName(actual.ability, plan);
const deltaHtml = delta == null || status === 'ok' ? '' : `<small>${escHtml(compareDeltaText(delta))}</small>`;
const noteHtml = note ? `<small>${escHtml(note)}</small>` : '';
@ -3753,6 +3762,7 @@ function initCompareModal() {
const json = await res.json();
if (json.reauth) { window.location.href = window.App?.authStartUrl?.() ?? 'auth/start.php'; return; }
if (json.error) throw new Error(json.error);
await ensureActionMetaLoaded();
compareLastPlan = plan;
compareLastResult = comparePlanToAnalysis(plan, json.aoe_events ?? [], Number(fight.startTime) || 0, json.mitigation_casts ?? []);
renderLastCompare();