feat: model specialization combat effects
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
: action === 'saveSpecialization' ? 'SPECIALIZATION'
|
||||
: action === 'saveFocus' ? 'FOCUS'
|
||||
: action === 'saveAbility' ? 'CLASS ABILITY'
|
||||
: action === 'saveCombatEffect' ? 'SHARED COMBAT EFFECT'
|
||||
: action === 'saveFocusAbilities' ? 'FOCUS ABILITY SET'
|
||||
: 'TREE NODE'
|
||||
);
|
||||
@@ -79,6 +80,12 @@
|
||||
{ label: 'COOLDOWN · SECONDS', current: specializationRecord?.cooldown_seconds, proposed: proposed.cooldownSeconds },
|
||||
{ label: 'DESCRIPTION', current: specializationRecord?.description, proposed: proposed.description }
|
||||
]
|
||||
: action === 'saveCombatEffect'
|
||||
? [
|
||||
{ label: 'NAME', current: specializationRecord?.name, proposed: proposed.name },
|
||||
{ label: 'SPECIALIZATION', current: specializationRecord?.specialization_id, proposed: proposed.specializationId },
|
||||
{ label: 'DESCRIPTION TEMPLATE', current: specializationRecord?.description_template, proposed: proposed.descriptionTemplate }
|
||||
]
|
||||
: action === 'saveNode'
|
||||
? [
|
||||
{ label: 'NAME', current: specializationRecord?.name, proposed: proposed.name },
|
||||
@@ -102,6 +109,9 @@
|
||||
const currentNodeEffects = $derived((currentSnapshot?.effects ?? []) as any[]);
|
||||
const currentNodeCosts = $derived((currentSnapshot?.costs ?? []) as any[]);
|
||||
const currentRankProfiles = $derived((currentSnapshot?.rankProfiles ?? []) as any[]);
|
||||
const calculationRecord = $derived((currentSnapshot?.record ?? null) as Record<string, unknown> | null);
|
||||
const proposedCalculationStages = $derived((jsonValue(proposed.stagesJson) ?? []) as any[]);
|
||||
const proposedCalculationProfiles = $derived((jsonValue(proposed.profilesJson) ?? []) as any[]);
|
||||
const effectSummary = (effect: any) => {
|
||||
const target = effect.statId || effect.stat_attribute_id || effect.abilityId || effect.ability_id || effect.label || 'CUSTOM EFFECT';
|
||||
const value = effect.value === null || effect.value === undefined || effect.value === '' ? '' : `${effect.value}${effect.unit ? ` ${effect.unit}` : ''}`;
|
||||
@@ -173,7 +183,19 @@
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{:else if module === 'specializations' && ['saveProgression','saveSpecialization','saveFocus','saveAbility','saveFocusAbilities','saveNode'].includes(action)}
|
||||
{:else if module === 'calculations'}
|
||||
<div class="proposal-compare-grid calculation-proposal-preview">
|
||||
<article class="proposal-editor-preview before">
|
||||
<header><span>CURRENT LIVE · {action === 'saveRevision' ? 'CALCULATION REVISION' : 'CALIBRATION CASE'}</span><b>{calculationRecord ? 'BEFORE' : 'NO LIVE RECORD'}</b></header>
|
||||
{#if calculationRecord}<div class="proposal-field-summary"><div><span>NAME</span><strong>{shown(calculationRecord.name)}</strong></div><div><span>STATE</span><strong>{shown(calculationRecord.status)}</strong></div>{#if action === 'saveRevision'}<div><span>STAGES</span><strong>{(currentSnapshot?.stages as any[])?.length ?? 0}</strong></div><div><span>ATTRIBUTE PROFILES</span><strong>{(currentSnapshot?.profiles as any[])?.length ?? 0}</strong></div>{/if}</div>{:else}<div class="proposal-empty-state"><b>NEW {action === 'saveRevision' ? 'CALCULATION REVISION' : 'CALIBRATION CASE'}</b><span>No live registry record will be replaced.</span></div>{/if}
|
||||
</article>
|
||||
<article class="proposal-editor-preview after">
|
||||
<header><span>PROPOSED · {action === 'saveRevision' ? 'CALCULATION REVISION' : 'CALIBRATION CASE'}</span><b>AFTER</b></header>
|
||||
<div class="proposal-field-summary"><div><span>NAME</span><strong>{shown(proposed.name)}</strong></div>{#if action === 'saveRevision'}<div><span>STAGES</span><strong>{proposedCalculationStages.length}</strong></div><div><span>ATTRIBUTE PROFILES</span><strong>{proposedCalculationProfiles.length}</strong></div><div><span>BASE REVISION</span><strong>{shown(proposed.basedOnRevisionId)}</strong></div>{:else}<div><span>STATE</span><strong>{shown(proposed.status)}</strong></div><div><span>MEASURED WEAPON</span><strong>{proposed.selectedWeapon === '1' ? 'SECONDARY' : 'PRIMARY'}</strong></div><div><span>CORE OBSERVATIONS</span><strong>{['bodyHit','criticalBodyHit','headshot','criticalHeadshot','magazineSeconds','reloadSeconds'].filter((field) => proposed[field]).length} / 6</strong></div>{/if}</div>
|
||||
{#if action === 'saveRevision'}<div class="proposal-rank-preview">{#each proposedCalculationStages as stage}<section><header><span>{stage.label}</span><b>{stage.operator?.replaceAll('_',' ').toUpperCase()}</b></header><p>ORDER {stage.displayOrder} · {stage.lockedPosition?.toUpperCase() ?? 'REORDERABLE'}</p></section>{/each}</div>{/if}
|
||||
</article>
|
||||
</div>
|
||||
{:else if module === 'specializations' && ['saveProgression','saveSpecialization','saveFocus','saveAbility','saveCombatEffect','saveFocusAbilities','saveNode'].includes(action)}
|
||||
<div class="proposal-compare-grid specialization-proposal-preview">
|
||||
<article class="proposal-editor-preview before">
|
||||
<header><span>CURRENT LIVE · {specializationKind}</span><b>{specializationRecord ? 'BEFORE' : 'NO LIVE RECORD'}</b></header>
|
||||
@@ -221,9 +243,10 @@
|
||||
<div class="proposal-rank-preview">
|
||||
{#each proposedRanks as rank}
|
||||
<section>
|
||||
<header><span>RANK {rank.rank}</span><b>{rank.effects?.length ?? 0} EFFECTS</b></header>
|
||||
<header><span>RANK {rank.rank}</span><b>{rank.effects?.length ?? 0} STATIC · {rank.combatEffects?.length ?? 0} CONDITIONAL</b></header>
|
||||
<p>{rank.description || 'NO RANK DESCRIPTION'}</p>
|
||||
{#each rank.effects ?? [] as effect}<small>{effectSummary(effect)}</small>{/each}
|
||||
{#each rank.combatEffects ?? [] as effect}<small>{effect.effectId} · {effect.triggerCount} HITS / {effect.triggerWindowSeconds}s · {effect.maxStacks} STACKS · {effect.modifiers?.length ?? 0} MODIFIERS</small>{/each}
|
||||
<small>{Object.entries(rank.costs ?? {}).filter(([, quantity]) => Number(quantity) > 0).map(([resource, quantity]) => `${resource} × ${quantity}`).join(' · ') || 'CREDITS ONLY'}</small>
|
||||
</section>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user