utils: update grid helpers and modification utilities
This commit is contained in:
parent
8bfa31d925
commit
c0dc3d0bc1
3 changed files with 123 additions and 62 deletions
|
|
@ -19,7 +19,7 @@ export interface SlotRange {
|
|||
const GRID_CONFIGS: Record<GridType, SlotRange> = {
|
||||
[GridType.Weapon]: { start: 0, end: 8, specialSlots: [-1] }, // mainhand + 9 grid slots
|
||||
[GridType.Summon]: { start: 0, end: 5, specialSlots: [-1, 6] }, // main + 6 grid + friend
|
||||
[GridType.Character]: { start: 1, end: 4, specialSlots: [] } // 4 slots (1-4), position 0 is protagonist (not user-selectable)
|
||||
[GridType.Character]: { start: 0, end: 4, specialSlots: [] } // 5 character slots (0-4)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -94,3 +94,55 @@ export function hasAnyModification(
|
|||
): boolean {
|
||||
return detectModifications(type, item).hasModifications
|
||||
}
|
||||
|
||||
// Weapon series that support weapon keys
|
||||
// 2 = Dark Opus, 3 = Draconic, 17 = Ultima, 24 = Astral, 34 = Superlative
|
||||
const WEAPON_KEY_SERIES = [2, 3, 17, 24, 34]
|
||||
|
||||
/**
|
||||
* Check if a weapon CAN be modified (has modifiable properties)
|
||||
* This is different from hasModifications which checks if it HAS been modified
|
||||
*/
|
||||
export function canWeaponBeModified(gridWeapon: GridWeapon | undefined): boolean {
|
||||
if (!gridWeapon?.weapon) return false
|
||||
|
||||
const weapon = gridWeapon.weapon
|
||||
|
||||
// Element can be changed (element = 0 means "any element")
|
||||
const canChangeElement = weapon.element === 0
|
||||
|
||||
// Weapon keys (series-specific)
|
||||
const hasWeaponKeys = WEAPON_KEY_SERIES.includes(weapon.series)
|
||||
|
||||
// AX skills
|
||||
const hasAxSkills = weapon.ax === true
|
||||
|
||||
// Awakening (maxAwakeningLevel > 0 means it can have awakening)
|
||||
const hasAwakening = (weapon.maxAwakeningLevel ?? 0) > 0
|
||||
|
||||
return canChangeElement || hasWeaponKeys || hasAxSkills || hasAwakening
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a character CAN be modified (has modifiable properties)
|
||||
* This is different from hasModifications which checks if it HAS been modified
|
||||
*/
|
||||
export function canCharacterBeModified(gridCharacter: GridCharacter | undefined): boolean {
|
||||
if (!gridCharacter?.character) return false
|
||||
|
||||
const character = gridCharacter.character
|
||||
|
||||
// Awakening (maxAwakeningLevel > 0 means it can have awakening)
|
||||
const hasAwakening = (character.maxAwakeningLevel ?? 0) > 0
|
||||
|
||||
// All characters can have rings (Over Mastery)
|
||||
const canHaveRings = true
|
||||
|
||||
// All characters can have earrings (Aetherial Mastery)
|
||||
const canHaveEarring = true
|
||||
|
||||
// Perpetuity is only for non-MC characters (position > 0)
|
||||
const canHavePerpetuity = gridCharacter.position > 0
|
||||
|
||||
return hasAwakening || canHaveRings || canHaveEarring || canHavePerpetuity
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,93 +2,102 @@ import type { SimpleAxSkill } from '$lib/types/api/entities'
|
|||
import { getRingStat, getEarringStat, getElementalizedEarringStat } from './masteryUtils'
|
||||
|
||||
const AX_SKILL_NAMES: Record<number, string> = {
|
||||
1: 'Attack',
|
||||
2: 'HP',
|
||||
3: 'Double Attack',
|
||||
4: 'Triple Attack',
|
||||
5: 'C.A. DMG',
|
||||
6: 'C.A. DMG Cap',
|
||||
7: 'Skill DMG',
|
||||
8: 'Skill DMG Cap',
|
||||
9: 'Stamina',
|
||||
10: 'Enmity',
|
||||
11: 'Critical Hit'
|
||||
1: 'Attack',
|
||||
2: 'HP',
|
||||
3: 'Double Attack',
|
||||
4: 'Triple Attack',
|
||||
5: 'C.A. DMG',
|
||||
6: 'C.A. DMG Cap',
|
||||
7: 'Skill DMG',
|
||||
8: 'Skill DMG Cap',
|
||||
9: 'Stamina',
|
||||
10: 'Enmity',
|
||||
11: 'Critical Hit'
|
||||
}
|
||||
|
||||
export function formatRingStat(
|
||||
modifier: number,
|
||||
strength: number,
|
||||
locale: 'en' | 'ja' = 'en'
|
||||
modifier: number,
|
||||
strength: number,
|
||||
locale: 'en' | 'ja' = 'en'
|
||||
): string {
|
||||
const stat = getRingStat(modifier)
|
||||
if (!stat) return `Unknown +${strength}`
|
||||
const stat = getRingStat(modifier)
|
||||
if (!stat) return `Unknown +${strength}`
|
||||
|
||||
const statName = stat.name[locale]
|
||||
return `${statName} +${strength}${stat.suffix}`
|
||||
const statName = stat.name[locale]
|
||||
return `${statName} +${strength}${stat.suffix}`
|
||||
}
|
||||
|
||||
export function formatEarringStat(
|
||||
modifier: number,
|
||||
strength: number,
|
||||
locale: 'en' | 'ja' = 'en',
|
||||
characterElement?: number
|
||||
modifier: number,
|
||||
strength: number,
|
||||
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)
|
||||
// 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}`
|
||||
if (!stat) return `Unknown +${strength}`
|
||||
|
||||
const statName = stat.name[locale]
|
||||
return `${statName} +${strength}${stat.suffix}`
|
||||
const statName = stat.name[locale]
|
||||
return `${statName} +${strength}${stat.suffix}`
|
||||
}
|
||||
|
||||
export function formatAxSkill(ax: SimpleAxSkill): string {
|
||||
const skillName = AX_SKILL_NAMES[ax.modifier] || `Unknown (${ax.modifier})`
|
||||
const suffix = ax.modifier <= 2 ? '' : '%'
|
||||
return `${skillName} +${ax.strength}${suffix}`
|
||||
const skillName = AX_SKILL_NAMES[ax.modifier] || `Unknown (${ax.modifier})`
|
||||
const suffix = ax.modifier <= 2 ? '' : '%'
|
||||
return `${skillName} +${ax.strength}${suffix}`
|
||||
}
|
||||
|
||||
export function getWeaponKeyTitle(series?: number): string {
|
||||
switch (series) {
|
||||
case 2:
|
||||
return 'Opus Pendulums'
|
||||
case 3:
|
||||
case 34:
|
||||
return 'Draconic Telumas'
|
||||
case 17:
|
||||
return 'Ultima Keys'
|
||||
case 22:
|
||||
return 'Revans Emblems'
|
||||
default:
|
||||
return 'Weapon Keys'
|
||||
}
|
||||
switch (series) {
|
||||
case 2:
|
||||
return 'Pendulums & Chains'
|
||||
case 3:
|
||||
case 34:
|
||||
return 'Telumas'
|
||||
case 17:
|
||||
return 'Ultima Keys'
|
||||
case 22:
|
||||
return 'Emblems'
|
||||
default:
|
||||
return 'Weapon Keys'
|
||||
}
|
||||
}
|
||||
|
||||
export function formatUncapLevel(level?: number | null): string {
|
||||
if (level === undefined || level === null) return '0★'
|
||||
return `${level}★`
|
||||
if (level === undefined || level === null) return '0★'
|
||||
return `${level}★`
|
||||
}
|
||||
|
||||
export function formatTranscendenceStep(step?: number | null): string {
|
||||
if (!step || step === 0) return ''
|
||||
return `Stage ${step}`
|
||||
if (!step || step === 0) return ''
|
||||
return `Stage ${step}`
|
||||
}
|
||||
|
||||
export function getStatModifierIcon(type: 'ring' | 'earring', modifier: number): string | null {
|
||||
return null
|
||||
return null
|
||||
}
|
||||
|
||||
export function getElementName(element?: number | null): string {
|
||||
switch (element) {
|
||||
case 0: return 'Null'
|
||||
case 1: return 'Wind'
|
||||
case 2: return 'Fire'
|
||||
case 3: return 'Water'
|
||||
case 4: return 'Earth'
|
||||
case 5: return 'Dark'
|
||||
case 6: return 'Light'
|
||||
default: return 'Unknown'
|
||||
}
|
||||
}
|
||||
switch (element) {
|
||||
case 0:
|
||||
return 'Null'
|
||||
case 1:
|
||||
return 'Wind'
|
||||
case 2:
|
||||
return 'Fire'
|
||||
case 3:
|
||||
return 'Water'
|
||||
case 4:
|
||||
return 'Earth'
|
||||
case 5:
|
||||
return 'Dark'
|
||||
case 6:
|
||||
return 'Light'
|
||||
default:
|
||||
return 'Unknown'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue