refactor: remove retired data format support
This commit is contained in:
@@ -3,7 +3,7 @@ import { gameDataIconUrl } from '$lib/server/game-data-icons';
|
||||
import { getSessionUser } from '$lib/server/auth/session';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { migrateLoadoutDraft } from '$lib/builder/loadout';
|
||||
import { parseLoadoutDraft } from '$lib/builder/loadout';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
const validVisibility = new Set(['private', 'unlisted', 'public']);
|
||||
@@ -13,7 +13,7 @@ const slugify = (value: string) => value.toLowerCase().normalize('NFKD')
|
||||
function parseLoadout(raw: FormDataEntryValue | null) {
|
||||
if (typeof raw !== 'string' || raw.length > 250_000) return null;
|
||||
try {
|
||||
return migrateLoadoutDraft(JSON.parse(raw));
|
||||
return parseLoadoutDraft(JSON.parse(raw));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
import { evaluateLoadoutCombat, summarizeLoadout } from '$lib/builder/loadout-combat';
|
||||
import { toast } from '$lib/toast';
|
||||
import {
|
||||
blankRoll, clamp, createDraft, gearBaseStatRange, gearSlots, levelScaledRange, migrateLoadoutDraft, remapRangeValue, scaled, weaponBaseRange,
|
||||
blankRoll, clamp, createDraft, gearBaseStatRange, gearSlots, levelScaledRange, parseLoadoutDraft, remapRangeValue, scaled, weaponBaseRange,
|
||||
type LoadoutDraft, type Roll
|
||||
} from '$lib/builder/loadout';
|
||||
|
||||
let { data, form } = $props();
|
||||
let draft = $state<LoadoutDraft>(untrack(() => migrateLoadoutDraft(data.initialBuild?.loadout) ?? createDraft()));
|
||||
let draft = $state<LoadoutDraft>(untrack(() => parseLoadoutDraft(data.initialBuild?.loadout) ?? createDraft()));
|
||||
let active = $state('gear:Holster');
|
||||
let saved = $state(false);
|
||||
let message = $state('');
|
||||
@@ -138,32 +138,29 @@
|
||||
const selectFocus = (focusId: string) => {
|
||||
const next = allFocuses.find((focus: any) => focus.id === focusId);
|
||||
if (!next) return;
|
||||
const unassigned = [...draft.specialization.unassignedChips];
|
||||
const displaced: LoadoutDraft['chips'][number][] = [];
|
||||
for (let index = 0; index < draft.chips.length; index += 1) {
|
||||
const chip = draft.chips[index];
|
||||
const ability = next.abilities[Math.floor(index / 3)];
|
||||
const definition = data.chipSets.find((item: any) => item.id === chip.setId);
|
||||
if (chip.setId && (!ability || definition?.specialization_ability_id !== ability.id)) {
|
||||
unassigned.push(structuredClone(chip));
|
||||
displaced.push(structuredClone(chip));
|
||||
draft.chips[index] = createDraft().chips[index];
|
||||
}
|
||||
}
|
||||
for (let index = unassigned.length - 1; index >= 0; index -= 1) {
|
||||
const chip = unassigned[index];
|
||||
for (const chip of displaced) {
|
||||
const definition = data.chipSets.find((item: any) => item.id === chip.setId);
|
||||
const abilityIndex = next.abilities.findIndex((ability: any) => ability.id === definition?.specialization_ability_id);
|
||||
if (abilityIndex < 0) continue;
|
||||
const targetIndex = [0, 1, 2].map((slot) => abilityIndex * 3 + slot).find((slot) => !draft.chips[slot].setId);
|
||||
if (targetIndex === undefined) continue;
|
||||
draft.chips[targetIndex] = structuredClone(chip);
|
||||
unassigned.splice(index, 1);
|
||||
}
|
||||
draft.specialization = {
|
||||
...draft.specialization,
|
||||
focusId,
|
||||
nodeRanks: {},
|
||||
effectStates: {},
|
||||
unassignedChips: unassigned
|
||||
effectStates: {}
|
||||
};
|
||||
active = 'specialization:focus';
|
||||
};
|
||||
@@ -304,28 +301,17 @@
|
||||
});
|
||||
onMount(() => {
|
||||
if (data.initialBuild) return;
|
||||
const stored = localStorage.getItem('shd-build-loadout-draft-v2') ?? localStorage.getItem('shd-build-loadout-draft-v1');
|
||||
const stored = localStorage.getItem('shd-build-loadout-draft-v2');
|
||||
if (!stored) return;
|
||||
try {
|
||||
const parsed = migrateLoadoutDraft(JSON.parse(stored));
|
||||
const parsed = parseLoadoutDraft(JSON.parse(stored));
|
||||
if (parsed) {
|
||||
draft = parsed;
|
||||
for (const slot of gearSlots) {
|
||||
if (!Number.isInteger(draft.gear[slot].level)) draft.gear[slot].level = 50;
|
||||
const item = gearItem(slot), core = coreAllocationRange(Number(item?.tier ?? 0), draft.gear[slot].level, 'gear');
|
||||
for (const key of coreKeys) if (!Number.isFinite(draft.gear[slot][key])) draft.gear[slot][key] = core.min;
|
||||
draft.gear[slot].rolls = [...(draft.gear[slot].rolls ?? []).slice(0, 2), blankRoll(), blankRoll()].slice(0, 2) as [Roll, Roll];
|
||||
}
|
||||
for (const weapon of draft.weapons) {
|
||||
if (!Number.isInteger(weapon.level)) weapon.level = 50;
|
||||
weapon.rolls = [...(weapon.rolls ?? []).slice(0, 2), blankRoll(), blankRoll()].slice(0, 2) as [Roll, Roll];
|
||||
}
|
||||
if (weaponItem(0) && weaponItem(1) && Number(weaponItem(0).is_exotic) && Number(weaponItem(1).is_exotic)) draft.weapons[1].itemId = '';
|
||||
saved = true;
|
||||
}
|
||||
} else localStorage.removeItem('shd-build-loadout-draft-v2');
|
||||
} catch {
|
||||
localStorage.removeItem('shd-build-loadout-draft-v2');
|
||||
localStorage.removeItem('shd-build-loadout-draft-v1');
|
||||
}
|
||||
});
|
||||
$effect(() => {
|
||||
@@ -342,7 +328,6 @@
|
||||
});
|
||||
function saveDraft() {
|
||||
localStorage.setItem('shd-build-loadout-draft-v2', JSON.stringify(draft));
|
||||
localStorage.removeItem('shd-build-loadout-draft-v1');
|
||||
saved = true;
|
||||
toast.success('Draft saved locally', 'This loadout is available on this device.');
|
||||
}
|
||||
@@ -397,9 +382,6 @@
|
||||
{#if activeParts[0] === 'specialization'}
|
||||
<div class="loadout-editor-head"><div><span>AGENT CLASS</span><h2>SPECIALIZATION FOCUS</h2></div><b>{selectedFocus ? `${selectedSpecializationPoints} / ${data.specializationProgression.availablePoints} POINTS` : 'UNASSIGNED'}</b></div>
|
||||
<BuilderPicker items={specializationItems} value={draft.specialization.focusId} onchange={selectFocus} label="SPECIALIZATION + FOCUS"/>
|
||||
{#if draft.specialization.unassignedChips.length}
|
||||
<div class="builder-remediation" role="status"><strong>UNRESOLVED LEGACY SKILL CHIPS</strong><span>{draft.specialization.unassignedChips.length} chip selection{draft.specialization.unassignedChips.length === 1 ? '' : 's'} from the previous builder could not be matched to this focus. The original data remains in this draft.</span></div>
|
||||
{/if}
|
||||
{#if selectedFocus}
|
||||
<div class="builder-specialization-identity"><span class="focus-composite-icon"><ItemIcon src={selectedFocus.specialization.iconUrl} alt={selectedFocus.specialization.name}/><GameIcon name={selectedFocus.primary_attribute.toLocaleLowerCase() as GameIconName} decorative/></span><div><small>{selectedFocus.specialization.name}</small><h3>{selectedFocus.name}</h3><p>{selectedFocus.description || 'No focus description has been entered.'}</p></div><b class:configured={Number(selectedFocus.builder_ready) === 1}>{Number(selectedFocus.builder_ready) === 1 ? 'BUILDER READY' : 'ISAC DATA INCOMPLETE'}</b></div>
|
||||
<div class="builder-ability-chip-panels">
|
||||
|
||||
Reference in New Issue
Block a user