feat: show item renders in public database
This commit is contained in:
+4
-1
File diff suppressed because one or more lines are too long
@@ -15,6 +15,7 @@
|
||||
|
||||
<article class="database-item-card" class:talent-card={item.variant === 'talent'}>
|
||||
<header>
|
||||
{#if item.renderUrl}<img class="database-item-render" src={item.renderUrl} alt="" loading="lazy"/>{/if}
|
||||
<div class="database-item-icon">
|
||||
{#if item.gameIcon}<GameIcon name={item.gameIcon} decorative/>{:else}<ItemIcon src={item.iconUrl} alt=""/>{/if}
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,7 @@ export type DatabaseItem = {
|
||||
kicker: string;
|
||||
variant?: 'talent';
|
||||
iconUrl?: string;
|
||||
renderUrl?: string;
|
||||
gameIcon?: GameIconName;
|
||||
headerBadge?: string;
|
||||
headerMetaIcon?: GameIconName;
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { DatabaseFact, DatabaseItem } from '$lib/database/items';
|
||||
import type { GameIconName } from '$lib/game-icons';
|
||||
import { weaponBaseRange } from '$lib/builder/loadout';
|
||||
import { gameDataIconUrl, type GameDataIconType } from '$lib/server/game-data-icons';
|
||||
import { managedImageUrl } from '$lib/server/managed-images';
|
||||
import { getDatabase } from '$lib/server/database';
|
||||
import { getPagination, getRegistrySearch } from '$lib/server/pagination';
|
||||
import { error } from '@sveltejs/kit';
|
||||
@@ -146,7 +147,10 @@ export const load: PageServerLoad = async ({ params, url }) => {
|
||||
}
|
||||
const where = conditions.join(' AND ');
|
||||
countSql = `SELECT COUNT(*) AS total FROM gear item WHERE ${where}`;
|
||||
rowsSql = `SELECT item.* FROM gear item WHERE ${where}
|
||||
rowsSql = `SELECT item.*,render.id AS render_id,render.updated_at AS render_updated_at
|
||||
FROM gear item
|
||||
LEFT JOIN managed_images render ON render.source_entity_type='gear_render' AND render.source_entity_id=item.id
|
||||
WHERE ${where}
|
||||
ORDER BY item.slot,item.tier,item.name COLLATE NOCASE LIMIT ? OFFSET ?`;
|
||||
filters = [
|
||||
{
|
||||
@@ -208,13 +212,14 @@ export const load: PageServerLoad = async ({ params, url }) => {
|
||||
}
|
||||
const where = conditions.join(' AND ');
|
||||
countSql = `SELECT COUNT(*) AS total FROM weapons item WHERE ${where}`;
|
||||
rowsSql = `SELECT item.*,
|
||||
rowsSql = `SELECT item.*,render.id AS render_id,render.updated_at AS render_updated_at,
|
||||
native.damage_min,native.damage_max,native.reference_level,
|
||||
(SELECT COUNT(*) FROM weapon_talent_options options WHERE options.weapon_id=item.id AND options.talent_slot=1) AS talent_1_count,
|
||||
(SELECT COUNT(*) FROM weapon_talent_options options WHERE options.weapon_id=item.id AND options.talent_slot=2) AS talent_2_count,
|
||||
(SELECT COUNT(*) FROM weapon_category_attribute_bonuses bonuses WHERE bonuses.weapon_category=item.category) AS bonus_count
|
||||
FROM weapons item
|
||||
LEFT JOIN weapon_tier_ranges native ON native.weapon_id=item.id AND native.tier=item.native_tier
|
||||
LEFT JOIN managed_images render ON render.source_entity_type='weapon_render' AND render.source_entity_id=item.id
|
||||
WHERE ${where}
|
||||
ORDER BY item.is_exotic DESC,item.category,item.name COLLATE NOCASE LIMIT ? OFFSET ?`;
|
||||
filters = [
|
||||
@@ -481,6 +486,7 @@ export const load: PageServerLoad = async ({ params, url }) => {
|
||||
];
|
||||
return {
|
||||
id: String(row.id), name: String(row.name), kicker: `${row.slot} // T${row.tier}`,
|
||||
renderUrl: row.render_id ? managedImageUrl(String(row.render_id), row.render_updated_at) : '',
|
||||
gameIcon: gearIcon(row.slot),
|
||||
badges: [{ label: `T${row.tier}` }, { label: `${Number(row.tier) === 0 ? 1 : 2} MOD SLOT${Number(row.tier) === 0 ? '' : 'S'}` }],
|
||||
facts: [
|
||||
@@ -507,6 +513,7 @@ export const load: PageServerLoad = async ({ params, url }) => {
|
||||
const level50Damage = row.damage_min === null ? null : weaponBaseRange(row.damage_min, row.damage_max, 50);
|
||||
return {
|
||||
id: String(row.id), name: String(row.name), kicker: `${row.category} // ${row.damage_type}`,
|
||||
renderUrl: row.render_id ? managedImageUrl(String(row.render_id), row.render_updated_at) : '',
|
||||
gameIcon: weaponIcon(row.category),
|
||||
headerBadge: `T${row.native_tier}`,
|
||||
headerMetaIcon: weaponIcon(row.damage_type),
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
let editing = $state<Editor | null>(null);
|
||||
let augmentEditing = $state<any | null>(null);
|
||||
let handledResultToken = $state('');
|
||||
let renderResetToken = $state(0);
|
||||
const compatibleBrands = (ids: string[]) => ids.map((id) => data.brands.find((brand) => brand.id === id)).filter(Boolean);
|
||||
const stat = (id: string) => data.stats.find((item) => item.id === id);
|
||||
const format = (value: number | string, statId: string) => {
|
||||
@@ -63,6 +64,7 @@
|
||||
}
|
||||
if (form?.gearSaved && form.resultToken && form.resultToken !== handledResultToken) {
|
||||
handledResultToken = form.resultToken;
|
||||
if (form.gearMode === 'add') renderResetToken += 1;
|
||||
editing = form.gearMode === 'add' ? blank() : null;
|
||||
}
|
||||
});
|
||||
@@ -79,7 +81,7 @@
|
||||
<SegmentedChoice legend="SLOT" name="slot" options={slotOptions} bind:value={editing.slot} onchange={(values) => changeSlot(values[0])} required/>
|
||||
<SegmentedChoice legend="TIER" name="tier" options={tierOptions} bind:value={editing.tier} required/>
|
||||
</div>
|
||||
<GameDataRenderUploadField currentUrl={editing.renderUrl} label="GEAR RENDER"/>
|
||||
<GameDataRenderUploadField currentUrl={editing.renderUrl} label="GEAR RENDER" resetToken={renderResetToken}/>
|
||||
<div class="gear-ranges">
|
||||
<div class="effect-band range-band"><strong>HP<small>BASE HEALTH</small></strong><label class="field">MINIMUM<input name="healthMin" type="number" min="0" step="any" bind:value={editing.base_health_min} required /></label><label class="field">MAXIMUM<input name="healthMax" type="number" min="0" step="any" bind:value={editing.base_health_max} required /></label></div>
|
||||
<div class="effect-band range-band" class:unavailable={!armoredSlots.includes(editing.slot)}><strong>AR<small>BASE ARMOR</small></strong><label class="field">MINIMUM<input name="armorMin" type="number" min="0" step="any" bind:value={editing.base_armor_min} disabled={!armoredSlots.includes(editing.slot)} required={armoredSlots.includes(editing.slot)} /></label><label class="field">MAXIMUM<input name="armorMax" type="number" min="0" step="any" bind:value={editing.base_armor_max} disabled={!armoredSlots.includes(editing.slot)} required={armoredSlots.includes(editing.slot)} /></label></div>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
let editing = $state<any | null>(null);
|
||||
let bonusEditing = $state<any | null>(null);
|
||||
let handledResultToken = $state('');
|
||||
let renderResetToken = $state(0);
|
||||
let openedRequestedWeapon = $state(false);
|
||||
const edit = (weapon: any) => {
|
||||
const tiers = [0, 1, 2].map((tier) => {
|
||||
@@ -94,6 +95,7 @@
|
||||
}
|
||||
if (form?.weaponSaved && form.resultToken && form.resultToken !== handledResultToken) {
|
||||
handledResultToken = form.resultToken;
|
||||
if (form.weaponMode === 'add') renderResetToken += 1;
|
||||
editing = form.weaponMode === 'add' ? blank() : null;
|
||||
}
|
||||
if (form?.weaponBonusProfileSaved && form.resultToken && form.resultToken !== handledResultToken) {
|
||||
@@ -147,7 +149,7 @@
|
||||
<SegmentedChoice legend="DAMAGE TYPE" name="damageType" options={damageTypeOptions} bind:value={editing.damage_type} required/>
|
||||
<label class="field exotic-toggle">EXOTIC STATUS<span title="Exotic weapon"><input name="isExotic" type="checkbox" value="1" checked={Number(editing.is_exotic) === 1} onchange={(event) => setExotic(event.currentTarget.checked)}/><GameIcon name="exotic" decorative/><b class="sr-only">EXOTIC WEAPON</b></span></label>
|
||||
</div>
|
||||
<GameDataRenderUploadField currentUrl={editing.renderUrl} label="WEAPON RENDER"/>
|
||||
<GameDataRenderUploadField currentUrl={editing.renderUrl} label="WEAPON RENDER" resetToken={renderResetToken}/>
|
||||
{#if Number(editing.is_exotic)}
|
||||
<section class="weapon-exotic-talent">
|
||||
<div class="selection-head"><div><span>DEDICATED EXOTIC TALENT</span><small>SELECT ONE TALENT FROM THE EXOTIC WEAPON REGISTRY</small></div><b>{editing.exotic_talent_id ? '1 / 1 ASSIGNED' : 'REQUIRED'}</b></div>
|
||||
|
||||
Reference in New Issue
Block a user