add centralized image utility system
This commit is contained in:
parent
bc2e7d6bdb
commit
91524ed064
1 changed files with 194 additions and 0 deletions
194
src/lib/utils/images.ts
Normal file
194
src/lib/utils/images.ts
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/**
|
||||
* Centralized image utility system for all game assets
|
||||
*/
|
||||
|
||||
export type ResourceType = 'character' | 'weapon' | 'summon'
|
||||
export type ImageVariant = 'main' | 'grid' | 'square' | 'detail' | 'base' | 'wide'
|
||||
|
||||
/**
|
||||
* Maps resource type and variant to the correct directory name
|
||||
*/
|
||||
function getImageDirectory(type: ResourceType, variant: ImageVariant): string {
|
||||
// All directories follow the pattern: {type}-{variant}
|
||||
return `${type}-${variant}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the file extension for a given resource type and variant
|
||||
*/
|
||||
function getFileExtension(type: ResourceType, variant: ImageVariant): string {
|
||||
// PNG variants: character-detail, weapon-base, summon-detail
|
||||
if (type === 'character' && variant === 'detail') return '.png'
|
||||
if (type === 'weapon' && variant === 'base') return '.png'
|
||||
if (type === 'summon' && variant === 'detail') return '.png'
|
||||
|
||||
// All other variants use JPG
|
||||
return '.jpg'
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the placeholder image for a given type and variant
|
||||
*/
|
||||
export function getPlaceholderImage(type: ResourceType, variant: ImageVariant): string {
|
||||
return `/images/placeholders/placeholder-${type}-${variant}.png`
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the character pose based on uncap level and transcendence
|
||||
*/
|
||||
export function getCharacterPose(uncapLevel?: number, transcendenceStep?: number): string {
|
||||
if (transcendenceStep && transcendenceStep > 0) return '04'
|
||||
if (uncapLevel && uncapLevel >= 5) return '03'
|
||||
if (uncapLevel && uncapLevel > 2) return '02'
|
||||
return '01'
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function to get image URL for any resource
|
||||
*/
|
||||
export function getImageUrl(
|
||||
type: ResourceType,
|
||||
id: string | number | null | undefined,
|
||||
variant: ImageVariant,
|
||||
options?: {
|
||||
pose?: string // For character poses
|
||||
element?: number // For element-specific weapon grids
|
||||
}
|
||||
): string {
|
||||
// Return placeholder if no ID
|
||||
if (!id) {
|
||||
return getPlaceholderImage(type, variant)
|
||||
}
|
||||
|
||||
const directory = getImageDirectory(type, variant)
|
||||
const extension = getFileExtension(type, variant)
|
||||
const basePath = `/images/${directory}`
|
||||
|
||||
// Handle character-specific logic
|
||||
if (type === 'character') {
|
||||
const pose = options?.pose || '01'
|
||||
return `${basePath}/${id}_${pose}${extension}`
|
||||
}
|
||||
|
||||
// Handle weapon grid element variants
|
||||
if (type === 'weapon' && variant === 'grid' && options?.element && options.element > 0) {
|
||||
return `${basePath}/${id}_${options.element}${extension}`
|
||||
}
|
||||
|
||||
// Standard format for weapons and summons
|
||||
return `${basePath}/${id}${extension}`
|
||||
}
|
||||
|
||||
// ===== Convenience Functions =====
|
||||
|
||||
/**
|
||||
* Get character image URL
|
||||
*/
|
||||
export function getCharacterImage(
|
||||
id: string | number | null | undefined,
|
||||
variant: ImageVariant = 'main',
|
||||
pose?: string
|
||||
): string {
|
||||
return getImageUrl('character', id, variant, { pose })
|
||||
}
|
||||
|
||||
/**
|
||||
* Get character detail image (PNG) with pose
|
||||
*/
|
||||
export function getCharacterDetailImage(
|
||||
id: string | number | null | undefined,
|
||||
pose?: string
|
||||
): string {
|
||||
return getImageUrl('character', id, 'detail', { pose })
|
||||
}
|
||||
|
||||
/**
|
||||
* Get weapon image URL
|
||||
*/
|
||||
export function getWeaponImage(
|
||||
id: string | number | null | undefined,
|
||||
variant: ImageVariant = 'main',
|
||||
element?: number
|
||||
): string {
|
||||
return getImageUrl('weapon', id, variant, { element })
|
||||
}
|
||||
|
||||
/**
|
||||
* Get weapon base image (PNG)
|
||||
*/
|
||||
export function getWeaponBaseImage(
|
||||
id: string | number | null | undefined
|
||||
): string {
|
||||
return getImageUrl('weapon', id, 'base')
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summon image URL
|
||||
*/
|
||||
export function getSummonImage(
|
||||
id: string | number | null | undefined,
|
||||
variant: ImageVariant = 'main'
|
||||
): string {
|
||||
return getImageUrl('summon', id, variant)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summon detail image (PNG)
|
||||
*/
|
||||
export function getSummonDetailImage(
|
||||
id: string | number | null | undefined
|
||||
): string {
|
||||
return getImageUrl('summon', id, 'detail')
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summon wide image
|
||||
*/
|
||||
export function getSummonWideImage(
|
||||
id: string | number | null | undefined
|
||||
): string {
|
||||
return getImageUrl('summon', id, 'wide')
|
||||
}
|
||||
|
||||
// ===== Special Handlers =====
|
||||
|
||||
/**
|
||||
* Get character image with automatic pose calculation
|
||||
*/
|
||||
export function getCharacterImageWithPose(
|
||||
id: string | number | null | undefined,
|
||||
variant: ImageVariant,
|
||||
uncapLevel?: number,
|
||||
transcendenceStep?: number,
|
||||
mainWeaponElement?: number | null,
|
||||
partyElement?: number | null
|
||||
): string {
|
||||
if (!id) {
|
||||
return getPlaceholderImage('character', variant)
|
||||
}
|
||||
|
||||
let pose = getCharacterPose(uncapLevel, transcendenceStep)
|
||||
|
||||
// Special handling for Gran/Djeeta (3030182000)
|
||||
if (String(id) === '3030182000') {
|
||||
const element = mainWeaponElement || partyElement || 1
|
||||
pose = `${pose}_0${element}`
|
||||
}
|
||||
|
||||
return getImageUrl('character', id, variant, { pose })
|
||||
}
|
||||
|
||||
/**
|
||||
* Get weapon grid image with element support
|
||||
*/
|
||||
export function getWeaponGridImage(
|
||||
id: string | number | null | undefined,
|
||||
element?: number,
|
||||
instanceElement?: number
|
||||
): string {
|
||||
// Handle element-specific weapons (primal weapons)
|
||||
if (id && element === 0 && instanceElement) {
|
||||
return getImageUrl('weapon', id, 'grid', { element: instanceElement })
|
||||
}
|
||||
return getImageUrl('weapon', id, 'grid')
|
||||
}
|
||||
Loading…
Reference in a new issue