diff --git a/app.js b/app.js index 4a8f29d..9c2dcb5 100644 --- a/app.js +++ b/app.js @@ -287,14 +287,26 @@ function cloneTotalsWithEffectDelta(totals, effectType, delta) { }; } -function describeMaxRollGain(effect, totals, currentDps, currentSurvivability) { +function calculateMaxRollGain(effect, totals, currentDps, currentSurvivability) { const withMaxRoll = cloneTotalsWithEffectDelta(totals, effect.id, effect.cap); const dpsGain = percentChange(currentDps, calculateDps(withMaxRoll, state.combatStyle)); const survivabilityGain = percentChange(currentSurvivability, calculateSurvivability(withMaxRoll)); const parts = []; if (Math.abs(dpsGain) >= 0.05) parts.push(`+${fmt(dpsGain)}% DPS`); if (Math.abs(survivabilityGain) >= 0.05) parts.push(`+${fmt(survivabilityGain)}% survivability`); - return parts.length ? parts.join(" / ") : "no effect for current style"; + return { + label: parts.length ? parts.join(" / ") : "no effect for current style", + score: Math.max(0, dpsGain, survivabilityGain), + }; +} + +function classifyGain(score, bestScore) { + if (bestScore <= 0 || score <= 0.05) return "gain-low"; + const ratio = score / bestScore; + if (ratio >= 0.75) return "gain-best"; + if (ratio >= 0.4) return "gain-good"; + if (ratio >= 0.15) return "gain-mid"; + return "gain-low"; } function percentChange(from, to) { @@ -333,11 +345,20 @@ function scorePiece(piece, profile, totals) { } function renderEffectTotals(totals, currentDps, currentSurvivability) { - $("#effectTotals").innerHTML = EFFECTS.map((effect) => ` + const gains = EFFECTS.map((effect) => ({ + effect, + gain: calculateMaxRollGain(effect, totals, currentDps, currentSurvivability), + })); + const bestScore = Math.max(...gains.map(({ gain }) => gain.score), 0); + + $("#effectTotals").innerHTML = gains.map(({ effect, gain }) => `
${effect.label} ${fmt(totals.effects[effect.id])}% - Max roll +${effect.cap}%: ${describeMaxRollGain(effect, totals, currentDps, currentSurvivability)} + + Max roll +${effect.cap}% + ${gain.label} +
`).join(""); } diff --git a/styles.css b/styles.css index 1e5dfef..92da8f2 100644 --- a/styles.css +++ b/styles.css @@ -174,6 +174,22 @@ h3 { margin-bottom: 0; } grid-column: 1 / -1; color: var(--muted); } +.max-roll-row { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 0.75rem; + align-items: baseline; +} +.max-roll-row > span { text-align: left; } +.max-roll-row > strong { + text-align: right; + font-size: 0.82rem; + overflow-wrap: anywhere; +} +.gain-best { color: #86efac; } +.gain-good { color: #bef264; } +.gain-mid { color: #fde047; } +.gain-low { color: #f87171; } .section-heading { margin: 1.5rem 0 1rem; } .section-heading p { color: var(--muted); }