utils: update grid helpers and modification utilities

This commit is contained in:
Justin Edmund 2025-11-30 20:05:54 -08:00
parent 8bfa31d925
commit c0dc3d0bc1
3 changed files with 123 additions and 62 deletions

View file

@ -19,7 +19,7 @@ export interface SlotRange {
const GRID_CONFIGS: Record<GridType, SlotRange> = { const GRID_CONFIGS: Record<GridType, SlotRange> = {
[GridType.Weapon]: { start: 0, end: 8, specialSlots: [-1] }, // mainhand + 9 grid slots [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.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)
} }
/** /**

View file

@ -94,3 +94,55 @@ export function hasAnyModification(
): boolean { ): boolean {
return detectModifications(type, item).hasModifications 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
}

View file

@ -34,7 +34,8 @@ export function formatEarringStat(
characterElement?: number characterElement?: number
): string { ): string {
// Use elementalized version if element is provided and it's an element-specific stat // Use elementalized version if element is provided and it's an element-specific stat
const stat = characterElement !== undefined && (modifier === 3 || modifier === 4) const stat =
characterElement !== undefined && (modifier === 3 || modifier === 4)
? getElementalizedEarringStat(modifier, characterElement, locale) ? getElementalizedEarringStat(modifier, characterElement, locale)
: getEarringStat(modifier) : getEarringStat(modifier)
@ -53,14 +54,14 @@ export function formatAxSkill(ax: SimpleAxSkill): string {
export function getWeaponKeyTitle(series?: number): string { export function getWeaponKeyTitle(series?: number): string {
switch (series) { switch (series) {
case 2: case 2:
return 'Opus Pendulums' return 'Pendulums & Chains'
case 3: case 3:
case 34: case 34:
return 'Draconic Telumas' return 'Telumas'
case 17: case 17:
return 'Ultima Keys' return 'Ultima Keys'
case 22: case 22:
return 'Revans Emblems' return 'Emblems'
default: default:
return 'Weapon Keys' return 'Weapon Keys'
} }
@ -82,13 +83,21 @@ export function getStatModifierIcon(type: 'ring' | 'earring', modifier: number):
export function getElementName(element?: number | null): string { export function getElementName(element?: number | null): string {
switch (element) { switch (element) {
case 0: return 'Null' case 0:
case 1: return 'Wind' return 'Null'
case 2: return 'Fire' case 1:
case 3: return 'Water' return 'Wind'
case 4: return 'Earth' case 2:
case 5: return 'Dark' return 'Fire'
case 6: return 'Light' case 3:
default: return 'Unknown' return 'Water'
case 4:
return 'Earth'
case 5:
return 'Dark'
case 6:
return 'Light'
default:
return 'Unknown'
} }
} }