update utility functions
This commit is contained in:
parent
cf34092ccc
commit
a00b8a8d18
5 changed files with 149 additions and 130 deletions
|
|
@ -1,3 +1,20 @@
|
||||||
|
interface ElementData {
|
||||||
|
en: string
|
||||||
|
ja: string
|
||||||
|
opposite_id: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ELEMENTS: Record<number, ElementData> = {
|
||||||
|
0: { en: 'Null', ja: '無', opposite_id: 0 },
|
||||||
|
1: { en: 'Wind', ja: '風', opposite_id: 4 },
|
||||||
|
2: { en: 'Fire', ja: '火', opposite_id: 3 },
|
||||||
|
3: { en: 'Water', ja: '水', opposite_id: 2 },
|
||||||
|
4: { en: 'Earth', ja: '土', opposite_id: 1 },
|
||||||
|
5: { en: 'Dark', ja: '闇', opposite_id: 6 },
|
||||||
|
6: { en: 'Light', ja: '光', opposite_id: 5 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy support - still used in many places
|
||||||
export const ELEMENT_LABELS: Record<number, string> = {
|
export const ELEMENT_LABELS: Record<number, string> = {
|
||||||
0: 'Null',
|
0: 'Null',
|
||||||
1: 'Wind',
|
1: 'Wind',
|
||||||
|
|
@ -32,4 +49,17 @@ export function getElementOptions() {
|
||||||
value: Number(value),
|
value: Number(value),
|
||||||
label
|
label
|
||||||
}))
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getElementName(element?: number, locale: 'en' | 'ja' = 'en'): string {
|
||||||
|
if (element === undefined || element === null) return '—'
|
||||||
|
const elementData = ELEMENTS[element]
|
||||||
|
if (!elementData) return '—'
|
||||||
|
return elementData[locale]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOppositeElement(element?: number): number | undefined {
|
||||||
|
if (element === undefined || element === null) return undefined
|
||||||
|
const elementData = ELEMENTS[element]
|
||||||
|
return elementData?.opposite_id
|
||||||
}
|
}
|
||||||
|
|
@ -1,98 +1,96 @@
|
||||||
import type { GridCharacter, GridWeapon, GridSummon } from '$lib/types/api/party'
|
import type { GridCharacter, GridWeapon, GridSummon } from '$lib/types/api/party'
|
||||||
|
|
||||||
export interface ModificationStatus {
|
export interface ModificationStatus {
|
||||||
hasModifications: boolean
|
hasModifications: boolean
|
||||||
hasAwakening: boolean
|
hasAwakening: boolean
|
||||||
hasWeaponKeys: boolean
|
hasWeaponKeys: boolean
|
||||||
hasAxSkills: boolean
|
hasAxSkills: boolean
|
||||||
hasRings: boolean
|
hasRings: boolean
|
||||||
hasEarring: boolean
|
hasEarring: boolean
|
||||||
hasPerpetuity: boolean
|
hasPerpetuity: boolean
|
||||||
hasTranscendence: boolean
|
hasTranscendence: boolean
|
||||||
hasUncapLevel: boolean
|
hasUncapLevel: boolean
|
||||||
hasElement: boolean
|
hasElement: boolean
|
||||||
hasQuickSummon: boolean
|
hasQuickSummon: boolean
|
||||||
hasFriendSummon: boolean
|
hasFriendSummon: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function detectModifications(
|
export function detectModifications(
|
||||||
type: 'character' | 'weapon' | 'summon',
|
type: 'character' | 'weapon' | 'summon',
|
||||||
item: GridCharacter | GridWeapon | GridSummon | undefined
|
item: GridCharacter | GridWeapon | GridSummon | undefined
|
||||||
): ModificationStatus {
|
): ModificationStatus {
|
||||||
const status: ModificationStatus = {
|
const status: ModificationStatus = {
|
||||||
hasModifications: false,
|
hasModifications: false,
|
||||||
hasAwakening: false,
|
hasAwakening: false,
|
||||||
hasWeaponKeys: false,
|
hasWeaponKeys: false,
|
||||||
hasAxSkills: false,
|
hasAxSkills: false,
|
||||||
hasRings: false,
|
hasRings: false,
|
||||||
hasEarring: false,
|
hasEarring: false,
|
||||||
hasPerpetuity: false,
|
hasPerpetuity: false,
|
||||||
hasTranscendence: false,
|
hasTranscendence: false,
|
||||||
hasUncapLevel: false,
|
hasUncapLevel: false,
|
||||||
hasElement: false,
|
hasElement: false,
|
||||||
hasQuickSummon: false,
|
hasQuickSummon: false,
|
||||||
hasFriendSummon: false
|
hasFriendSummon: false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item) return status
|
if (!item) return status
|
||||||
|
|
||||||
if (type === 'character') {
|
if (type === 'character') {
|
||||||
const char = item as GridCharacter
|
const char = item as GridCharacter
|
||||||
|
|
||||||
status.hasAwakening = !!char.awakening
|
status.hasAwakening = !!char.awakening
|
||||||
status.hasRings = !!(char.over_mastery && char.over_mastery.length > 0)
|
status.hasRings = !!(char.overMastery && char.overMastery.length > 0)
|
||||||
status.hasEarring = !!char.aetherial_mastery
|
status.hasEarring = !!char.aetherialMastery
|
||||||
status.hasPerpetuity = !!char.perpetuity
|
status.hasPerpetuity = !!char.perpetuity
|
||||||
status.hasTranscendence = !!(char.transcendenceStep && char.transcendenceStep > 0)
|
status.hasTranscendence = !!(char.transcendenceStep && char.transcendenceStep > 0)
|
||||||
status.hasUncapLevel = char.uncapLevel !== undefined && char.uncapLevel !== null
|
status.hasUncapLevel = char.uncapLevel !== undefined && char.uncapLevel !== null
|
||||||
|
|
||||||
status.hasModifications =
|
status.hasModifications =
|
||||||
status.hasAwakening ||
|
status.hasAwakening ||
|
||||||
status.hasRings ||
|
status.hasRings ||
|
||||||
status.hasEarring ||
|
status.hasEarring ||
|
||||||
status.hasPerpetuity ||
|
status.hasPerpetuity ||
|
||||||
status.hasTranscendence ||
|
status.hasTranscendence ||
|
||||||
status.hasUncapLevel
|
status.hasUncapLevel
|
||||||
|
} else if (type === 'weapon') {
|
||||||
|
const weapon = item as GridWeapon
|
||||||
|
|
||||||
} else if (type === 'weapon') {
|
status.hasAwakening = !!weapon.awakening
|
||||||
const weapon = item as GridWeapon
|
status.hasWeaponKeys = !!(weapon.weaponKeys && weapon.weaponKeys.length > 0)
|
||||||
|
status.hasAxSkills = !!(weapon.ax && weapon.ax.length > 0)
|
||||||
|
status.hasTranscendence = !!(weapon.transcendenceStep && weapon.transcendenceStep > 0)
|
||||||
|
status.hasUncapLevel = weapon.uncapLevel !== undefined && weapon.uncapLevel !== null
|
||||||
|
status.hasElement = !!(weapon.element && weapon.weapon?.element === 0)
|
||||||
|
|
||||||
status.hasAwakening = !!weapon.awakening
|
status.hasModifications =
|
||||||
status.hasWeaponKeys = !!(weapon.weaponKeys && weapon.weaponKeys.length > 0)
|
status.hasAwakening ||
|
||||||
status.hasAxSkills = !!(weapon.ax && weapon.ax.length > 0)
|
status.hasWeaponKeys ||
|
||||||
status.hasTranscendence = !!(weapon.transcendenceStep && weapon.transcendenceStep > 0)
|
status.hasAxSkills ||
|
||||||
status.hasUncapLevel = weapon.uncapLevel !== undefined && weapon.uncapLevel !== null
|
status.hasTranscendence ||
|
||||||
status.hasElement = !!(weapon.element && weapon.weapon?.element === 0)
|
status.hasUncapLevel ||
|
||||||
|
status.hasElement
|
||||||
|
} else if (type === 'summon') {
|
||||||
|
const summon = item as GridSummon
|
||||||
|
|
||||||
status.hasModifications =
|
status.hasTranscendence = !!(summon.transcendenceStep && summon.transcendenceStep > 0)
|
||||||
status.hasAwakening ||
|
status.hasUncapLevel = summon.uncapLevel !== undefined && summon.uncapLevel !== null
|
||||||
status.hasWeaponKeys ||
|
status.hasQuickSummon = !!summon.quickSummon
|
||||||
status.hasAxSkills ||
|
status.hasFriendSummon = !!summon.friend
|
||||||
status.hasTranscendence ||
|
|
||||||
status.hasUncapLevel ||
|
|
||||||
status.hasElement
|
|
||||||
|
|
||||||
} else if (type === 'summon') {
|
status.hasModifications =
|
||||||
const summon = item as GridSummon
|
status.hasTranscendence ||
|
||||||
|
status.hasUncapLevel ||
|
||||||
|
status.hasQuickSummon ||
|
||||||
|
status.hasFriendSummon
|
||||||
|
}
|
||||||
|
|
||||||
status.hasTranscendence = !!(summon.transcendenceStep && summon.transcendenceStep > 0)
|
return status
|
||||||
status.hasUncapLevel = summon.uncapLevel !== undefined && summon.uncapLevel !== null
|
|
||||||
status.hasQuickSummon = !!summon.quickSummon
|
|
||||||
status.hasFriendSummon = !!summon.friend
|
|
||||||
|
|
||||||
status.hasModifications =
|
|
||||||
status.hasTranscendence ||
|
|
||||||
status.hasUncapLevel ||
|
|
||||||
status.hasQuickSummon ||
|
|
||||||
status.hasFriendSummon
|
|
||||||
}
|
|
||||||
|
|
||||||
return status
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasAnyModification(
|
export function hasAnyModification(
|
||||||
type: 'character' | 'weapon' | 'summon',
|
type: 'character' | 'weapon' | 'summon',
|
||||||
item: GridCharacter | GridWeapon | GridSummon | undefined
|
item: GridCharacter | GridWeapon | GridSummon | undefined
|
||||||
): boolean {
|
): boolean {
|
||||||
return detectModifications(type, item).hasModifications
|
return detectModifications(type, item).hasModifications
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,5 @@
|
||||||
import type { SimpleAxSkill } from '$lib/types/api/entities'
|
import type { SimpleAxSkill } from '$lib/types/api/entities'
|
||||||
|
import { getRingStat, getEarringStat, getElementalizedEarringStat } from './masteryUtils'
|
||||||
const RING_STAT_NAMES: Record<number, string> = {
|
|
||||||
1: 'HP',
|
|
||||||
2: 'Attack',
|
|
||||||
3: 'Double Attack',
|
|
||||||
4: 'Triple Attack',
|
|
||||||
5: 'Elemental Attack',
|
|
||||||
6: 'Critical Hit',
|
|
||||||
7: 'Skill Damage',
|
|
||||||
8: 'Skill DMG Cap',
|
|
||||||
9: 'Ougi Damage',
|
|
||||||
10: 'Ougi DMG Cap',
|
|
||||||
11: 'Chain Burst DMG',
|
|
||||||
12: 'Chain Burst Cap',
|
|
||||||
13: 'Healing',
|
|
||||||
14: 'Healing Cap',
|
|
||||||
15: 'Stamina',
|
|
||||||
16: 'Enmity',
|
|
||||||
17: 'Debuff Success'
|
|
||||||
}
|
|
||||||
|
|
||||||
const EARRING_STAT_NAMES: Record<number, string> = {
|
|
||||||
1: 'HP',
|
|
||||||
2: 'Attack',
|
|
||||||
3: 'Defense',
|
|
||||||
4: 'Double Attack',
|
|
||||||
5: 'Triple Attack',
|
|
||||||
6: 'Elemental Attack',
|
|
||||||
7: 'Critical Hit',
|
|
||||||
8: 'Skill Damage',
|
|
||||||
9: 'Skill DMG Cap',
|
|
||||||
10: 'Ougi Damage',
|
|
||||||
11: 'Ougi DMG Cap',
|
|
||||||
12: 'Auto Attack Cap',
|
|
||||||
13: 'Chain Burst DMG',
|
|
||||||
14: 'Chain Burst Cap',
|
|
||||||
15: 'Healing',
|
|
||||||
16: 'Healing Cap'
|
|
||||||
}
|
|
||||||
|
|
||||||
const AX_SKILL_NAMES: Record<number, string> = {
|
const AX_SKILL_NAMES: Record<number, string> = {
|
||||||
1: 'Attack',
|
1: 'Attack',
|
||||||
|
|
@ -53,16 +15,33 @@ const AX_SKILL_NAMES: Record<number, string> = {
|
||||||
11: 'Critical Hit'
|
11: 'Critical Hit'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatRingStat(modifier: number, strength: number): string {
|
export function formatRingStat(
|
||||||
const statName = RING_STAT_NAMES[modifier] || `Unknown (${modifier})`
|
modifier: number,
|
||||||
const suffix = modifier <= 2 ? '' : '%'
|
strength: number,
|
||||||
return `${statName} +${strength}${suffix}`
|
locale: 'en' | 'ja' = 'en'
|
||||||
|
): string {
|
||||||
|
const stat = getRingStat(modifier)
|
||||||
|
if (!stat) return `Unknown +${strength}`
|
||||||
|
|
||||||
|
const statName = stat.name[locale]
|
||||||
|
return `${statName} +${strength}${stat.suffix}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatEarringStat(modifier: number, strength: number): string {
|
export function formatEarringStat(
|
||||||
const statName = EARRING_STAT_NAMES[modifier] || `Unknown (${modifier})`
|
modifier: number,
|
||||||
const suffix = modifier <= 3 ? '' : '%'
|
strength: number,
|
||||||
return `${statName} +${strength}${suffix}`
|
locale: 'en' | 'ja' = 'en',
|
||||||
|
characterElement?: number
|
||||||
|
): string {
|
||||||
|
// Use elementalized version if element is provided and it's an element-specific stat
|
||||||
|
const stat = characterElement !== undefined && (modifier === 3 || modifier === 4)
|
||||||
|
? getElementalizedEarringStat(modifier, characterElement, locale)
|
||||||
|
: getEarringStat(modifier)
|
||||||
|
|
||||||
|
if (!stat) return `Unknown +${strength}`
|
||||||
|
|
||||||
|
const statName = stat.name[locale]
|
||||||
|
return `${statName} +${strength}${stat.suffix}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatAxSkill(ax: SimpleAxSkill): string {
|
export function formatAxSkill(ax: SimpleAxSkill): string {
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,26 @@
|
||||||
* Utility functions for weapon and character modifiers (awakenings, weapon keys, AX skills)
|
* Utility functions for weapon and character modifiers (awakenings, weapon keys, AX skills)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Awakening, WeaponKey, SimpleAxSkill } from '$lib/types'
|
import type { Awakening } from '$lib/types/Awakening'
|
||||||
|
import type { WeaponKey } from '$lib/types/WeaponKey'
|
||||||
|
import type { SimpleAxSkill } from '$lib/types/SimpleAxSkill'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the image URL for an awakening type
|
* Get the image URL for an awakening type
|
||||||
*/
|
*/
|
||||||
export function getAwakeningImage(awakening?: { type?: Awakening; level?: number }): string | null {
|
export function getAwakeningImage(awakening?: { type?: Awakening; level?: number }): string | null {
|
||||||
if (!awakening?.type?.slug) return null
|
if (!awakening?.type?.slug) return null
|
||||||
return `/images/awakening/${awakening.type.slug}.png`
|
|
||||||
|
const slug = awakening.type.slug
|
||||||
|
|
||||||
|
// No image for Balanced awakening type (character only)
|
||||||
|
if (slug === 'character-balanced') return null
|
||||||
|
|
||||||
|
// Character awakenings are JPG, weapon awakenings are PNG
|
||||||
|
const isCharacterAwakening = slug.startsWith('character-')
|
||||||
|
const extension = isCharacterAwakening ? 'jpg' : 'png'
|
||||||
|
|
||||||
|
return `/images/awakening/${slug}.${extension}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ export const PROFICIENCY_LABELS: Record<number, string> = {
|
||||||
0: 'None',
|
0: 'None',
|
||||||
1: 'Sabre',
|
1: 'Sabre',
|
||||||
2: 'Dagger',
|
2: 'Dagger',
|
||||||
3: 'Spear',
|
3: 'Axe',
|
||||||
4: 'Axe',
|
4: 'Spear',
|
||||||
5: 'Staff',
|
5: 'Staff',
|
||||||
6: 'Gun',
|
6: 'Gun',
|
||||||
7: 'Melee',
|
7: 'Melee',
|
||||||
|
|
@ -29,4 +29,4 @@ export function getProficiencyOptions() {
|
||||||
value: Number(value),
|
value: Number(value),
|
||||||
label
|
label
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue