Add ISAC weapon data management

This commit is contained in:
JB
2026-07-25 00:49:08 -04:00
parent 3f78f0f9d8
commit e528f18d8f
12 changed files with 555 additions and 13 deletions
+13 -3
View File
@@ -3,7 +3,8 @@
let { data, form } = $props();
type Effect = { statId: string; valueI: string; valueII: string };
let talent = $state<any>(null), trigger = $state<any>(null), uptime = $state(false);
const blankTalent = () => ({ id: '', name: '', category: 'Weapon', descriptionTemplate: '', tierIDescription: '', tierIIDescription: '', triggerIds: [], effects: [{ statId: '', valueI: '', valueII: '' }] });
let handledResultToken = $state('');
const blankTalent = () => ({ id: '', name: '', category: 'Weapon Talent 1', descriptionTemplate: '', tierIDescription: '', tierIIDescription: '', triggerIds: [], effects: [{ statId: '', valueI: '', valueII: '' }] });
const editTalent = (row: any) => {
const tier = (name: string) => row.tiers.find((item: any) => item.tier === name) ?? { description: '', triggerIds: [], effects: [] };
const one = tier('I'), two = tier('II');
@@ -37,11 +38,20 @@
const effect = talent.effects[Number(rawIndex) - 1];
return effect ? displayValue(effect, tier) : placeholder;
});
$effect(() => {
if (!form?.resultToken || form.resultToken === handledResultToken) return;
handledResultToken = form.resultToken;
if (form.talentSaved) talent = form.talentMode === 'add' ? blankTalent() : null;
if (form.triggerSaved) {
if (form.triggerMode === 'add') blankTrigger();
else trigger = null;
}
});
</script>
<svelte:head><title>Talents & triggers — SHD.build admin</title></svelte:head>
<div class="module-toolbar"><div><p class="eyebrow">TALENT REGISTRY</p><h2>TALENTS & TRIGGERS</h2><p>Shared behavior with tier-specific values, reusable triggers, and attribute effects.</p></div><div><button class="secondary" onclick={blankTrigger}>ADD TRIGGER +</button><button class="primary" onclick={() => talent = blankTalent()}>ADD TALENT +</button></div></div>
<div class="module-kpis"><div><span>TALENTS</span><strong>{data.talents.length}</strong><small>Registered definitions</small></div><div><span>TRIGGERS</span><strong>{data.triggers.length}</strong><small>Reusable conditions</small></div><div><span>WEAPON</span><strong>{data.talents.filter((item) => item.category === 'Weapon').length}</strong><small>Weapon talents</small></div><div><span>GEAR</span><strong>{data.talents.filter((item) => item.category !== 'Weapon').length}</strong><small>Body armor and backpack</small></div></div>
<div class="module-kpis"><div><span>TALENTS</span><strong>{data.talents.length}</strong><small>Registered definitions</small></div><div><span>TOP / TALENT 1</span><strong>{data.talents.filter((item) => item.category === 'Weapon Talent 1').length}</strong><small>First-slot weapon talents</small></div><div><span>BOTTOM / TALENT 2</span><strong>{data.talents.filter((item) => item.category === 'Weapon Talent 2').length}</strong><small>Second-slot weapon talents</small></div><div><span>EXOTIC</span><strong>{data.talents.filter((item) => item.category === 'Exotic Weapon').length}</strong><small>Exotic-only talents</small></div></div>
{#if trigger}
<div class="dashboard-editor"><div class="editor-title"><div><p class="eyebrow">{trigger.id ? 'MODIFY TRIGGER' : 'NEW TRIGGER'}</p><h3>{trigger.id ? trigger.name : 'TRIGGER DEFINITION'}</h3></div><button aria-label="Close trigger editor" onclick={() => trigger = null}>×</button></div><PendingForm action="?/saveTrigger"><input type="hidden" name="id" value={trigger.id}/><div class="form-grid"><label class="field">NAME<input name="name" bind:value={trigger.name} required/></label><label class="field">DESCRIPTION<textarea name="description" bind:value={trigger.description} required></textarea></label><label class="field uptime-field"><span><input name="supportsUptime" type="checkbox" bind:checked={uptime}/> ENABLE THEORETICAL UPTIME</span><div><input name="minUptime" type="number" min="0" max="100" bind:value={trigger.min_uptime} disabled={!uptime} placeholder="MIN %"/><input name="maxUptime" type="number" min="0" max="100" bind:value={trigger.max_uptime} disabled={!uptime} placeholder="MAX %"/></div></label><p class="script-note"><b>CALCULATION SCRIPT</b><span>Reserved for the future calculation engine</span></p></div>{#if form?.triggerError}<p class="error">{form.triggerError}</p>{/if}<div class="form-actions"><button type="button" class="secondary" onclick={() => trigger = null}>CANCEL</button><button class="primary">SAVE TRIGGER →</button></div></PendingForm></div>
@@ -52,7 +62,7 @@
<div class="editor-title"><div><p class="eyebrow">{talent.id ? 'MODIFY TALENT' : 'NEW TALENT'}</p><h3>{talent.id ? talent.name : 'TALENT DEFINITION'}</h3></div><button aria-label="Close talent editor" onclick={() => talent = null}>×</button></div>
<PendingForm action="?/saveTalent">
<input type="hidden" name="id" value={talent.id}/><input type="hidden" name="effects" value={JSON.stringify(talent.effects)}/>
<div class="form-grid talent-identity"><label class="field">NAME<input name="name" bind:value={talent.name} required/></label><label class="field">CATEGORY<select name="category" bind:value={talent.category}><option>Weapon</option><option>Backpack</option><option>Body Armor</option></select></label></div>
<div class="form-grid talent-identity"><label class="field">NAME<input name="name" bind:value={talent.name} required/></label><label class="field">CATEGORY / SLOT<select name="category" bind:value={talent.category}><option value="Weapon · Slot Unassigned" disabled>Weapon · Choose a slot</option><option>Weapon Talent 1</option><option>Weapon Talent 2</option><option>Exotic Weapon</option><option>Backpack</option><option>Body Armor</option></select></label></div>
<label class="field template-field">SHARED DESCRIPTION TEMPLATE<textarea name="descriptionTemplate" bind:value={talent.descriptionTemplate} placeholder="Hitting an enemy {1} times grants +{2}..." required></textarea><small>Use {'{1}'}, {'{2}'}, and so on to insert each effect value with its unit.</small></label>
<div class="tier-preview"><div><span>TIER I PREVIEW</span><p>{preview('I') || 'Description preview'}</p></div><div><span>TIER II PREVIEW</span><p>{preview('II') || 'Description preview'}</p></div></div>
<p class="label">SHARED ACTIVATION TRIGGERS</p>