feat: add source-owned combat mechanic programs
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import type { SkillCalculation } from '$lib/calculations/skill';
|
||||
|
||||
let {
|
||||
result,
|
||||
abilityNames = {}
|
||||
}: {
|
||||
result: SkillCalculation;
|
||||
abilityNames?: Record<string, string>;
|
||||
} = $props();
|
||||
const number = new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 });
|
||||
</script>
|
||||
|
||||
<article class:incomplete={result.status === 'INSUFFICIENT_DATA'} class="skill-calculation" aria-live="polite">
|
||||
<header>
|
||||
<div><p>SKILL OUTPUT</p><h3>Specialization abilities</h3></div>
|
||||
<b>{result.status === 'OK' ? 'CALCULATED' : 'INSUFFICIENT DATA'}</b>
|
||||
</header>
|
||||
{#if result.status === 'INSUFFICIENT_DATA'}
|
||||
<div class="missing">
|
||||
<strong>Skill calculation unavailable</strong>
|
||||
<span>ISAC requires the following data:</span>
|
||||
<ul>{#each result.missing as item}<li>{item.replaceAll(':', ' · ')}</li>{/each}</ul>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="combined">
|
||||
<span><small>SINGLE-TARGET DPS</small><b>{number.format(result.combined.singleTargetDps)}</b></span>
|
||||
<span><small>ALL-TARGET DPS</small><b>{number.format(result.combined.aggregateDps)}</b></span>
|
||||
<span><small>ENCOUNTER DAMAGE</small><b>{number.format(result.combined.aggregateEncounterDamage)}</b></span>
|
||||
</div>
|
||||
<div class="ability-results">
|
||||
{#each result.abilities as ability}
|
||||
<div class:disabled={!ability.enabled}>
|
||||
<strong>{abilityNames[ability.abilityId] ?? ability.abilityId}</strong>
|
||||
<span>{ability.enabled ? `${ability.activationCount} ACTIVATIONS` : 'OFF'}</span>
|
||||
<small>{number.format(ability.damage.singleTargetDps)} SINGLE DPS</small>
|
||||
<small>{number.format(ability.damage.aggregateDps)} TOTAL DPS</small>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<footer>SKILLS CAN CRIT AND MULTI-SHOT · SKILLS DO NOT HEADSHOT · ENCOUNTER TRIGGERS FOLLOW THE PRIMARY WEAPON TIMELINE</footer>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
.skill-calculation{display:grid;gap:var(--shd-gap-md);padding:var(--shd-gap-md);border:1px solid var(--shd-border);border-top:2px solid var(--shd-info);background:var(--shd-surface)}
|
||||
.skill-calculation.incomplete{border-top-color:var(--shd-danger)}
|
||||
header{display:flex;justify-content:space-between;align-items:start;gap:var(--shd-gap-md)}
|
||||
header p,h3{margin:0}header p{color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:1.1px}h3{text-transform:uppercase;font-size:var(--shd-type-body);letter-spacing:.7px}
|
||||
header>b{padding:5px 7px;border:1px solid var(--shd-info);color:var(--shd-info);font-size:var(--shd-type-telemetry);letter-spacing:.8px}.incomplete header>b{border-color:var(--shd-danger);color:var(--shd-danger)}
|
||||
.combined{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--shd-border)}.combined span{display:grid;gap:4px;padding:9px;border-left:1px solid var(--shd-border)}.combined span:first-child{border-left:0}.combined b{color:var(--shd-info);font-size:20px}
|
||||
small{color:var(--shd-text-muted);font-size:var(--shd-type-telemetry);font-weight:900;letter-spacing:.7px}
|
||||
.ability-results{display:grid;border:1px solid var(--shd-border)}.ability-results>div{display:grid;grid-template-columns:minmax(140px,1fr) repeat(3,auto);gap:var(--shd-gap-sm);padding:7px 8px;border-top:1px solid var(--shd-border);align-items:center}.ability-results>div:first-child{border-top:0}.ability-results>div.disabled{opacity:.55}.ability-results span{color:var(--shd-orange);font-size:var(--shd-type-telemetry);font-weight:900}
|
||||
.missing{display:grid;gap:4px;padding:10px;border:1px solid var(--shd-danger);border-left-width:2px;background:#1d1212;color:var(--shd-text-muted);font-size:var(--shd-type-supporting)}.missing strong{color:var(--shd-danger);text-transform:uppercase}.missing ul{margin:2px 0 0;padding-left:18px}
|
||||
footer{color:var(--shd-text-dim);font-size:var(--shd-type-telemetry);font-weight:800;letter-spacing:.6px}
|
||||
@media(max-width:700px){header,.combined{display:grid;grid-template-columns:1fr}.combined span{border-left:0;border-top:1px solid var(--shd-border)}.combined span:first-child{border-top:0}.ability-results>div{grid-template-columns:1fr 1fr}.ability-results strong{grid-column:1/-1}}
|
||||
</style>
|
||||
Reference in New Issue
Block a user