commit
492c2b40ed
36 changed files with 1343 additions and 214 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -51,6 +51,8 @@ public/images/weapon*
|
||||||
public/images/summon*
|
public/images/summon*
|
||||||
public/images/chara*
|
public/images/chara*
|
||||||
public/images/job*
|
public/images/job*
|
||||||
|
public/images/awakening*
|
||||||
|
public/images/ax*
|
||||||
|
|
||||||
# Typescript v1 declaration files
|
# Typescript v1 declaration files
|
||||||
typings/
|
typings/
|
||||||
|
|
|
||||||
31
components/AwakeningSelect/index.scss
Normal file
31
components/AwakeningSelect/index.scss
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
.AwakeningSelect .AwakeningSet {
|
||||||
|
.errors {
|
||||||
|
color: $error;
|
||||||
|
display: none;
|
||||||
|
padding: $unit 0;
|
||||||
|
|
||||||
|
&.visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: $unit;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.SelectTrigger {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Label {
|
||||||
|
flex-grow: 0;
|
||||||
|
|
||||||
|
.Input {
|
||||||
|
min-width: $unit * 12;
|
||||||
|
width: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
192
components/AwakeningSelect/index.tsx
Normal file
192
components/AwakeningSelect/index.tsx
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
import React, { ForwardedRef, useEffect, useState } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
|
||||||
|
import Input from '~components/Input'
|
||||||
|
import Select from '~components/Select'
|
||||||
|
import SelectItem from '~components/SelectItem'
|
||||||
|
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
import { weaponAwakening, characterAwakening } from '~utils/awakening'
|
||||||
|
import type { Awakening } from '~utils/awakening'
|
||||||
|
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
object: 'character' | 'weapon'
|
||||||
|
awakeningType?: number
|
||||||
|
awakeningLevel?: number
|
||||||
|
sendValidity: (isValid: boolean) => void
|
||||||
|
sendValues: (type: number, level: number) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const AwakeningSelect = (props: Props) => {
|
||||||
|
const router = useRouter()
|
||||||
|
const locale =
|
||||||
|
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
const awakeningLevelInput = React.createRef<HTMLInputElement>()
|
||||||
|
|
||||||
|
// States
|
||||||
|
const [awakeningType, setAwakeningType] = useState(-1)
|
||||||
|
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||||
|
|
||||||
|
const [maxValue, setMaxValue] = useState(1)
|
||||||
|
|
||||||
|
const [error, setError] = useState('')
|
||||||
|
|
||||||
|
// Classes
|
||||||
|
const inputClasses = classNames({
|
||||||
|
Bound: true,
|
||||||
|
Hidden: awakeningType === -1,
|
||||||
|
})
|
||||||
|
|
||||||
|
const errorClasses = classNames({
|
||||||
|
errors: true,
|
||||||
|
visible: error !== '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set max value based on object type
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.object === 'character') setMaxValue(9)
|
||||||
|
else if (props.object === 'weapon') setMaxValue(15)
|
||||||
|
}, [props.object])
|
||||||
|
|
||||||
|
// Set default awakening and level based on object type
|
||||||
|
useEffect(() => {
|
||||||
|
let defaultAwakening = 0
|
||||||
|
if (props.object === 'weapon') defaultAwakening = -1
|
||||||
|
|
||||||
|
setAwakeningType(
|
||||||
|
props.awakeningType != undefined ? props.awakeningType : defaultAwakening
|
||||||
|
)
|
||||||
|
setAwakeningLevel(props.awakeningLevel ? props.awakeningLevel : 1)
|
||||||
|
}, [props.object, props.awakeningType, props.awakeningLevel])
|
||||||
|
|
||||||
|
// Send awakening type and level when changed
|
||||||
|
useEffect(() => {
|
||||||
|
props.sendValues(awakeningType, awakeningLevel)
|
||||||
|
}, [props.sendValues, awakeningType, awakeningLevel])
|
||||||
|
|
||||||
|
// Send validity of form when awakening level changes
|
||||||
|
useEffect(() => {
|
||||||
|
props.sendValidity(awakeningLevel > 0 && error === '')
|
||||||
|
}, [props.sendValidity, awakeningLevel, error])
|
||||||
|
|
||||||
|
// Classes
|
||||||
|
function changeOpen() {
|
||||||
|
setOpen(!open)
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateOptions(object: 'character' | 'weapon') {
|
||||||
|
let options: Awakening[] = []
|
||||||
|
if (object === 'character') options = characterAwakening
|
||||||
|
else if (object === 'weapon') options = weaponAwakening
|
||||||
|
else return
|
||||||
|
|
||||||
|
let optionElements: React.ReactNode[] = options.map((awakening, i) => {
|
||||||
|
return (
|
||||||
|
<SelectItem key={i} value={awakening.id}>
|
||||||
|
{awakening.name[locale]}
|
||||||
|
</SelectItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (object === 'weapon') {
|
||||||
|
optionElements?.unshift(
|
||||||
|
<SelectItem key={-1} value={-1}>
|
||||||
|
{t('awakening.no_type')}
|
||||||
|
</SelectItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return optionElements
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelectChange(rawValue: string) {
|
||||||
|
const value = parseInt(rawValue)
|
||||||
|
setAwakeningType(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
const value = parseFloat(event.target.value)
|
||||||
|
if (handleLevelError(value)) setAwakeningLevel(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLevelError(value: number) {
|
||||||
|
let error = ''
|
||||||
|
if (value < 1) {
|
||||||
|
error = t('awakening.errors.value_too_low', {
|
||||||
|
minValue: 1,
|
||||||
|
})
|
||||||
|
} else if (value > maxValue) {
|
||||||
|
error = t('awakening.errors.value_too_high', {
|
||||||
|
maxValue: maxValue,
|
||||||
|
})
|
||||||
|
} else if (value % 1 != 0) {
|
||||||
|
error = t('awakening.errors.value_not_whole')
|
||||||
|
} else if (!value || value <= 0) {
|
||||||
|
error = t('awakening.errors.value_empty')
|
||||||
|
} else {
|
||||||
|
error = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
setError(error)
|
||||||
|
|
||||||
|
return error.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const rangeString = (object: 'character' | 'weapon') => {
|
||||||
|
let minValue = 1
|
||||||
|
let maxValue = 1
|
||||||
|
|
||||||
|
if (object === 'weapon') {
|
||||||
|
minValue = 1
|
||||||
|
maxValue = 15
|
||||||
|
} else if (object === 'character') {
|
||||||
|
minValue = 1
|
||||||
|
maxValue = 9
|
||||||
|
} else return
|
||||||
|
|
||||||
|
return `${minValue}~${maxValue}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="AwakeningSelect">
|
||||||
|
<div className="AwakeningSet">
|
||||||
|
<div className="fields">
|
||||||
|
<Select
|
||||||
|
key="awakening_type"
|
||||||
|
value={`${awakeningType}`}
|
||||||
|
open={open}
|
||||||
|
onValueChange={handleSelectChange}
|
||||||
|
onClick={() => changeOpen()}
|
||||||
|
triggerClass="modal"
|
||||||
|
>
|
||||||
|
{generateOptions(props.object)}
|
||||||
|
</Select>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
value={awakeningLevel}
|
||||||
|
className={inputClasses}
|
||||||
|
type="number"
|
||||||
|
placeholder={rangeString(props.object)}
|
||||||
|
min={1}
|
||||||
|
max={maxValue}
|
||||||
|
step="1"
|
||||||
|
onChange={handleInputChange}
|
||||||
|
ref={awakeningLevelInput}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p className={errorClasses}>{error}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AwakeningSelect
|
||||||
|
|
@ -23,25 +23,24 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: $unit;
|
gap: $unit;
|
||||||
|
|
||||||
select {
|
.SelectTrigger {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Input {
|
input {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
border: none;
|
border: none;
|
||||||
background-color: $grey-90;
|
border-radius: $input-corner;
|
||||||
border-radius: 6px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: $grey-15;
|
display: none;
|
||||||
height: $unit * 6;
|
|
||||||
display: block;
|
|
||||||
font-size: $font-regular;
|
|
||||||
padding: $unit;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
min-width: 100px;
|
min-width: $unit-14x;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
|
|
||||||
|
&.Visible {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { ForwardedRef, useEffect, useState } from 'react'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
|
|
||||||
|
import Select from '~components/Select'
|
||||||
|
import SelectItem from '~components/SelectItem'
|
||||||
|
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import { axData } from '~utils/axData'
|
import { axData } from '~utils/axData'
|
||||||
|
|
@ -32,6 +35,9 @@ const AXSelect = (props: Props) => {
|
||||||
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
|
const [openAX1, setOpenAX1] = useState(false)
|
||||||
|
const [openAX2, setOpenAX2] = useState(false)
|
||||||
|
|
||||||
// Set up form states and error handling
|
// Set up form states and error handling
|
||||||
const [errors, setErrors] = useState<ErrorMap>({
|
const [errors, setErrors] = useState<ErrorMap>({
|
||||||
axValue1: '',
|
axValue1: '',
|
||||||
|
|
@ -49,9 +55,9 @@ const AXSelect = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Refs
|
// Refs
|
||||||
const primaryAxModifierSelect = React.createRef<HTMLSelectElement>()
|
const primaryAxModifierSelect = React.createRef<HTMLButtonElement>()
|
||||||
const primaryAxValueInput = React.createRef<HTMLInputElement>()
|
const primaryAxValueInput = React.createRef<HTMLInputElement>()
|
||||||
const secondaryAxModifierSelect = React.createRef<HTMLSelectElement>()
|
const secondaryAxModifierSelect = React.createRef<HTMLButtonElement>()
|
||||||
const secondaryAxValueInput = React.createRef<HTMLInputElement>()
|
const secondaryAxValueInput = React.createRef<HTMLInputElement>()
|
||||||
|
|
||||||
// States
|
// States
|
||||||
|
|
@ -61,19 +67,8 @@ const AXSelect = (props: Props) => {
|
||||||
const [secondaryAxValue, setSecondaryAxValue] = useState(0.0)
|
const [secondaryAxValue, setSecondaryAxValue] = useState(0.0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.currentSkills && props.currentSkills[0]) {
|
setupAx1()
|
||||||
if (props.currentSkills[0].modifier != null)
|
setupAx2()
|
||||||
setPrimaryAxModifier(props.currentSkills[0].modifier)
|
|
||||||
|
|
||||||
setPrimaryAxValue(props.currentSkills[0].strength)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.currentSkills && props.currentSkills[1]) {
|
|
||||||
if (props.currentSkills[1].modifier != null)
|
|
||||||
setSecondaryAxModifier(props.currentSkills[1].modifier)
|
|
||||||
|
|
||||||
setSecondaryAxValue(props.currentSkills[1].strength)
|
|
||||||
}
|
|
||||||
}, [props.currentSkills])
|
}, [props.currentSkills])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -92,10 +87,68 @@ const AXSelect = (props: Props) => {
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
props.sendValidity(
|
if (
|
||||||
primaryAxValue > 0 && errors.axValue1 === '' && errors.axValue2 === ''
|
props.currentSkills &&
|
||||||
|
props.currentSkills[0].modifier != null &&
|
||||||
|
props.currentSkills[0].modifier >= 0
|
||||||
|
) {
|
||||||
|
setPrimaryAxModifier(props.currentSkills[0].modifier)
|
||||||
|
setPrimaryAxValue(props.currentSkills[0].strength)
|
||||||
|
} else setPrimaryAxModifier(-1)
|
||||||
|
}, [props.currentSkills, setPrimaryAxModifier])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.currentSkills && props.currentSkills[1].modifier) {
|
||||||
|
setSecondaryAxModifier(props.currentSkills[1].modifier)
|
||||||
|
setSecondaryAxValue(props.currentSkills[1].strength)
|
||||||
|
} else {
|
||||||
|
setSecondaryAxModifier(-1)
|
||||||
|
}
|
||||||
|
}, [props.currentSkills, setSecondaryAxModifier])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(
|
||||||
|
primaryAxModifier,
|
||||||
|
primaryAxValue,
|
||||||
|
secondaryAxModifier,
|
||||||
|
secondaryAxValue
|
||||||
)
|
)
|
||||||
}, [props, primaryAxValue, errors])
|
|
||||||
|
let noErrors = false
|
||||||
|
|
||||||
|
if (errors.axValue1 === '' && errors.axValue2 === '') {
|
||||||
|
if (primaryAxModifier === -1 && secondaryAxModifier === -1)
|
||||||
|
noErrors = true
|
||||||
|
else if (
|
||||||
|
primaryAxModifier >= 0 &&
|
||||||
|
primaryAxValue > 0 &&
|
||||||
|
secondaryAxModifier === -1
|
||||||
|
)
|
||||||
|
noErrors = true
|
||||||
|
else if (
|
||||||
|
primaryAxModifier >= 0 &&
|
||||||
|
primaryAxValue > 0 &&
|
||||||
|
secondaryAxModifier >= 0 &&
|
||||||
|
secondaryAxValue > 0
|
||||||
|
)
|
||||||
|
noErrors = true
|
||||||
|
else
|
||||||
|
console.log(
|
||||||
|
primaryAxModifier >= 0,
|
||||||
|
primaryAxValue > 0,
|
||||||
|
secondaryAxModifier >= 0,
|
||||||
|
secondaryAxValue > 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
props.sendValidity(noErrors)
|
||||||
|
}, [
|
||||||
|
primaryAxModifier,
|
||||||
|
primaryAxValue,
|
||||||
|
secondaryAxModifier,
|
||||||
|
secondaryAxValue,
|
||||||
|
errors,
|
||||||
|
])
|
||||||
|
|
||||||
// Classes
|
// Classes
|
||||||
const secondarySetClasses = classNames({
|
const secondarySetClasses = classNames({
|
||||||
|
|
@ -103,6 +156,62 @@ const AXSelect = (props: Props) => {
|
||||||
hidden: primaryAxModifier < 0,
|
hidden: primaryAxModifier < 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function setupAx1() {
|
||||||
|
if (
|
||||||
|
props.currentSkills &&
|
||||||
|
props.currentSkills[0] &&
|
||||||
|
// Should this be > -1 or != null
|
||||||
|
props.currentSkills[0].modifier != null
|
||||||
|
) {
|
||||||
|
setPrimaryAxModifier(props.currentSkills[0].modifier)
|
||||||
|
setPrimaryAxValue(props.currentSkills[0].strength)
|
||||||
|
|
||||||
|
if (props.currentSkills[0].modifier > -1 && primaryAxValueInput.current) {
|
||||||
|
const modifier = props.currentSkills[0].modifier
|
||||||
|
const axSkill = axData[props.axType - 1][modifier]
|
||||||
|
setupInput(axSkill, primaryAxValueInput.current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupAx2() {
|
||||||
|
if (
|
||||||
|
props.currentSkills &&
|
||||||
|
props.currentSkills[1] &&
|
||||||
|
// Should this be > -1 or != null
|
||||||
|
props.currentSkills[1].modifier != null
|
||||||
|
) {
|
||||||
|
const firstSkill = props.currentSkills[0]
|
||||||
|
const primaryAxSkill = axData[props.axType - 1][firstSkill.modifier]
|
||||||
|
const secondaryAxSkill = findSecondaryAxSkill(
|
||||||
|
primaryAxSkill,
|
||||||
|
props.currentSkills[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
props.currentSkills[1].modifier > -1 &&
|
||||||
|
secondaryAxValueInput.current
|
||||||
|
) {
|
||||||
|
setupInput(secondaryAxSkill, secondaryAxValueInput.current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findSecondaryAxSkill(
|
||||||
|
axSkill: AxSkill | undefined,
|
||||||
|
skillAtIndex: SimpleAxSkill
|
||||||
|
) {
|
||||||
|
if (axSkill)
|
||||||
|
return axSkill.secondary
|
||||||
|
? axSkill.secondary.find((skill) => skill.id === skillAtIndex.modifier)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSelect(ref: ForwardedRef<HTMLButtonElement>) {
|
||||||
|
if (ref === primaryAxModifierSelect) setOpenAX1(!openAX1)
|
||||||
|
if (ref === secondaryAxModifierSelect) setOpenAX2(!openAX2)
|
||||||
|
}
|
||||||
|
|
||||||
function generateOptions(modifierSet: number) {
|
function generateOptions(modifierSet: number) {
|
||||||
const axOptions = axData[props.axType - 1]
|
const axOptions = axData[props.axType - 1]
|
||||||
|
|
||||||
|
|
@ -110,9 +219,9 @@ const AXSelect = (props: Props) => {
|
||||||
if (modifierSet == 0) {
|
if (modifierSet == 0) {
|
||||||
axOptionElements = axOptions.map((ax, i) => {
|
axOptionElements = axOptions.map((ax, i) => {
|
||||||
return (
|
return (
|
||||||
<option key={i} value={ax.id}>
|
<SelectItem key={i} value={ax.id}>
|
||||||
{ax.name[locale]}
|
{ax.name[locale]}
|
||||||
</option>
|
</SelectItem>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -129,9 +238,9 @@ const AXSelect = (props: Props) => {
|
||||||
const secondaryAxOptions = primarySkill.secondary
|
const secondaryAxOptions = primarySkill.secondary
|
||||||
axOptionElements = secondaryAxOptions.map((ax, i) => {
|
axOptionElements = secondaryAxOptions.map((ax, i) => {
|
||||||
return (
|
return (
|
||||||
<option key={i} value={ax.id}>
|
<SelectItem key={i} value={ax.id}>
|
||||||
{ax.name[locale]}
|
{ax.name[locale]}
|
||||||
</option>
|
</SelectItem>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -139,39 +248,47 @@ const AXSelect = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
axOptionElements?.unshift(
|
axOptionElements?.unshift(
|
||||||
<option key={-1} value={-1}>
|
<SelectItem key={-1} value={-1}>
|
||||||
{t('ax.no_skill')}
|
{t('ax.no_skill')}
|
||||||
</option>
|
</SelectItem>
|
||||||
)
|
)
|
||||||
return axOptionElements
|
return axOptionElements
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSelectChange(event: React.ChangeEvent<HTMLSelectElement>) {
|
function handleAX1SelectChange(rawValue: string) {
|
||||||
const value = parseInt(event.target.value)
|
const value = parseInt(rawValue)
|
||||||
|
setPrimaryAxModifier(value)
|
||||||
|
|
||||||
if (primaryAxModifierSelect.current == event.target) {
|
if (
|
||||||
setPrimaryAxModifier(value)
|
primaryAxValueInput.current &&
|
||||||
|
secondaryAxModifierSelect.current &&
|
||||||
|
secondaryAxValueInput.current
|
||||||
|
) {
|
||||||
|
setupInput(axData[props.axType - 1][value], primaryAxValueInput.current)
|
||||||
|
setPrimaryAxValue(0)
|
||||||
|
primaryAxValueInput.current.value = ''
|
||||||
|
|
||||||
if (
|
// Reset the secondary AX modifier, reset the AX value and hide the input
|
||||||
primaryAxValueInput.current &&
|
setSecondaryAxModifier(-1)
|
||||||
secondaryAxModifierSelect.current &&
|
setSecondaryAxValue(0)
|
||||||
secondaryAxValueInput.current
|
secondaryAxValueInput.current.className = 'Input Contained'
|
||||||
) {
|
secondaryAxValueInput.current.value = ''
|
||||||
setupInput(axData[props.axType - 1][value], primaryAxValueInput.current)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
secondaryAxModifierSelect.current.value = '-1'
|
function handleAX2SelectChange(rawValue: string) {
|
||||||
secondaryAxValueInput.current.value = ''
|
const value = parseInt(rawValue)
|
||||||
}
|
setSecondaryAxModifier(value)
|
||||||
} else {
|
|
||||||
setSecondaryAxModifier(value)
|
|
||||||
|
|
||||||
const primaryAxSkill = axData[props.axType - 1][primaryAxModifier]
|
const primaryAxSkill = axData[props.axType - 1][primaryAxModifier]
|
||||||
const currentAxSkill = primaryAxSkill.secondary
|
const currentAxSkill = primaryAxSkill.secondary
|
||||||
? primaryAxSkill.secondary.find((skill) => skill.id == value)
|
? primaryAxSkill.secondary.find((skill) => skill.id == value)
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
if (secondaryAxValueInput.current)
|
if (secondaryAxValueInput.current) {
|
||||||
setupInput(currentAxSkill, secondaryAxValueInput.current)
|
setupInput(currentAxSkill, secondaryAxValueInput.current)
|
||||||
|
setSecondaryAxValue(0)
|
||||||
|
secondaryAxValueInput.current.value = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +316,7 @@ const AXSelect = (props: Props) => {
|
||||||
} else if (value > primaryAxSkill.maxValue) {
|
} else if (value > primaryAxSkill.maxValue) {
|
||||||
newErrors.axValue1 = t('ax.errors.value_too_high', {
|
newErrors.axValue1 = t('ax.errors.value_too_high', {
|
||||||
name: primaryAxSkill.name[locale],
|
name: primaryAxSkill.name[locale],
|
||||||
maxValue: primaryAxSkill.minValue,
|
maxValue: primaryAxSkill.maxValue,
|
||||||
suffix: primaryAxSkill.suffix ? primaryAxSkill.suffix : '',
|
suffix: primaryAxSkill.suffix ? primaryAxSkill.suffix : '',
|
||||||
})
|
})
|
||||||
} else if (!value || value <= 0) {
|
} else if (!value || value <= 0) {
|
||||||
|
|
@ -234,7 +351,7 @@ const AXSelect = (props: Props) => {
|
||||||
} else if (value > secondaryAxSkill.maxValue) {
|
} else if (value > secondaryAxSkill.maxValue) {
|
||||||
newErrors.axValue2 = t('ax.errors.value_too_high', {
|
newErrors.axValue2 = t('ax.errors.value_too_high', {
|
||||||
name: secondaryAxSkill.name[locale],
|
name: secondaryAxSkill.name[locale],
|
||||||
maxValue: secondaryAxSkill.minValue,
|
maxValue: secondaryAxSkill.maxValue,
|
||||||
suffix: secondaryAxSkill.suffix ? secondaryAxSkill.suffix : '',
|
suffix: secondaryAxSkill.suffix ? secondaryAxSkill.suffix : '',
|
||||||
})
|
})
|
||||||
} else if (!secondaryAxSkill.suffix && value % 1 !== 0) {
|
} else if (!secondaryAxSkill.suffix && value % 1 !== 0) {
|
||||||
|
|
@ -260,6 +377,7 @@ const AXSelect = (props: Props) => {
|
||||||
if (ax) {
|
if (ax) {
|
||||||
const rangeString = `${ax.minValue}~${ax.maxValue}${ax.suffix || ''}`
|
const rangeString = `${ax.minValue}~${ax.maxValue}${ax.suffix || ''}`
|
||||||
|
|
||||||
|
element.className = 'Input Bound Visible'
|
||||||
element.disabled = false
|
element.disabled = false
|
||||||
element.placeholder = rangeString
|
element.placeholder = rangeString
|
||||||
element.min = `${ax.minValue}`
|
element.min = `${ax.minValue}`
|
||||||
|
|
@ -268,10 +386,12 @@ const AXSelect = (props: Props) => {
|
||||||
} else {
|
} else {
|
||||||
if (primaryAxValueInput.current && secondaryAxValueInput.current) {
|
if (primaryAxValueInput.current && secondaryAxValueInput.current) {
|
||||||
if (primaryAxValueInput.current == element) {
|
if (primaryAxValueInput.current == element) {
|
||||||
|
primaryAxValueInput.current.className = 'Input Contained'
|
||||||
primaryAxValueInput.current.disabled = true
|
primaryAxValueInput.current.disabled = true
|
||||||
primaryAxValueInput.current.placeholder = ''
|
primaryAxValueInput.current.placeholder = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secondaryAxValueInput.current.className = 'Input Contained'
|
||||||
secondaryAxValueInput.current.disabled = true
|
secondaryAxValueInput.current.disabled = true
|
||||||
secondaryAxValueInput.current.placeholder = ''
|
secondaryAxValueInput.current.placeholder = ''
|
||||||
}
|
}
|
||||||
|
|
@ -282,29 +402,26 @@ const AXSelect = (props: Props) => {
|
||||||
<div className="AXSelect">
|
<div className="AXSelect">
|
||||||
<div className="AXSet">
|
<div className="AXSet">
|
||||||
<div className="fields">
|
<div className="fields">
|
||||||
<select
|
<Select
|
||||||
key="ax1"
|
key="ax1"
|
||||||
defaultValue={
|
value={`${primaryAxModifier}`}
|
||||||
props.currentSkills && props.currentSkills[0]
|
open={openAX1}
|
||||||
? props.currentSkills[0].modifier
|
onValueChange={handleAX1SelectChange}
|
||||||
: -1
|
onClick={() => openSelect(primaryAxModifierSelect)}
|
||||||
}
|
triggerClass="modal"
|
||||||
onChange={handleSelectChange}
|
|
||||||
ref={primaryAxModifierSelect}
|
|
||||||
>
|
>
|
||||||
{generateOptions(0)}
|
{generateOptions(0)}
|
||||||
</select>
|
</Select>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
defaultValue={
|
defaultValue={
|
||||||
props.currentSkills && props.currentSkills[0]
|
props.currentSkills && props.currentSkills[0]
|
||||||
? props.currentSkills[0].strength
|
? props.currentSkills[0].strength
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
className="Input"
|
|
||||||
type="number"
|
type="number"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
ref={primaryAxValueInput}
|
ref={primaryAxValueInput}
|
||||||
disabled={primaryAxValue != 0}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className={primaryErrorClasses}>{errors.axValue1}</p>
|
<p className={primaryErrorClasses}>{errors.axValue1}</p>
|
||||||
|
|
@ -312,29 +429,26 @@ const AXSelect = (props: Props) => {
|
||||||
|
|
||||||
<div className={secondarySetClasses}>
|
<div className={secondarySetClasses}>
|
||||||
<div className="fields">
|
<div className="fields">
|
||||||
<select
|
<Select
|
||||||
key="ax2"
|
key="ax2"
|
||||||
defaultValue={
|
value={`${secondaryAxModifier}`}
|
||||||
props.currentSkills && props.currentSkills[1]
|
open={openAX2}
|
||||||
? props.currentSkills[1].modifier
|
onValueChange={handleAX2SelectChange}
|
||||||
: -1
|
onClick={() => openSelect(secondaryAxModifierSelect)}
|
||||||
}
|
triggerClass="modal"
|
||||||
onChange={handleSelectChange}
|
|
||||||
ref={secondaryAxModifierSelect}
|
ref={secondaryAxModifierSelect}
|
||||||
>
|
>
|
||||||
{generateOptions(1)}
|
{generateOptions(1)}
|
||||||
</select>
|
</Select>
|
||||||
<input
|
<input
|
||||||
defaultValue={
|
defaultValue={
|
||||||
props.currentSkills && props.currentSkills[1]
|
props.currentSkills && props.currentSkills[1]
|
||||||
? props.currentSkills[1].strength
|
? props.currentSkills[1].strength
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
className="Input"
|
|
||||||
type="number"
|
type="number"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
ref={secondaryAxValueInput}
|
ref={secondaryAxValueInput}
|
||||||
disabled={secondaryAxValue != 0}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className={secondaryErrorClasses}>{errors.axValue2}</p>
|
<p className={secondaryErrorClasses}>{errors.axValue2}</p>
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background-color: var(--button-bg-disabled);
|
||||||
|
color: var(--button-text-disabled);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--button-bg-disabled);
|
||||||
|
color: var(--button-text-disabled);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.medium {
|
&.medium {
|
||||||
height: $unit * 5.5;
|
height: $unit * 5.5;
|
||||||
padding: ($unit * 1.5) $unit-2x;
|
padding: ($unit * 1.5) $unit-2x;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
.ToggleGroup {
|
.ToggleGroup {
|
||||||
$height: 36px;
|
$height: 36px;
|
||||||
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.14);
|
background-color: var(--toggle-bg);
|
||||||
|
border: 1px solid var(--toggle-stroke);
|
||||||
border-radius: $height;
|
border-radius: $height;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: $height;
|
height: $height;
|
||||||
|
|
@ -9,10 +10,10 @@
|
||||||
padding: calc($unit / 2);
|
padding: calc($unit / 2);
|
||||||
|
|
||||||
.ToggleItem {
|
.ToggleItem {
|
||||||
background: $grey-100;
|
background: var(--toggle-bg);
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
color: $grey-50;
|
color: var(--input-secondary);
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: $font-regular;
|
font-size: $font-regular;
|
||||||
padding: ($unit) $unit * 2;
|
padding: ($unit) $unit * 2;
|
||||||
|
|
@ -32,33 +33,33 @@
|
||||||
color: $grey-15;
|
color: $grey-15;
|
||||||
|
|
||||||
&.fire {
|
&.fire {
|
||||||
background: $fire-bg-20;
|
background: var(--fire-bg);
|
||||||
color: $fire-text-10;
|
color: var(--fire-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.water {
|
&.water {
|
||||||
background: $water-bg-20;
|
background: var(--water-bg);
|
||||||
color: $water-text-10;
|
color: var(--water-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.earth {
|
&.earth {
|
||||||
background: $earth-bg-20;
|
background: var(--earth-bg);
|
||||||
color: $earth-text-10;
|
color: var(--earth-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.wind {
|
&.wind {
|
||||||
background: $wind-bg-20;
|
background: var(--wind-bg);
|
||||||
color: $wind-text-10;
|
color: var(--wind-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.dark {
|
&.dark {
|
||||||
background: $dark-bg-10;
|
background: var(--dark-bg);
|
||||||
color: $dark-text-10;
|
color: var(--dark-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.light {
|
&.light {
|
||||||
background: $light-bg-20;
|
background: var(--light-bg);
|
||||||
color: $light-text-10;
|
color: var(--light-text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: block;
|
display: block;
|
||||||
padding: ($unit * 1.5) $unit-2x;
|
padding: $unit-2x;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&.Bound {
|
&.Bound {
|
||||||
|
|
@ -15,6 +15,10 @@
|
||||||
background-color: var(--input-bound-bg-hover);
|
background-color: var(--input-bound-bg-hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.Hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.InputError {
|
.InputError {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import React from 'react'
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
interface Props
|
interface Props
|
||||||
|
|
@ -11,12 +12,26 @@ interface Props
|
||||||
label?: string
|
label?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const Input = React.forwardRef<HTMLInputElement, Props>(function input(
|
const Input = React.forwardRef<HTMLInputElement, Props>(function Input(
|
||||||
props: Props,
|
props: Props,
|
||||||
forwardedRef
|
forwardedRef
|
||||||
) {
|
) {
|
||||||
|
// States
|
||||||
|
const [inputValue, setInputValue] = useState('')
|
||||||
|
|
||||||
|
// Classes
|
||||||
const classes = classNames({ Input: true }, props.className)
|
const classes = classNames({ Input: true }, props.className)
|
||||||
const { value, ...inputProps } = props
|
const { defaultValue, ...inputProps } = props
|
||||||
|
|
||||||
|
// Change value when prop updates
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.value) setInputValue(`${props.value}`)
|
||||||
|
}, [props.value])
|
||||||
|
|
||||||
|
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
setInputValue(event.target.value)
|
||||||
|
if (props.onChange) props.onChange(event)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className="Label" htmlFor={props.name}>
|
<label className="Label" htmlFor={props.name}>
|
||||||
|
|
@ -24,8 +39,9 @@ const Input = React.forwardRef<HTMLInputElement, Props>(function input(
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
className={classes}
|
className={classes}
|
||||||
defaultValue={props.value || ''}
|
value={inputValue}
|
||||||
ref={forwardedRef}
|
ref={forwardedRef}
|
||||||
|
onChange={handleChange}
|
||||||
formNoValidate
|
formNoValidate
|
||||||
/>
|
/>
|
||||||
{props.label}
|
{props.label}
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,6 @@ const Party = (props: Props) => {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(body)
|
|
||||||
|
|
||||||
return await api.endpoints.parties.create(body)
|
return await api.endpoints.parties.create(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
&.fire {
|
&.fire {
|
||||||
.Segment input:checked + label {
|
.Segment input:checked + label {
|
||||||
background: $fire-bg-10;
|
background: var(--fire-bg);
|
||||||
color: $fire-text-10;
|
color: var(--fire-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Segment:hover label {
|
.Segment:hover label {
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
&.water {
|
&.water {
|
||||||
.Segment input:checked + label {
|
.Segment input:checked + label {
|
||||||
background: $water-bg-10;
|
background: var(--water-bg);
|
||||||
color: $water-text-10;
|
color: var(--water-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Segment:hover label {
|
.Segment:hover label {
|
||||||
|
|
@ -39,8 +39,8 @@
|
||||||
|
|
||||||
&.earth {
|
&.earth {
|
||||||
.Segment input:checked + label {
|
.Segment input:checked + label {
|
||||||
background: $earth-bg-10;
|
background: var(--earth-bg);
|
||||||
color: $earth-text-10;
|
color: var(--earth-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Segment:hover label {
|
.Segment:hover label {
|
||||||
|
|
@ -51,8 +51,8 @@
|
||||||
|
|
||||||
&.wind {
|
&.wind {
|
||||||
.Segment input:checked + label {
|
.Segment input:checked + label {
|
||||||
background: $wind-bg-10;
|
background: var(--wind-bg);
|
||||||
color: $wind-text-10;
|
color: var(--wind-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Segment:hover label {
|
.Segment:hover label {
|
||||||
|
|
@ -63,8 +63,8 @@
|
||||||
|
|
||||||
&.light {
|
&.light {
|
||||||
.Segment input:checked + label {
|
.Segment input:checked + label {
|
||||||
background: $light-bg-10;
|
background: var(--light-bg);
|
||||||
color: $light-text-10;
|
color: var(--light-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Segment:hover label {
|
.Segment:hover label {
|
||||||
|
|
@ -75,8 +75,8 @@
|
||||||
|
|
||||||
&.dark {
|
&.dark {
|
||||||
.Segment input:checked + label {
|
.Segment input:checked + label {
|
||||||
background: $dark-bg-10;
|
background: var(--dark-bg);
|
||||||
color: $dark-text-10;
|
color: var(--dark-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Segment:hover label {
|
.Segment:hover label {
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,22 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: $unit-2x $unit-2x;
|
padding: $unit-2x $unit-2x;
|
||||||
|
|
||||||
|
&.modal {
|
||||||
|
background-color: var(--select-modal-bg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--select-modal-bg-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--input-bg-hover);
|
background-color: var(--input-bg-hover);
|
||||||
|
color: var(--text-primary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&[data-placeholder] > span:not(.SelectIcon) {
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&[data-placeholder] > span:not(.SelectIcon) {
|
&[data-placeholder] > span:not(.SelectIcon) {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@ interface Props
|
||||||
triggerClass?: string
|
triggerClass?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const Select = (props: Props) => {
|
const Select = React.forwardRef<HTMLButtonElement, Props>(function Select(
|
||||||
|
props: Props,
|
||||||
|
forwardedRef
|
||||||
|
) {
|
||||||
const [value, setValue] = useState('')
|
const [value, setValue] = useState('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -33,7 +36,6 @@ const Select = (props: Props) => {
|
||||||
if (props.onValueChange) props.onValueChange(newValue)
|
if (props.onValueChange) props.onValueChange(newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(value)
|
|
||||||
return (
|
return (
|
||||||
<RadixSelect.Root
|
<RadixSelect.Root
|
||||||
value={value !== '' ? value : undefined}
|
value={value !== '' ? value : undefined}
|
||||||
|
|
@ -42,6 +44,7 @@ const Select = (props: Props) => {
|
||||||
<RadixSelect.Trigger
|
<RadixSelect.Trigger
|
||||||
className={classNames('SelectTrigger', props.triggerClass)}
|
className={classNames('SelectTrigger', props.triggerClass)}
|
||||||
placeholder={props.placeholder}
|
placeholder={props.placeholder}
|
||||||
|
ref={forwardedRef}
|
||||||
>
|
>
|
||||||
<RadixSelect.Value placeholder={props.placeholder} />
|
<RadixSelect.Value placeholder={props.placeholder} />
|
||||||
<RadixSelect.Icon className="SelectIcon">
|
<RadixSelect.Icon className="SelectIcon">
|
||||||
|
|
@ -62,6 +65,6 @@ const Select = (props: Props) => {
|
||||||
</RadixSelect.Portal>
|
</RadixSelect.Portal>
|
||||||
</RadixSelect.Root>
|
</RadixSelect.Root>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
export default Select
|
export default Select
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
.SelectItem {
|
.SelectItem {
|
||||||
border-radius: $item-corner;
|
border-radius: $item-corner;
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
color: var(--text-secondary);
|
color: var(--text-tertiary);
|
||||||
font-size: $font-regular;
|
font-size: $font-regular;
|
||||||
padding: ($unit * 1.5) $unit-2x;
|
padding: ($unit * 1.5) $unit-2x;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import Select from '~components/Select'
|
||||||
|
import SelectGroup from '~components/SelectGroup'
|
||||||
|
import SelectItem from '~components/SelectItem'
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
@ -9,32 +12,27 @@ interface Props {
|
||||||
currentValue?: WeaponKey
|
currentValue?: WeaponKey
|
||||||
series: number
|
series: number
|
||||||
slot: number
|
slot: number
|
||||||
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void
|
onChange?: (value: string, slot: number) => void
|
||||||
onBlur?: (event: React.ChangeEvent<HTMLSelectElement>) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const WeaponKeyDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
const WeaponKeySelect = React.forwardRef<HTMLButtonElement, Props>(
|
||||||
function useFieldSet(props, ref) {
|
function useFieldSet(props, ref) {
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
const [keys, setKeys] = useState<WeaponKey[][]>([])
|
const [keys, setKeys] = useState<WeaponKey[][]>([])
|
||||||
const [currentKey, setCurrentKey] = useState('')
|
|
||||||
|
|
||||||
const pendulumNames = [
|
const pendulumNames = [
|
||||||
{ en: 'Pendulum', jp: '' },
|
{ en: 'Pendulum', jp: 'ペンデュラム' },
|
||||||
{ en: 'Chain', jp: '' },
|
{ en: 'Chain', jp: 'チェイン' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const telumaNames = [{ en: 'Teluma', jp: '' }]
|
const telumaNames = [{ en: 'Teluma', jp: 'テルマ' }]
|
||||||
const emblemNames = [{ en: 'Emblem', jp: '' }]
|
const emblemNames = [{ en: 'Emblem', jp: 'エンブレム' }]
|
||||||
const gauphNames = [
|
const gauphNames = [
|
||||||
{ en: 'Gauph Key', jp: '' },
|
{ en: 'Gauph Key', jp: 'ガフスキー' },
|
||||||
{ en: 'Ultima Key', jp: '' },
|
{ en: 'Ultima Key', jp: 'ガフスキーΩ' },
|
||||||
{ en: 'Gate of Omnipotence', jp: '' },
|
{ en: 'Gate of Omnipotence', jp: 'ガフスキー' },
|
||||||
]
|
]
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.currentValue) setCurrentKey(props.currentValue.id)
|
|
||||||
}, [props.currentValue])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filterParams = {
|
const filterParams = {
|
||||||
params: {
|
params: {
|
||||||
|
|
@ -50,22 +48,26 @@ const WeaponKeyDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
||||||
)
|
)
|
||||||
let groupedKeys = []
|
let groupedKeys = []
|
||||||
for (let i = 0; i <= numGroups; i++) {
|
for (let i = 0; i <= numGroups; i++) {
|
||||||
groupedKeys[i] = weaponKeys.filter((key) => key.group == i)
|
const values = weaponKeys.filter((key) => key.group == i)
|
||||||
|
if (values.length > 0) groupedKeys[i] = values
|
||||||
}
|
}
|
||||||
|
|
||||||
setKeys(groupedKeys)
|
setKeys(groupedKeys.filter(() => true))
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchWeaponKeys() {
|
function fetchWeaponKeys() {
|
||||||
api.endpoints.weapon_keys.getAll(filterParams).then((response) => {
|
api.endpoints.weapon_keys
|
||||||
const keys = response.data.map((k: any) => k.weapon_key)
|
.getAll(filterParams)
|
||||||
organizeWeaponKeys(keys)
|
.then((response) => organizeWeaponKeys(response.data))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchWeaponKeys()
|
fetchWeaponKeys()
|
||||||
}, [props.series, props.slot])
|
}, [props.series, props.slot])
|
||||||
|
|
||||||
|
function openSelect() {
|
||||||
|
setOpen(!open)
|
||||||
|
}
|
||||||
|
|
||||||
function weaponKeyGroup(index: number) {
|
function weaponKeyGroup(index: number) {
|
||||||
;['α', 'β', 'γ', 'Δ'].sort((a, b) => a.localeCompare(b, 'el'))
|
;['α', 'β', 'γ', 'Δ'].sort((a, b) => a.localeCompare(b, 'el'))
|
||||||
|
|
||||||
|
|
@ -78,9 +80,9 @@ const WeaponKeyDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
||||||
keys[index].length > 0 &&
|
keys[index].length > 0 &&
|
||||||
keys[index].sort(sortByOrder).map((item, i) => {
|
keys[index].sort(sortByOrder).map((item, i) => {
|
||||||
return (
|
return (
|
||||||
<option key={i} value={item.id}>
|
<SelectItem key={i} value={item.id}>
|
||||||
{item.name.en}
|
{item.name.en}
|
||||||
</option>
|
</SelectItem>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -88,26 +90,25 @@ const WeaponKeyDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
||||||
if (props.series == 2 && index == 0) name = pendulumNames[0]
|
if (props.series == 2 && index == 0) name = pendulumNames[0]
|
||||||
else if (props.series == 2 && props.slot == 1 && index == 1)
|
else if (props.series == 2 && props.slot == 1 && index == 1)
|
||||||
name = pendulumNames[1]
|
name = pendulumNames[1]
|
||||||
else if (props.series == 3) name = telumaNames[index]
|
else if (props.series == 3) name = telumaNames[0]
|
||||||
else if (props.series == 17) name = gauphNames[props.slot]
|
else if (props.series == 17) name = gauphNames[props.slot]
|
||||||
else if (props.series == 22) name = emblemNames[index]
|
else if (props.series == 24) name = emblemNames[index]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<optgroup
|
<SelectGroup
|
||||||
key={index}
|
key={index}
|
||||||
label={
|
label={
|
||||||
props.series == 17 && props.slot == 2 ? name.en : `${name.en}s`
|
props.series == 17 && props.slot == 2 ? name.en : `${name.en}s`
|
||||||
}
|
}
|
||||||
|
separator={false}
|
||||||
>
|
>
|
||||||
{options}
|
{options}
|
||||||
</optgroup>
|
</SelectGroup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChange(event: React.ChangeEvent<HTMLSelectElement>) {
|
function handleChange(value: string) {
|
||||||
if (props.onChange) props.onChange(event)
|
if (props.onChange) props.onChange(value, props.slot)
|
||||||
|
|
||||||
setCurrentKey(event.currentTarget.value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const emptyOption = () => {
|
const emptyOption = () => {
|
||||||
|
|
@ -115,28 +116,30 @@ const WeaponKeyDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
||||||
if (props.series == 2) name = pendulumNames[0].en
|
if (props.series == 2) name = pendulumNames[0].en
|
||||||
else if (props.series == 3) name = telumaNames[0].en
|
else if (props.series == 3) name = telumaNames[0].en
|
||||||
else if (props.series == 17) name = gauphNames[props.slot].en
|
else if (props.series == 17) name = gauphNames[props.slot].en
|
||||||
else if (props.series == 22) name = emblemNames[0].en
|
else if (props.series == 24) name = emblemNames[0].en
|
||||||
|
|
||||||
return `No ${name}`
|
return `No ${name}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<select
|
<Select
|
||||||
key={`weapon-key-${props.slot}`}
|
key={`weapon-key-${props.slot}`}
|
||||||
value={currentKey}
|
value={props.currentValue ? props.currentValue.id : 'no-key'}
|
||||||
onBlur={props.onBlur}
|
open={open}
|
||||||
onChange={handleChange}
|
onValueChange={handleChange}
|
||||||
|
onClick={openSelect}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
triggerClass="modal"
|
||||||
>
|
>
|
||||||
<option key="-1" value="-1">
|
<SelectItem key="no-key" value="no-key">
|
||||||
{emptyOption()}
|
{emptyOption()}
|
||||||
</option>
|
</SelectItem>
|
||||||
{Array.from(Array(keys?.length)).map((x, i) => {
|
{Array.from(Array(keys?.length)).map((x, i) => {
|
||||||
return weaponKeyGroup(i)
|
return weaponKeyGroup(i)
|
||||||
})}
|
})}
|
||||||
</select>
|
</Select>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export default WeaponKeyDropdown
|
export default WeaponKeySelect
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { getCookie } from 'cookies-next'
|
import { getCookie } from 'cookies-next'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
|
|
@ -7,8 +7,9 @@ import { AxiosResponse } from 'axios'
|
||||||
import * as Dialog from '@radix-ui/react-dialog'
|
import * as Dialog from '@radix-ui/react-dialog'
|
||||||
|
|
||||||
import AXSelect from '~components/AxSelect'
|
import AXSelect from '~components/AxSelect'
|
||||||
|
import AwakeningSelect from '~components/AwakeningSelect'
|
||||||
import ElementToggle from '~components/ElementToggle'
|
import ElementToggle from '~components/ElementToggle'
|
||||||
import WeaponKeyDropdown from '~components/WeaponKeyDropdown'
|
import WeaponKeySelect from '~components/WeaponKeySelect'
|
||||||
import Button from '~components/Button'
|
import Button from '~components/Button'
|
||||||
|
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
@ -27,6 +28,8 @@ interface GridWeaponObject {
|
||||||
ax_modifier2?: number
|
ax_modifier2?: number
|
||||||
ax_strength1?: number
|
ax_strength1?: number
|
||||||
ax_strength2?: number
|
ax_strength2?: number
|
||||||
|
awakening_type?: number
|
||||||
|
awakening_level?: Number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,21 +53,43 @@ const WeaponModal = (props: Props) => {
|
||||||
? { Authorization: `Bearer ${accountData.token}` }
|
? { Authorization: `Bearer ${accountData.token}` }
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
// Refs
|
|
||||||
const weaponKey1Select = React.createRef<HTMLSelectElement>()
|
|
||||||
const weaponKey2Select = React.createRef<HTMLSelectElement>()
|
|
||||||
const weaponKey3Select = React.createRef<HTMLSelectElement>()
|
|
||||||
|
|
||||||
// State
|
// State
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [formValid, setFormValid] = useState(false)
|
const [formValid, setFormValid] = useState(false)
|
||||||
|
|
||||||
const [element, setElement] = useState(-1)
|
const [element, setElement] = useState(-1)
|
||||||
|
|
||||||
|
const [awakeningType, setAwakeningType] = useState(-1)
|
||||||
|
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||||
|
|
||||||
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
||||||
const [secondaryAxModifier, setSecondaryAxModifier] = useState(-1)
|
const [secondaryAxModifier, setSecondaryAxModifier] = useState(-1)
|
||||||
const [primaryAxValue, setPrimaryAxValue] = useState(0.0)
|
const [primaryAxValue, setPrimaryAxValue] = useState(0.0)
|
||||||
const [secondaryAxValue, setSecondaryAxValue] = useState(0.0)
|
const [secondaryAxValue, setSecondaryAxValue] = useState(0.0)
|
||||||
|
|
||||||
|
const [weaponKey1, setWeaponKey1] = useState<WeaponKey | undefined>()
|
||||||
|
const [weaponKey2, setWeaponKey2] = useState<WeaponKey | undefined>()
|
||||||
|
const [weaponKey3, setWeaponKey3] = useState<WeaponKey | undefined>()
|
||||||
|
const [weaponKey1Id, setWeaponKey1Id] = useState('')
|
||||||
|
const [weaponKey2Id, setWeaponKey2Id] = useState('')
|
||||||
|
const [weaponKey3Id, setWeaponKey3Id] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setElement(props.gridWeapon.element)
|
||||||
|
|
||||||
|
if (props.gridWeapon.weapon_keys) {
|
||||||
|
props.gridWeapon.weapon_keys.forEach((key) => {
|
||||||
|
if (key.slot + 1 === 1) {
|
||||||
|
setWeaponKey1(key)
|
||||||
|
} else if (key.slot + 1 === 2) {
|
||||||
|
setWeaponKey2(key)
|
||||||
|
} else if (key.slot + 1 === 3) {
|
||||||
|
setWeaponKey3(key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [props])
|
||||||
|
|
||||||
function receiveAxValues(
|
function receiveAxValues(
|
||||||
primaryAxModifier: number,
|
primaryAxModifier: number,
|
||||||
primaryAxValue: number,
|
primaryAxValue: number,
|
||||||
|
|
@ -78,10 +103,15 @@ const WeaponModal = (props: Props) => {
|
||||||
setSecondaryAxValue(secondaryAxValue)
|
setSecondaryAxValue(secondaryAxValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
function receiveAxValidity(isValid: boolean) {
|
function receiveValidity(isValid: boolean) {
|
||||||
setFormValid(isValid)
|
setFormValid(isValid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function receiveAwakeningValues(type: number, level: number) {
|
||||||
|
setAwakeningType(type)
|
||||||
|
setAwakeningLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
function receiveElementValue(element: string) {
|
function receiveElementValue(element: string) {
|
||||||
setElement(parseInt(element))
|
setElement(parseInt(element))
|
||||||
}
|
}
|
||||||
|
|
@ -91,14 +121,18 @@ const WeaponModal = (props: Props) => {
|
||||||
|
|
||||||
if (props.gridWeapon.object.element == 0) object.weapon.element = element
|
if (props.gridWeapon.object.element == 0) object.weapon.element = element
|
||||||
|
|
||||||
if ([2, 3, 17, 24].includes(props.gridWeapon.object.series))
|
if (
|
||||||
object.weapon.weapon_key1_id = weaponKey1Select.current?.value
|
[2, 3, 17, 24].includes(props.gridWeapon.object.series) &&
|
||||||
|
weaponKey1Id
|
||||||
|
) {
|
||||||
|
object.weapon.weapon_key1_id = weaponKey1Id
|
||||||
|
}
|
||||||
|
|
||||||
if ([2, 3, 17].includes(props.gridWeapon.object.series))
|
if ([2, 3, 17].includes(props.gridWeapon.object.series) && weaponKey2Id)
|
||||||
object.weapon.weapon_key2_id = weaponKey2Select.current?.value
|
object.weapon.weapon_key2_id = weaponKey2Id
|
||||||
|
|
||||||
if (props.gridWeapon.object.series == 17)
|
if (props.gridWeapon.object.series == 17 && weaponKey3Id)
|
||||||
object.weapon.weapon_key3_id = weaponKey3Select.current?.value
|
object.weapon.weapon_key3_id = weaponKey3Id
|
||||||
|
|
||||||
if (props.gridWeapon.object.ax > 0) {
|
if (props.gridWeapon.object.ax > 0) {
|
||||||
object.weapon.ax_modifier1 = primaryAxModifier
|
object.weapon.ax_modifier1 = primaryAxModifier
|
||||||
|
|
@ -107,6 +141,11 @@ const WeaponModal = (props: Props) => {
|
||||||
object.weapon.ax_strength2 = secondaryAxValue
|
object.weapon.ax_strength2 = secondaryAxValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.gridWeapon.object.awakening) {
|
||||||
|
object.weapon.awakening_type = awakeningType
|
||||||
|
object.weapon.awakening_level = awakeningLevel
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +158,7 @@ const WeaponModal = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function processResult(response: AxiosResponse) {
|
function processResult(response: AxiosResponse) {
|
||||||
const gridWeapon: GridWeapon = response.data.grid_weapon
|
const gridWeapon: GridWeapon = response.data
|
||||||
|
|
||||||
if (gridWeapon.mainhand) appState.grid.weapons.mainWeapon = gridWeapon
|
if (gridWeapon.mainhand) appState.grid.weapons.mainWeapon = gridWeapon
|
||||||
else appState.grid.weapons.allWeapons[gridWeapon.position] = gridWeapon
|
else appState.grid.weapons.allWeapons[gridWeapon.position] = gridWeapon
|
||||||
|
|
@ -131,12 +170,18 @@ const WeaponModal = (props: Props) => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function receiveWeaponKey(value: string, slot: number) {
|
||||||
|
if (slot === 0) setWeaponKey1Id(value)
|
||||||
|
if (slot === 1) setWeaponKey2Id(value)
|
||||||
|
if (slot === 2) setWeaponKey3Id(value)
|
||||||
|
}
|
||||||
|
|
||||||
const elementSelect = () => {
|
const elementSelect = () => {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h3>{t('modals.weapon.subtitles.element')}</h3>
|
<h3>{t('modals.weapon.subtitles.element')}</h3>
|
||||||
<ElementToggle
|
<ElementToggle
|
||||||
currentElement={props.gridWeapon.element}
|
currentElement={element}
|
||||||
sendValue={receiveElementValue}
|
sendValue={receiveElementValue}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -148,45 +193,45 @@ const WeaponModal = (props: Props) => {
|
||||||
<section>
|
<section>
|
||||||
<h3>{t('modals.weapon.subtitles.weapon_keys')}</h3>
|
<h3>{t('modals.weapon.subtitles.weapon_keys')}</h3>
|
||||||
{[2, 3, 17, 22].includes(props.gridWeapon.object.series) ? (
|
{[2, 3, 17, 22].includes(props.gridWeapon.object.series) ? (
|
||||||
<WeaponKeyDropdown
|
<WeaponKeySelect
|
||||||
currentValue={
|
currentValue={weaponKey1 != null ? weaponKey1 : undefined}
|
||||||
props.gridWeapon.weapon_keys
|
|
||||||
? props.gridWeapon.weapon_keys[0]
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
series={props.gridWeapon.object.series}
|
series={props.gridWeapon.object.series}
|
||||||
slot={0}
|
slot={0}
|
||||||
ref={weaponKey1Select}
|
onChange={receiveWeaponKey}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{[2, 3, 17].includes(props.gridWeapon.object.series) ? (
|
{[2, 3, 17].includes(props.gridWeapon.object.series) ? (
|
||||||
<WeaponKeyDropdown
|
<WeaponKeySelect
|
||||||
currentValue={
|
currentValue={weaponKey2 != null ? weaponKey2 : undefined}
|
||||||
props.gridWeapon.weapon_keys
|
|
||||||
? props.gridWeapon.weapon_keys[1]
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
series={props.gridWeapon.object.series}
|
series={props.gridWeapon.object.series}
|
||||||
slot={1}
|
slot={1}
|
||||||
ref={weaponKey2Select}
|
onChange={receiveWeaponKey}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{props.gridWeapon.object.series == 17 ? (
|
{props.gridWeapon.object.series == 17 ? (
|
||||||
<WeaponKeyDropdown
|
<WeaponKeySelect
|
||||||
currentValue={
|
currentValue={weaponKey3 != null ? weaponKey3 : undefined}
|
||||||
props.gridWeapon.weapon_keys
|
|
||||||
? props.gridWeapon.weapon_keys[2]
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
series={props.gridWeapon.object.series}
|
series={props.gridWeapon.object.series}
|
||||||
slot={2}
|
slot={2}
|
||||||
ref={weaponKey3Select}
|
onChange={receiveWeaponKey}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
|
||||||
|
{props.gridWeapon.object.series == 24 &&
|
||||||
|
props.gridWeapon.object.uncap.ulb ? (
|
||||||
|
<WeaponKeySelect
|
||||||
|
currentValue={weaponKey1 != null ? weaponKey1 : undefined}
|
||||||
|
series={props.gridWeapon.object.series}
|
||||||
|
slot={0}
|
||||||
|
onChange={receiveWeaponKey}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
|
|
@ -202,19 +247,39 @@ const WeaponModal = (props: Props) => {
|
||||||
<AXSelect
|
<AXSelect
|
||||||
axType={props.gridWeapon.object.ax}
|
axType={props.gridWeapon.object.ax}
|
||||||
currentSkills={props.gridWeapon.ax}
|
currentSkills={props.gridWeapon.ax}
|
||||||
sendValidity={receiveAxValidity}
|
sendValidity={receiveValidity}
|
||||||
sendValues={receiveAxValues}
|
sendValues={receiveAxValues}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const awakeningSelect = () => {
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<h3>{t('modals.weapon.subtitles.awakening')}</h3>
|
||||||
|
<AwakeningSelect
|
||||||
|
object="weapon"
|
||||||
|
awakeningType={props.gridWeapon.awakening?.type}
|
||||||
|
awakeningLevel={props.gridWeapon.awakening?.level}
|
||||||
|
sendValidity={receiveValidity}
|
||||||
|
sendValues={receiveAwakeningValues}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function openChange(open: boolean) {
|
function openChange(open: boolean) {
|
||||||
setFormValid(false)
|
if (props.gridWeapon.object.ax > 0 || props.gridWeapon.object.awakening) {
|
||||||
|
setFormValid(false)
|
||||||
|
} else {
|
||||||
|
setFormValid(true)
|
||||||
|
}
|
||||||
setOpen(open)
|
setOpen(open)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
// TODO: Refactor into Dialog component
|
||||||
<Dialog.Root open={open} onOpenChange={openChange}>
|
<Dialog.Root open={open} onOpenChange={openChange}>
|
||||||
<Dialog.Trigger asChild>{props.children}</Dialog.Trigger>
|
<Dialog.Trigger asChild>{props.children}</Dialog.Trigger>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
|
|
@ -244,9 +309,11 @@ const WeaponModal = (props: Props) => {
|
||||||
? keySelect()
|
? keySelect()
|
||||||
: ''}
|
: ''}
|
||||||
{props.gridWeapon.object.ax > 0 ? axSelect() : ''}
|
{props.gridWeapon.object.ax > 0 ? axSelect() : ''}
|
||||||
|
{props.gridWeapon.awakening ? awakeningSelect() : ''}
|
||||||
<Button
|
<Button
|
||||||
|
contained={true}
|
||||||
onClick={updateWeapon}
|
onClick={updateWeapon}
|
||||||
disabled={props.gridWeapon.object.ax > 0 && !formValid}
|
disabled={!formValid}
|
||||||
text={t('modals.weapon.buttons.confirm')}
|
text={t('modals.weapon.buttons.confirm')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,23 @@
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
|
.Awakening {
|
||||||
|
width: 40%;
|
||||||
|
height: auto;
|
||||||
|
top: 67%;
|
||||||
|
left: -3.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Modifiers > .Skills {
|
||||||
|
bottom: 12%;
|
||||||
|
right: -3.5%;
|
||||||
|
|
||||||
|
& > .Skill {
|
||||||
|
width: 25%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: $medium-screen) {
|
@media (max-width: $medium-screen) {
|
||||||
width: 25vw;
|
width: 25vw;
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +73,23 @@
|
||||||
width: 160px;
|
width: 160px;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
|
.Awakening {
|
||||||
|
width: 30%;
|
||||||
|
height: auto;
|
||||||
|
top: 14%;
|
||||||
|
left: -3.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Modifiers > .Skills {
|
||||||
|
bottom: 12%;
|
||||||
|
left: -3.5%;
|
||||||
|
|
||||||
|
& > .Skill {
|
||||||
|
width: 20%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: $medium-screen) {
|
@media (max-width: $medium-screen) {
|
||||||
width: 20vw;
|
width: 20vw;
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +115,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: $unit;
|
left: $unit;
|
||||||
top: $unit;
|
top: $unit;
|
||||||
z-index: 3;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
|
|
@ -102,12 +136,37 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: calc($unit / 4);
|
margin-bottom: calc($unit / 4);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
transition: all 0.18s ease-in-out;
|
transition: all 0.18s ease-in-out;
|
||||||
|
|
||||||
&:hover .icon svg {
|
&:hover .icon svg {
|
||||||
fill: var(--icon-secondary-hover);
|
fill: var(--icon-secondary-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Awakening {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Modifiers {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
|
||||||
|
.Skills {
|
||||||
|
display: flex;
|
||||||
|
gap: $unit-fourth;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding: $unit-half;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,12 @@ import WeaponHovercard from '~components/WeaponHovercard'
|
||||||
import UncapIndicator from '~components/UncapIndicator'
|
import UncapIndicator from '~components/UncapIndicator'
|
||||||
import Button from '~components/Button'
|
import Button from '~components/Button'
|
||||||
|
|
||||||
import { ButtonType } from '~utils/enums'
|
|
||||||
import type { SearchableObject } from '~types'
|
import type { SearchableObject } from '~types'
|
||||||
|
|
||||||
|
import { appState } from '~utils/appState'
|
||||||
|
import { axData } from '~utils/axData'
|
||||||
|
import { weaponAwakening } from '~utils/awakening'
|
||||||
|
|
||||||
import PlusIcon from '~public/icons/Add.svg'
|
import PlusIcon from '~public/icons/Add.svg'
|
||||||
import SettingsIcon from '~public/icons/Settings.svg'
|
import SettingsIcon from '~public/icons/Settings.svg'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
@ -71,6 +74,265 @@ const WeaponUnit = (props: Props) => {
|
||||||
setImageUrl(imgSrc)
|
setImageUrl(imgSrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function awakeningImage() {
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.awakening &&
|
||||||
|
props.gridWeapon.awakening &&
|
||||||
|
props.gridWeapon.awakening.type >= 0
|
||||||
|
) {
|
||||||
|
const awakening = weaponAwakening.find(
|
||||||
|
(awakening) => awakening.id === props.gridWeapon?.awakening?.type
|
||||||
|
)
|
||||||
|
const name = awakening?.name[locale]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
alt={`${name} Lv${props.gridWeapon.awakening.level}`}
|
||||||
|
className="Awakening"
|
||||||
|
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/awakening/weapon_${props.gridWeapon.awakening.type}.png`}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function telumaImage(index: number) {
|
||||||
|
const baseUrl = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-keys/`
|
||||||
|
let filename = ''
|
||||||
|
let altText = ''
|
||||||
|
|
||||||
|
// If there is a grid weapon, it is a Draconic Weapon and it has keys
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.series === 3 &&
|
||||||
|
props.gridWeapon.weapon_keys
|
||||||
|
) {
|
||||||
|
if (index === 0 && props.gridWeapon.weapon_keys[0]) {
|
||||||
|
altText = `${props.gridWeapon.weapon_keys[0].name[locale]}`
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[0].slug}.png`
|
||||||
|
} else if (index === 1 && props.gridWeapon.weapon_keys[1]) {
|
||||||
|
altText = `${props.gridWeapon.weapon_keys[1].name[locale]}`
|
||||||
|
|
||||||
|
const element = props.gridWeapon.object.element
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[1].slug}-${element}.png`
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
alt={altText}
|
||||||
|
key={altText}
|
||||||
|
className="Skill"
|
||||||
|
src={`${baseUrl}${filename}`}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function telumaImages() {
|
||||||
|
let images: JSX.Element[] = []
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.series === 3 &&
|
||||||
|
props.gridWeapon.weapon_keys &&
|
||||||
|
props.gridWeapon.weapon_keys.length > 0
|
||||||
|
) {
|
||||||
|
for (let i = 0; i < props.gridWeapon.weapon_keys.length; i++) {
|
||||||
|
const image = telumaImage(i)
|
||||||
|
if (image) images.push(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images
|
||||||
|
}
|
||||||
|
|
||||||
|
function ultimaImage(index: number) {
|
||||||
|
const baseUrl = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-keys/`
|
||||||
|
let filename = ''
|
||||||
|
let altText = ''
|
||||||
|
|
||||||
|
// If there is a grid weapon, it is a Dark Opus Weapon and it has keys
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.series === 17 &&
|
||||||
|
props.gridWeapon.weapon_keys
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
props.gridWeapon.weapon_keys[index] &&
|
||||||
|
(props.gridWeapon.weapon_keys[index].slot === 1 ||
|
||||||
|
props.gridWeapon.weapon_keys[index].slot === 2)
|
||||||
|
) {
|
||||||
|
altText = `${props.gridWeapon.weapon_keys[index].name[locale]}`
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[index].slug}.png`
|
||||||
|
} else if (
|
||||||
|
props.gridWeapon.weapon_keys[index] &&
|
||||||
|
props.gridWeapon.weapon_keys[index].slot === 0
|
||||||
|
) {
|
||||||
|
altText = `${props.gridWeapon.weapon_keys[index].name[locale]}`
|
||||||
|
|
||||||
|
const weapon = props.gridWeapon.object.proficiency
|
||||||
|
|
||||||
|
const suffix = `${weapon}`
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[index].slug}-${suffix}.png`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<img alt={`${altText}`} className="Skill" src={`${baseUrl}${filename}`} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ultimaImages() {
|
||||||
|
let images: JSX.Element[] = []
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.series === 17 &&
|
||||||
|
props.gridWeapon.weapon_keys &&
|
||||||
|
props.gridWeapon.weapon_keys.length > 0
|
||||||
|
) {
|
||||||
|
for (let i = 0; i < props.gridWeapon.weapon_keys.length; i++) {
|
||||||
|
const image = ultimaImage(i)
|
||||||
|
if (image) images.push(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images
|
||||||
|
}
|
||||||
|
|
||||||
|
function opusImage(index: number) {
|
||||||
|
const baseUrl = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-keys/`
|
||||||
|
let filename = ''
|
||||||
|
let altText = ''
|
||||||
|
|
||||||
|
// If there is a grid weapon, it is a Dark Opus Weapon and it has keys
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.series === 2 &&
|
||||||
|
props.gridWeapon.weapon_keys
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
props.gridWeapon.weapon_keys[index] &&
|
||||||
|
props.gridWeapon.weapon_keys[index].slot === 0
|
||||||
|
) {
|
||||||
|
altText = `${props.gridWeapon.weapon_keys[index].name[locale]}`
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[index].slug}.png`
|
||||||
|
} else if (
|
||||||
|
props.gridWeapon.weapon_keys[index] &&
|
||||||
|
props.gridWeapon.weapon_keys[index].slot === 1
|
||||||
|
) {
|
||||||
|
altText = `${props.gridWeapon.weapon_keys[index].name[locale]}`
|
||||||
|
|
||||||
|
const element = props.gridWeapon.object.element
|
||||||
|
const mod = props.gridWeapon.object.name.en.includes('Repudiation')
|
||||||
|
? 'primal'
|
||||||
|
: 'magna'
|
||||||
|
|
||||||
|
const suffix = `${mod}-${element}`
|
||||||
|
const weaponKey = props.gridWeapon.weapon_keys[index]
|
||||||
|
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'pendulum-strength',
|
||||||
|
'pendulum-zeal',
|
||||||
|
'pendulum-strife',
|
||||||
|
'chain-temperament',
|
||||||
|
'chain-restoration',
|
||||||
|
'chain-glorification',
|
||||||
|
].includes(weaponKey.slug)
|
||||||
|
) {
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[index].slug}-${suffix}.png`
|
||||||
|
} else {
|
||||||
|
filename = `${props.gridWeapon.weapon_keys[index].slug}.png`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
alt={altText}
|
||||||
|
key={altText}
|
||||||
|
className="Skill"
|
||||||
|
src={`${baseUrl}${filename}`}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function opusImages() {
|
||||||
|
let images: JSX.Element[] = []
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.series === 2 &&
|
||||||
|
props.gridWeapon.weapon_keys &&
|
||||||
|
props.gridWeapon.weapon_keys.length > 0
|
||||||
|
) {
|
||||||
|
for (let i = 0; i < props.gridWeapon.weapon_keys.length; i++) {
|
||||||
|
const image = opusImage(i)
|
||||||
|
if (image) images.push(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images
|
||||||
|
}
|
||||||
|
|
||||||
|
function axImage(index: number) {
|
||||||
|
const axSkill = getCanonicalAxSkill(index)
|
||||||
|
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.ax &&
|
||||||
|
props.gridWeapon.object.ax > 0 &&
|
||||||
|
props.gridWeapon.ax &&
|
||||||
|
axSkill
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
alt={`axskill`}
|
||||||
|
className="Skill"
|
||||||
|
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/ax/${axSkill.slug}.png`}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function axImages() {
|
||||||
|
let images: JSX.Element[] = []
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.ax > 0 &&
|
||||||
|
props.gridWeapon.ax &&
|
||||||
|
props.gridWeapon.ax.length > 0
|
||||||
|
) {
|
||||||
|
for (let i = 0; i < props.gridWeapon.ax.length; i++) {
|
||||||
|
const image = axImage(i)
|
||||||
|
if (image) images.push(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCanonicalAxSkill(index: number) {
|
||||||
|
if (
|
||||||
|
props.gridWeapon &&
|
||||||
|
props.gridWeapon.object.ax &&
|
||||||
|
props.gridWeapon.object.ax > 0 &&
|
||||||
|
props.gridWeapon.ax
|
||||||
|
) {
|
||||||
|
const axOptions = axData[props.gridWeapon.object.ax - 1]
|
||||||
|
const weaponAxSkill: SimpleAxSkill = props.gridWeapon.ax[0]
|
||||||
|
|
||||||
|
let axSkill = axOptions.find((ax) => ax.id === weaponAxSkill.modifier)
|
||||||
|
|
||||||
|
if (index !== 0 && axSkill && axSkill.secondary) {
|
||||||
|
const weaponSubAxSkill: SimpleAxSkill = props.gridWeapon.ax[1]
|
||||||
|
axSkill = axSkill.secondary.find(
|
||||||
|
(ax) => ax.id === weaponSubAxSkill.modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return axSkill
|
||||||
|
} else return
|
||||||
|
}
|
||||||
|
|
||||||
function passUncapData(uncap: number) {
|
function passUncapData(uncap: number) {
|
||||||
if (props.gridWeapon)
|
if (props.gridWeapon)
|
||||||
props.updateUncap(props.gridWeapon.id, props.position, uncap)
|
props.updateUncap(props.gridWeapon.id, props.position, uncap)
|
||||||
|
|
@ -81,12 +343,22 @@ const WeaponUnit = (props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
weapon.ax > 0 ||
|
weapon.ax > 0 ||
|
||||||
|
weapon.awakening ||
|
||||||
(weapon.series && [2, 3, 17, 22, 24].includes(weapon.series))
|
(weapon.series && [2, 3, 17, 22, 24].includes(weapon.series))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const image = (
|
const image = (
|
||||||
<div className="WeaponImage">
|
<div className="WeaponImage">
|
||||||
|
<div className="Modifiers">
|
||||||
|
{awakeningImage()}
|
||||||
|
<div className="Skills">
|
||||||
|
{axImages()}
|
||||||
|
{telumaImages()}
|
||||||
|
{opusImages()}
|
||||||
|
{ultimaImages()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<img alt={weapon?.name.en} className="grid_image" src={imageUrl} />
|
<img alt={weapon?.name.en} className="grid_image" src={imageUrl} />
|
||||||
{props.editable ? (
|
{props.editable ? (
|
||||||
<span className="icon">
|
<span className="icon">
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,20 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
import Party from '~components/Party'
|
import Party from '~components/Party'
|
||||||
|
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import { groupWeaponKeys } from '~utils/groupWeaponKeys'
|
||||||
import organizeRaids from '~utils/organizeRaids'
|
import organizeRaids from '~utils/organizeRaids'
|
||||||
import setUserToken from '~utils/setUserToken'
|
import setUserToken from '~utils/setUserToken'
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
import type { GroupedWeaponKeys } from '~utils/groupWeaponKeys'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
jobs: Job[]
|
jobs: Job[]
|
||||||
jobSkills: JobSkill[]
|
jobSkills: JobSkill[]
|
||||||
raids: Raid[]
|
raids: Raid[]
|
||||||
sortedRaids: Raid[][]
|
sortedRaids: Raid[][]
|
||||||
|
weaponKeys: GroupedWeaponKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
const NewRoute: React.FC<Props> = (props: Props) => {
|
const NewRoute: React.FC<Props> = (props: Props) => {
|
||||||
|
|
@ -31,6 +34,7 @@ const NewRoute: React.FC<Props> = (props: Props) => {
|
||||||
appState.raids = props.raids
|
appState.raids = props.raids
|
||||||
appState.jobs = props.jobs
|
appState.jobs = props.jobs
|
||||||
appState.jobSkills = props.jobSkills
|
appState.jobSkills = props.jobSkills
|
||||||
|
appState.weaponKeys = props.weaponKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Party new={true} raids={props.sortedRaids} pushHistory={callback} />
|
return <Party new={true} raids={props.sortedRaids} pushHistory={callback} />
|
||||||
|
|
@ -61,9 +65,11 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
||||||
return response.data
|
return response.data
|
||||||
})
|
})
|
||||||
|
|
||||||
let jobSkills = await api.allJobSkills().then((response) => {
|
let jobSkills = await api.allJobSkills().then((response) => response.data)
|
||||||
return response.data
|
|
||||||
})
|
let weaponKeys = await api.endpoints.weapon_keys
|
||||||
|
.getAll()
|
||||||
|
.then((response) => groupWeaponKeys(response.data))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -71,6 +77,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
||||||
jobSkills: jobSkills,
|
jobSkills: jobSkills,
|
||||||
raids: raids,
|
raids: raids,
|
||||||
sortedRaids: sortedRaids,
|
sortedRaids: sortedRaids,
|
||||||
|
weaponKeys: weaponKeys,
|
||||||
...(await serverSideTranslations(locale, ['common'])),
|
...(await serverSideTranslations(locale, ['common'])),
|
||||||
// Will be passed to the page component as props
|
// Will be passed to the page component as props
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,12 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
import Party from '~components/Party'
|
import Party from '~components/Party'
|
||||||
|
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
|
import { groupWeaponKeys } from '~utils/groupWeaponKeys'
|
||||||
import organizeRaids from '~utils/organizeRaids'
|
import organizeRaids from '~utils/organizeRaids'
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
import type { GroupedWeaponKeys } from '~utils/groupWeaponKeys'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
party: Party
|
party: Party
|
||||||
|
|
@ -16,6 +18,7 @@ interface Props {
|
||||||
jobSkills: JobSkill[]
|
jobSkills: JobSkill[]
|
||||||
raids: Raid[]
|
raids: Raid[]
|
||||||
sortedRaids: Raid[][]
|
sortedRaids: Raid[][]
|
||||||
|
weaponKeys: GroupedWeaponKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
const PartyRoute: React.FC<Props> = (props: Props) => {
|
const PartyRoute: React.FC<Props> = (props: Props) => {
|
||||||
|
|
@ -27,6 +30,7 @@ const PartyRoute: React.FC<Props> = (props: Props) => {
|
||||||
appState.raids = props.raids
|
appState.raids = props.raids
|
||||||
appState.jobs = props.jobs
|
appState.jobs = props.jobs
|
||||||
appState.jobSkills = props.jobSkills
|
appState.jobSkills = props.jobSkills
|
||||||
|
appState.weaponKeys = props.weaponKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Party team={props.party} raids={props.sortedRaids} />
|
return <Party team={props.party} raids={props.sortedRaids} />
|
||||||
|
|
@ -65,6 +69,10 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
||||||
})
|
})
|
||||||
|
|
||||||
let jobSkills = await api.allJobSkills(headers).then((response) => response.data)
|
let jobSkills = await api.allJobSkills(headers).then((response) => response.data)
|
||||||
|
|
||||||
|
let weaponKeys = await api.endpoints.weapon_keys
|
||||||
|
.getAll()
|
||||||
|
.then((response) => groupWeaponKeys(response.data))
|
||||||
|
|
||||||
let party: Party | null = null
|
let party: Party | null = null
|
||||||
if (query.party) {
|
if (query.party) {
|
||||||
|
|
@ -81,6 +89,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
||||||
jobSkills: jobSkills,
|
jobSkills: jobSkills,
|
||||||
raids: raids,
|
raids: raids,
|
||||||
sortedRaids: sortedRaids,
|
sortedRaids: sortedRaids,
|
||||||
|
weaponKeys: weaponKeys,
|
||||||
...(await serverSideTranslations(locale, ["common"])),
|
...(await serverSideTranslations(locale, ["common"])),
|
||||||
// Will be passed to the page component as props
|
// Will be passed to the page component as props
|
||||||
},
|
},
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 2.3 KiB |
|
|
@ -8,6 +8,15 @@
|
||||||
"value_empty": "{{name}} must have a value"
|
"value_empty": "{{name}} must have a value"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"awakening": {
|
||||||
|
"no_type": "No awakening",
|
||||||
|
"errors": {
|
||||||
|
"value_too_low": "Awakening level must be at least {{minValue}}",
|
||||||
|
"value_too_high": "Awakening level cannot be greater than {{maxValue}}",
|
||||||
|
"value_not_whole": "Awakening level must be a whole number",
|
||||||
|
"value_empty": "Awakening must have a level"
|
||||||
|
}
|
||||||
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"copy": "Copy link",
|
"copy": "Copy link",
|
||||||
|
|
@ -192,6 +201,7 @@
|
||||||
"subtitles": {
|
"subtitles": {
|
||||||
"element": "Element",
|
"element": "Element",
|
||||||
"ax_skills": "AX Skills",
|
"ax_skills": "AX Skills",
|
||||||
|
"awakening": "Awakening",
|
||||||
"weapon_keys": "Weapon Keys"
|
"weapon_keys": "Weapon Keys"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,20 @@
|
||||||
"no_skill": "EXスキルなし",
|
"no_skill": "EXスキルなし",
|
||||||
"errors": {
|
"errors": {
|
||||||
"value_too_low": "{{name}}は最低{{minValue}}{{suffix}}を入力してください",
|
"value_too_low": "{{name}}は最低{{minValue}}{{suffix}}を入力してください",
|
||||||
"value_too_high": "{{name}}は最大{{maxValue}}を入力してください",
|
"value_too_high": "{{name}}は最大{{maxValue}}{{suffix}}を入力してください",
|
||||||
"value_not_whole": "{{name}}は整数でなければなりません",
|
"value_not_whole": "{{name}}は整数でなければなりません",
|
||||||
"value_empty": "{{name}}を入力してください"
|
"value_empty": "{{name}}を入力してください"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"awakening": {
|
||||||
|
"no_type": "覚醒タイプなし",
|
||||||
|
"errors": {
|
||||||
|
"value_too_low": "覚醒レベルは最低{{minValue}}を入力してください",
|
||||||
|
"value_too_high": "覚醒レベルは最大{{maxValue}}を入力してください",
|
||||||
|
"value_not_whole": "覚醒レベルは整数でなければなりません",
|
||||||
|
"value_empty": "覚醒レベルを入力してください"
|
||||||
|
}
|
||||||
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"cancel": "キャンセルs",
|
"cancel": "キャンセルs",
|
||||||
"copy": "リンクをコピー",
|
"copy": "リンクをコピー",
|
||||||
|
|
@ -193,6 +202,7 @@
|
||||||
"subtitles": {
|
"subtitles": {
|
||||||
"element": "属性",
|
"element": "属性",
|
||||||
"ax_skills": "EXスキル",
|
"ax_skills": "EXスキル",
|
||||||
|
"awakening": "覚醒",
|
||||||
"weapon_keys": "武器スキル"
|
"weapon_keys": "武器スキル"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
--select-bg: #{$select--bg--light};
|
--select-bg: #{$select--bg--light};
|
||||||
--select-contained-bg: #{$select--contained--bg--light};
|
--select-contained-bg: #{$select--contained--bg--light};
|
||||||
--select-contained-bg-hover: #{$select--contained--bg--light--hover};
|
--select-contained-bg-hover: #{$select--contained--bg--light--hover};
|
||||||
|
--select-modal-bg: #{$select--modal--bg--light};
|
||||||
|
--select-modal-bg-hover: #{$select--modal--bg--light--hover};
|
||||||
--select-separator: #{$select--separator--light};
|
--select-separator: #{$select--separator--light};
|
||||||
--option-bg-hover: #{$option--bg--light--hover};
|
--option-bg-hover: #{$option--bg--light--hover};
|
||||||
|
|
||||||
|
|
@ -72,19 +74,40 @@
|
||||||
--subaura-orange-secondary: #{$subaura--orange--secondary--light};
|
--subaura-orange-secondary: #{$subaura--orange--secondary--light};
|
||||||
--subaura-orange-text: #{$subaura--orange--text--light};
|
--subaura-orange-text: #{$subaura--orange--text--light};
|
||||||
|
|
||||||
|
// Light - Element Toggle
|
||||||
|
--toggle-bg: #{$toggle--bg--light};
|
||||||
|
--toggle-stroke: #{$toggle--stroke--light};
|
||||||
|
|
||||||
--grid-border-color: #{$grid--border--color--light};
|
--grid-border-color: #{$grid--border--color--light};
|
||||||
|
|
||||||
|
--wind-bg: #{$wind-bg-10};
|
||||||
--wind-hover-bg: #{$wind-bg-20};
|
--wind-hover-bg: #{$wind-bg-20};
|
||||||
|
--wind-text: #{$wind-text-10};
|
||||||
--wind-hover-text: #{$wind-text-20};
|
--wind-hover-text: #{$wind-text-20};
|
||||||
|
|
||||||
|
--fire-bg: #{$fire-bg-10};
|
||||||
--fire-hover-bg: #{$fire-bg-20};
|
--fire-hover-bg: #{$fire-bg-20};
|
||||||
|
--fire-text: #{$fire-text-10};
|
||||||
--fire-hover-text: #{$fire-text-20};
|
--fire-hover-text: #{$fire-text-20};
|
||||||
|
|
||||||
|
--water-bg: #{$water-bg-10};
|
||||||
--water-hover-bg: #{$water-bg-20};
|
--water-hover-bg: #{$water-bg-20};
|
||||||
|
--water-text: #{$water-text-10};
|
||||||
--water-hover-text: #{$water-text-20};
|
--water-hover-text: #{$water-text-20};
|
||||||
|
|
||||||
|
--earth-bg: #{$earth-bg-10};
|
||||||
--earth-hover-bg: #{$earth-bg-20};
|
--earth-hover-bg: #{$earth-bg-20};
|
||||||
|
--earth-text: #{$earth-text-10};
|
||||||
--earth-hover-text: #{$earth-text-20};
|
--earth-hover-text: #{$earth-text-20};
|
||||||
|
|
||||||
|
--dark-bg: #{$dark-bg-10};
|
||||||
--dark-hover-bg: #{$dark-bg-20};
|
--dark-hover-bg: #{$dark-bg-20};
|
||||||
|
--dark-text: #{$dark-text-10};
|
||||||
--dark-hover-text: #{$dark-text-20};
|
--dark-hover-text: #{$dark-text-20};
|
||||||
|
|
||||||
|
--light-bg: #{$light-bg-10};
|
||||||
--light-hover-bg: #{$light-bg-20};
|
--light-hover-bg: #{$light-bg-20};
|
||||||
|
--light-text: #{$light-text-10};
|
||||||
--light-hover-text: #{$light-text-20};
|
--light-hover-text: #{$light-text-20};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,6 +151,8 @@
|
||||||
--select-bg: #{$select--bg--dark};
|
--select-bg: #{$select--bg--dark};
|
||||||
--select-contained-bg: #{$select--contained--bg--dark};
|
--select-contained-bg: #{$select--contained--bg--dark};
|
||||||
--select-contained-bg-hover: #{$select--contained--bg--dark--hover};
|
--select-contained-bg-hover: #{$select--contained--bg--dark--hover};
|
||||||
|
--select-modal-bg: #{$select--modal--bg--dark};
|
||||||
|
--select-modal-bg-hover: #{$select--modal--bg--dark--hover};
|
||||||
--select-separator: #{$select--separator--dark};
|
--select-separator: #{$select--separator--dark};
|
||||||
--option-bg-hover: #{$option--bg--dark--hover};
|
--option-bg-hover: #{$option--bg--dark--hover};
|
||||||
|
|
||||||
|
|
@ -162,16 +187,40 @@
|
||||||
--subaura-orange-secondary: #{$subaura--orange--secondary--dark};
|
--subaura-orange-secondary: #{$subaura--orange--secondary--dark};
|
||||||
--subaura-orange-text: #{$subaura--orange--text--dark};
|
--subaura-orange-text: #{$subaura--orange--text--dark};
|
||||||
|
|
||||||
|
// Dark - Element Toggle
|
||||||
|
--toggle-bg: #{$toggle--bg--dark};
|
||||||
|
--toggle-stroke: #{$toggle--stroke--dark};
|
||||||
|
|
||||||
--grid-border-color: #{$grid--border--color--dark};
|
--grid-border-color: #{$grid--border--color--dark};
|
||||||
|
|
||||||
|
// Element theming
|
||||||
|
--wind-bg: #{$wind-bg-10};
|
||||||
--wind-hover-bg: #{$wind-bg-00};
|
--wind-hover-bg: #{$wind-bg-00};
|
||||||
|
--wind-text: #{$wind-text-10};
|
||||||
--wind-hover-text: #{$wind-text-00};
|
--wind-hover-text: #{$wind-text-00};
|
||||||
|
|
||||||
|
--fire-bg: #{$fire-bg-10};
|
||||||
--fire-hover-bg: #{$fire-bg-00};
|
--fire-hover-bg: #{$fire-bg-00};
|
||||||
|
--fire-text: #{$fire-text-10};
|
||||||
--fire-hover-text: #{$fire-text-00};
|
--fire-hover-text: #{$fire-text-00};
|
||||||
|
|
||||||
|
--water-bg: #{$water-bg-10};
|
||||||
|
--water-hover-bg: #{$water-bg-00};
|
||||||
|
--water-text: #{$water-text-10};
|
||||||
|
--water-hover-text: #{$water-text-00};
|
||||||
|
|
||||||
|
--earth-bg: #{$earth-bg-10};
|
||||||
--earth-hover-bg: #{$earth-bg-00};
|
--earth-hover-bg: #{$earth-bg-00};
|
||||||
|
--earth-text: #{$earth-text-10};
|
||||||
--earth-hover-text: #{$earth-text-00};
|
--earth-hover-text: #{$earth-text-00};
|
||||||
|
|
||||||
|
--dark-bg: #{$dark-bg-10};
|
||||||
--dark-hover-bg: #{$dark-bg-00};
|
--dark-hover-bg: #{$dark-bg-00};
|
||||||
|
--dark-text: #{$dark-text-10};
|
||||||
--dark-hover-text: #{$dark-text-00};
|
--dark-hover-text: #{$dark-text-00};
|
||||||
|
|
||||||
|
--light-bg: #{$light-bg-10};
|
||||||
--light-hover-bg: #{$light-bg-00};
|
--light-hover-bg: #{$light-bg-00};
|
||||||
|
--light-text: #{$light-text-10};
|
||||||
--light-hover-text: #{$light-text-00};
|
--light-hover-text: #{$light-text-00};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ $unit-6x: $unit * 6;
|
||||||
$unit-8x: $unit * 8;
|
$unit-8x: $unit * 8;
|
||||||
$unit-10x: $unit * 10;
|
$unit-10x: $unit * 10;
|
||||||
$unit-12x: $unit * 12;
|
$unit-12x: $unit * 12;
|
||||||
|
$unit-14x: $unit * 14;
|
||||||
$unit-20x: $unit * 20;
|
$unit-20x: $unit * 20;
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
|
|
@ -34,6 +35,7 @@ $grey-55: #888;
|
||||||
$grey-60: #a9a9a9;
|
$grey-60: #a9a9a9;
|
||||||
$grey-70: #c6c6c6;
|
$grey-70: #c6c6c6;
|
||||||
$grey-80: #e9e9e9;
|
$grey-80: #e9e9e9;
|
||||||
|
$grey-85: #efefef;
|
||||||
$grey-90: #f5f5f5;
|
$grey-90: #f5f5f5;
|
||||||
$grey-95: #fafafa;
|
$grey-95: #fafafa;
|
||||||
$grey-100: white;
|
$grey-100: white;
|
||||||
|
|
@ -132,8 +134,8 @@ $menu--text--dark--hover: $grey-15;
|
||||||
// Color Definitions: Button
|
// Color Definitions: Button
|
||||||
$button--bg--light: $grey-80;
|
$button--bg--light: $grey-80;
|
||||||
$button--bg--light--hover: $grey-100;
|
$button--bg--light--hover: $grey-100;
|
||||||
$button--bg--light--disabled: $grey-50;
|
$button--bg--light--disabled: $grey-80;
|
||||||
$button--contained--bg--light: $grey-90;
|
$button--contained--bg--light: $grey-85;
|
||||||
$button--contained--bg--light--hover: $grey-80;
|
$button--contained--bg--light--hover: $grey-80;
|
||||||
|
|
||||||
$button--bg--dark: $grey-00;
|
$button--bg--dark: $grey-00;
|
||||||
|
|
@ -144,10 +146,10 @@ $button--contained--bg--dark--hover: $grey-05;
|
||||||
|
|
||||||
$button--text--light: $grey-55;
|
$button--text--light: $grey-55;
|
||||||
$button--text--light--hover: $grey-40;
|
$button--text--light--hover: $grey-40;
|
||||||
$button--text--light--disabled: $grey-40;
|
$button--text--light--disabled: $grey-70;
|
||||||
$button--text--dark: $grey-70;
|
$button--text--dark: $grey-70;
|
||||||
$button--text--dark--hover: $grey-100;
|
$button--text--dark--hover: $grey-100;
|
||||||
$button--text--dark--disabled: $grey-50;
|
$button--text--dark--disabled: $grey-40;
|
||||||
|
|
||||||
// Color Definitions: Input
|
// Color Definitions: Input
|
||||||
$input--bg--light: $grey-100;
|
$input--bg--light: $grey-100;
|
||||||
|
|
@ -155,7 +157,7 @@ $input--bg--light--hover: $grey-95;
|
||||||
$input--bg--dark: $grey-40;
|
$input--bg--dark: $grey-40;
|
||||||
$input--bg--dark--hover: $grey-30;
|
$input--bg--dark--hover: $grey-30;
|
||||||
|
|
||||||
$input--bound--bg--light: $grey-90;
|
$input--bound--bg--light: $grey-85;
|
||||||
$input--bound--bg--light--hover: $grey-80;
|
$input--bound--bg--light--hover: $grey-80;
|
||||||
$input--bound--bg--dark: $grey-15;
|
$input--bound--bg--dark: $grey-15;
|
||||||
$input--bound--bg--dark--hover: $grey-25;
|
$input--bound--bg--dark--hover: $grey-25;
|
||||||
|
|
@ -163,12 +165,20 @@ $input--bound--bg--dark--hover: $grey-25;
|
||||||
// Color Definitions: Select
|
// Color Definitions: Select
|
||||||
$select--bg--light: $grey-100;
|
$select--bg--light: $grey-100;
|
||||||
$select--bg--dark: $grey-10;
|
$select--bg--dark: $grey-10;
|
||||||
|
|
||||||
$select--contained--bg--light: $grey-90;
|
$select--contained--bg--light: $grey-90;
|
||||||
$select--contained--bg--dark: $grey-05;
|
|
||||||
$select--contained--bg--light--hover: $grey-80;
|
$select--contained--bg--light--hover: $grey-80;
|
||||||
|
$select--contained--bg--dark: $grey-05;
|
||||||
$select--contained--bg--dark--hover: $grey-00;
|
$select--contained--bg--dark--hover: $grey-00;
|
||||||
|
|
||||||
|
$select--modal--bg--light: $grey-85;
|
||||||
|
$select--modal--bg--light--hover: $grey-80;
|
||||||
|
$select--modal--bg--dark: $grey-40;
|
||||||
|
$select--modal--bg--dark--hover: $grey-30;
|
||||||
|
|
||||||
$select--separator--light: $grey-90;
|
$select--separator--light: $grey-90;
|
||||||
$select--separator--dark: $grey-05;
|
$select--separator--dark: $grey-05;
|
||||||
|
|
||||||
$option--bg--light--hover: $grey-90;
|
$option--bg--light--hover: $grey-90;
|
||||||
$option--bg--dark--hover: $grey-00;
|
$option--bg--dark--hover: $grey-00;
|
||||||
|
|
||||||
|
|
@ -205,6 +215,13 @@ $subaura--orange--primary--dark: $orange-00;
|
||||||
$subaura--orange--secondary--dark: $orange-10;
|
$subaura--orange--secondary--dark: $orange-10;
|
||||||
$subaura--orange--text--dark: $orange-00;
|
$subaura--orange--text--dark: $orange-00;
|
||||||
|
|
||||||
|
// Color Definitions: Element Toggle
|
||||||
|
$toggle--bg--light: $grey-90;
|
||||||
|
$toggle--bg--dark: $grey-15;
|
||||||
|
|
||||||
|
$toggle--stroke--light: rgba(0, 0, 0, 0.14);
|
||||||
|
$toggle--stroke--dark: rgba(0, 0, 0, 0.8);
|
||||||
|
|
||||||
// Color Definitions: Text
|
// Color Definitions: Text
|
||||||
$text--primary--color--light: $grey-40;
|
$text--primary--color--light: $grey-40;
|
||||||
$text--primary--color--dark: $grey-90;
|
$text--primary--color--dark: $grey-90;
|
||||||
|
|
|
||||||
1
types/AxSkill.d.ts
vendored
1
types/AxSkill.d.ts
vendored
|
|
@ -5,6 +5,7 @@ interface AxSkill {
|
||||||
ja: string
|
ja: string
|
||||||
}
|
}
|
||||||
id: number
|
id: number
|
||||||
|
slug: string
|
||||||
minValue: number
|
minValue: number
|
||||||
maxValue: number
|
maxValue: number
|
||||||
suffix?: string
|
suffix?: string
|
||||||
|
|
|
||||||
4
types/GridCharacter.d.ts
vendored
4
types/GridCharacter.d.ts
vendored
|
|
@ -3,4 +3,8 @@ interface GridCharacter {
|
||||||
position: number
|
position: number
|
||||||
object: Character
|
object: Character
|
||||||
uncap_level: number
|
uncap_level: number
|
||||||
|
awakening: {
|
||||||
|
type: number
|
||||||
|
level: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
types/GridWeapon.d.ts
vendored
4
types/GridWeapon.d.ts
vendored
|
|
@ -7,4 +7,8 @@ interface GridWeapon {
|
||||||
element: number
|
element: number
|
||||||
weapon_keys?: Array<WeaponKey>
|
weapon_keys?: Array<WeaponKey>
|
||||||
ax?: Array<SimpleAxSkill>
|
ax?: Array<SimpleAxSkill>
|
||||||
|
awakening?: {
|
||||||
|
type: number
|
||||||
|
level: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
types/Weapon.d.ts
vendored
1
types/Weapon.d.ts
vendored
|
|
@ -9,6 +9,7 @@ interface Weapon {
|
||||||
max_skill_level: number
|
max_skill_level: number
|
||||||
series: number
|
series: number
|
||||||
ax: number
|
ax: number
|
||||||
|
awakening: boolean
|
||||||
name: {
|
name: {
|
||||||
[key: string]: string
|
[key: string]: string
|
||||||
en: string
|
en: string
|
||||||
|
|
|
||||||
1
types/WeaponKey.d.ts
vendored
1
types/WeaponKey.d.ts
vendored
|
|
@ -5,6 +5,7 @@ interface WeaponKey {
|
||||||
en: string
|
en: string
|
||||||
ja: string
|
ja: string
|
||||||
}
|
}
|
||||||
|
slug: string
|
||||||
series: integer
|
series: integer
|
||||||
slot: integer
|
slot: integer
|
||||||
group: integer
|
group: integer
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { proxy } from 'valtio'
|
import { proxy } from 'valtio'
|
||||||
import { JobSkillObject } from '~types'
|
import { JobSkillObject } from '~types'
|
||||||
|
import { GroupedWeaponKeys } from './groupWeaponKeys'
|
||||||
|
|
||||||
const emptyJob: Job = {
|
const emptyJob: Job = {
|
||||||
id: '-1',
|
id: '-1',
|
||||||
|
|
@ -57,6 +58,7 @@ interface AppState {
|
||||||
raids: Raid[]
|
raids: Raid[]
|
||||||
jobs: Job[]
|
jobs: Job[]
|
||||||
jobSkills: JobSkill[]
|
jobSkills: JobSkill[]
|
||||||
|
weaponKeys: GroupedWeaponKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialAppState: AppState = {
|
export const initialAppState: AppState = {
|
||||||
|
|
@ -103,6 +105,13 @@ export const initialAppState: AppState = {
|
||||||
raids: [],
|
raids: [],
|
||||||
jobs: [],
|
jobs: [],
|
||||||
jobSkills: [],
|
jobSkills: [],
|
||||||
|
weaponKeys: {
|
||||||
|
pendulum: [],
|
||||||
|
chain: [],
|
||||||
|
teluma: [],
|
||||||
|
gauph: [],
|
||||||
|
emblem: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appState = proxy(initialAppState)
|
export const appState = proxy(initialAppState)
|
||||||
|
|
|
||||||
62
utils/awakening.tsx
Normal file
62
utils/awakening.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
export type Awakening = {
|
||||||
|
id: number
|
||||||
|
name: {
|
||||||
|
[key: string]: string
|
||||||
|
en: string
|
||||||
|
ja: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export const characterAwakening: Awakening[] = [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
name: {
|
||||||
|
en: 'Balanced',
|
||||||
|
ja: 'バランス',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: {
|
||||||
|
en: 'Attack',
|
||||||
|
ja: '攻撃',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: {
|
||||||
|
en: 'Defense',
|
||||||
|
ja: '防御',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: {
|
||||||
|
en: 'Multiattack',
|
||||||
|
ja: '連続攻撃',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const weaponAwakening: Awakening[] = [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
name: {
|
||||||
|
en: 'Attack',
|
||||||
|
ja: '攻撃',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: {
|
||||||
|
en: 'Defense',
|
||||||
|
ja: '防御',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: {
|
||||||
|
en: 'Special',
|
||||||
|
ja: '特殊',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -6,6 +6,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '攻撃',
|
ja: '攻撃',
|
||||||
},
|
},
|
||||||
id: 0,
|
id: 0,
|
||||||
|
slug: 'atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3.5,
|
maxValue: 3.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -16,6 +17,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -26,6 +28,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'DA確率',
|
ja: 'DA確率',
|
||||||
},
|
},
|
||||||
id: 5,
|
id: 5,
|
||||||
|
slug: 'da',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -36,6 +39,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'TA確率',
|
ja: 'TA確率',
|
||||||
},
|
},
|
||||||
id: 6,
|
id: 6,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -46,6 +50,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'アビ上限',
|
ja: 'アビ上限',
|
||||||
},
|
},
|
||||||
id: 7,
|
id: 7,
|
||||||
|
slug: 'skill-cap',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -58,6 +63,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '防御',
|
ja: '防御',
|
||||||
},
|
},
|
||||||
id: 1,
|
id: 1,
|
||||||
|
slug: 'def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 8,
|
maxValue: 8,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -68,6 +74,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'HP',
|
ja: 'HP',
|
||||||
},
|
},
|
||||||
id: 2,
|
id: 2,
|
||||||
|
slug: 'hp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -78,6 +85,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '弱体耐性',
|
ja: '弱体耐性',
|
||||||
},
|
},
|
||||||
id: 9,
|
id: 9,
|
||||||
|
slug: 'debuff',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -88,6 +96,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '回復性能',
|
ja: '回復性能',
|
||||||
},
|
},
|
||||||
id: 10,
|
id: 10,
|
||||||
|
slug: 'healing',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -98,6 +107,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '背水',
|
ja: '背水',
|
||||||
},
|
},
|
||||||
id: 11,
|
id: 11,
|
||||||
|
slug: 'enmity',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -109,6 +119,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'HP',
|
ja: 'HP',
|
||||||
},
|
},
|
||||||
id: 2,
|
id: 2,
|
||||||
|
slug: 'hp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 11,
|
maxValue: 11,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -119,6 +130,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '防御',
|
ja: '防御',
|
||||||
},
|
},
|
||||||
id: 1,
|
id: 1,
|
||||||
|
slug: 'def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -129,6 +141,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '弱体耐性',
|
ja: '弱体耐性',
|
||||||
},
|
},
|
||||||
id: 9,
|
id: 9,
|
||||||
|
slug: 'debuff',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -139,6 +152,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '回復性能',
|
ja: '回復性能',
|
||||||
},
|
},
|
||||||
id: 10,
|
id: 10,
|
||||||
|
slug: 'healing',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -149,6 +163,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -160,6 +175,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 8.5,
|
maxValue: 8.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -170,6 +186,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '攻撃',
|
ja: '攻撃',
|
||||||
},
|
},
|
||||||
id: 0,
|
id: 0,
|
||||||
|
slug: 'atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 1.5,
|
maxValue: 1.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -180,6 +197,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '全属性攻撃力',
|
ja: '全属性攻撃力',
|
||||||
},
|
},
|
||||||
id: 13,
|
id: 13,
|
||||||
|
slug: 'ele-atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -190,6 +208,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義上限',
|
ja: '奥義上限',
|
||||||
},
|
},
|
||||||
id: 8,
|
id: 8,
|
||||||
|
slug: 'ca-cap',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -200,6 +219,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -211,6 +231,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '連撃率',
|
ja: '連撃率',
|
||||||
},
|
},
|
||||||
id: 4,
|
id: 4,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -221,6 +242,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -231,6 +253,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '全属性攻撃力',
|
ja: '全属性攻撃力',
|
||||||
},
|
},
|
||||||
id: 13,
|
id: 13,
|
||||||
|
slug: 'ele-atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -241,6 +264,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'DA確率',
|
ja: 'DA確率',
|
||||||
},
|
},
|
||||||
id: 5,
|
id: 5,
|
||||||
|
slug: 'da',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -251,6 +275,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'TA確率',
|
ja: 'TA確率',
|
||||||
},
|
},
|
||||||
id: 6,
|
id: 6,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -265,6 +290,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '攻撃',
|
ja: '攻撃',
|
||||||
},
|
},
|
||||||
id: 0,
|
id: 0,
|
||||||
|
slug: 'atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3.5,
|
maxValue: 3.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -275,6 +301,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 8.5,
|
maxValue: 8.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -285,6 +312,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '連撃確率',
|
ja: '連撃確率',
|
||||||
},
|
},
|
||||||
id: 4,
|
id: 4,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1.5,
|
minValue: 1.5,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -295,6 +323,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '通常ダメ上限',
|
ja: '通常ダメ上限',
|
||||||
},
|
},
|
||||||
id: 14,
|
id: 14,
|
||||||
|
slug: 'na-dmg',
|
||||||
minValue: 0.5,
|
minValue: 0.5,
|
||||||
maxValue: 1.5,
|
maxValue: 1.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -305,6 +334,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'アビ与ダメ上昇',
|
ja: 'アビ与ダメ上昇',
|
||||||
},
|
},
|
||||||
id: 15,
|
id: 15,
|
||||||
|
slug: 'skill-supp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
},
|
},
|
||||||
|
|
@ -316,6 +346,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '防御',
|
ja: '防御',
|
||||||
},
|
},
|
||||||
id: 1,
|
id: 1,
|
||||||
|
slug: 'def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 8,
|
maxValue: 8,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -326,6 +357,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '属性ダメ軽減',
|
ja: '属性ダメ軽減',
|
||||||
},
|
},
|
||||||
id: 17,
|
id: 17,
|
||||||
|
slug: 'ele-def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -336,6 +368,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '弱体耐性',
|
ja: '弱体耐性',
|
||||||
},
|
},
|
||||||
id: 9,
|
id: 9,
|
||||||
|
slug: 'debuff',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -346,6 +379,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '回復性能',
|
ja: '回復性能',
|
||||||
},
|
},
|
||||||
id: 10,
|
id: 10,
|
||||||
|
slug: 'healing',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -356,6 +390,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '背水',
|
ja: '背水',
|
||||||
},
|
},
|
||||||
id: 11,
|
id: 11,
|
||||||
|
slug: 'enmity',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -367,6 +402,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'HP',
|
ja: 'HP',
|
||||||
},
|
},
|
||||||
id: 2,
|
id: 2,
|
||||||
|
slug: 'hp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 11,
|
maxValue: 11,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -377,6 +413,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '属性ダメ軽減',
|
ja: '属性ダメ軽減',
|
||||||
},
|
},
|
||||||
id: 17,
|
id: 17,
|
||||||
|
slug: 'ele-def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -387,6 +424,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '弱体耐性',
|
ja: '弱体耐性',
|
||||||
},
|
},
|
||||||
id: 9,
|
id: 9,
|
||||||
|
slug: 'debuff',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -397,6 +435,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '回復性能',
|
ja: '回復性能',
|
||||||
},
|
},
|
||||||
id: 10,
|
id: 10,
|
||||||
|
slug: 'healing',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -407,6 +446,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -418,6 +458,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 8.5,
|
maxValue: 8.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -428,6 +469,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '連撃率',
|
ja: '連撃率',
|
||||||
},
|
},
|
||||||
id: 4,
|
id: 4,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1.5,
|
minValue: 1.5,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -438,6 +480,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'アビ与ダメ上昇',
|
ja: 'アビ与ダメ上昇',
|
||||||
},
|
},
|
||||||
id: 15,
|
id: 15,
|
||||||
|
slug: 'skill-supp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
},
|
},
|
||||||
|
|
@ -447,6 +490,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義与ダメ上昇',
|
ja: '奥義与ダメ上昇',
|
||||||
},
|
},
|
||||||
id: 16,
|
id: 16,
|
||||||
|
slug: 'ca-supp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
},
|
},
|
||||||
|
|
@ -456,6 +500,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -467,6 +512,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '連撃率',
|
ja: '連撃率',
|
||||||
},
|
},
|
||||||
id: 4,
|
id: 4,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -477,6 +523,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義与ダメ上昇',
|
ja: '奥義与ダメ上昇',
|
||||||
},
|
},
|
||||||
id: 16,
|
id: 16,
|
||||||
|
slug: 'ca-supp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
},
|
},
|
||||||
|
|
@ -486,6 +533,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '通常ダメ上限',
|
ja: '通常ダメ上限',
|
||||||
},
|
},
|
||||||
id: 14,
|
id: 14,
|
||||||
|
slug: 'na-cap',
|
||||||
minValue: 0.5,
|
minValue: 0.5,
|
||||||
maxValue: 1.5,
|
maxValue: 1.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -496,6 +544,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -505,6 +554,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '背水',
|
ja: '背水',
|
||||||
},
|
},
|
||||||
id: 11,
|
id: 11,
|
||||||
|
slug: 'enmity',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -518,6 +568,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '攻撃',
|
ja: '攻撃',
|
||||||
},
|
},
|
||||||
id: 0,
|
id: 0,
|
||||||
|
slug: 'atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3.5,
|
maxValue: 3.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -528,6 +579,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -538,6 +590,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'DA確率',
|
ja: 'DA確率',
|
||||||
},
|
},
|
||||||
id: 5,
|
id: 5,
|
||||||
|
slug: 'da',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -548,6 +601,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'TA確率',
|
ja: 'TA確率',
|
||||||
},
|
},
|
||||||
id: 6,
|
id: 6,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -558,6 +612,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'アビ上限',
|
ja: 'アビ上限',
|
||||||
},
|
},
|
||||||
id: 7,
|
id: 7,
|
||||||
|
slug: 'skill-cap',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -570,6 +625,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '防御',
|
ja: '防御',
|
||||||
},
|
},
|
||||||
id: 1,
|
id: 1,
|
||||||
|
slug: 'def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 8,
|
maxValue: 8,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -580,6 +636,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'HP',
|
ja: 'HP',
|
||||||
},
|
},
|
||||||
id: 2,
|
id: 2,
|
||||||
|
slug: 'hp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -590,6 +647,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '弱体耐性',
|
ja: '弱体耐性',
|
||||||
},
|
},
|
||||||
id: 9,
|
id: 9,
|
||||||
|
slug: 'debuff',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -600,6 +658,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '回復性能',
|
ja: '回復性能',
|
||||||
},
|
},
|
||||||
id: 10,
|
id: 10,
|
||||||
|
slug: 'healing',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -610,6 +669,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '背水',
|
ja: '背水',
|
||||||
},
|
},
|
||||||
id: 11,
|
id: 11,
|
||||||
|
slug: 'enmity',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -621,6 +681,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'HP',
|
ja: 'HP',
|
||||||
},
|
},
|
||||||
id: 2,
|
id: 2,
|
||||||
|
slug: 'hp',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 11,
|
maxValue: 11,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -631,6 +692,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '防御',
|
ja: '防御',
|
||||||
},
|
},
|
||||||
id: 1,
|
id: 1,
|
||||||
|
slug: 'def',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -641,6 +703,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '弱体耐性',
|
ja: '弱体耐性',
|
||||||
},
|
},
|
||||||
id: 9,
|
id: 9,
|
||||||
|
slug: 'debuff',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -651,6 +714,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '回復性能',
|
ja: '回復性能',
|
||||||
},
|
},
|
||||||
id: 10,
|
id: 10,
|
||||||
|
slug: 'healing',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -661,6 +725,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -672,6 +737,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 8.5,
|
maxValue: 8.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -682,6 +748,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '攻撃',
|
ja: '攻撃',
|
||||||
},
|
},
|
||||||
id: 0,
|
id: 0,
|
||||||
|
slug: 'atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 1.5,
|
maxValue: 1.5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -692,6 +759,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '全属性攻撃力',
|
ja: '全属性攻撃力',
|
||||||
},
|
},
|
||||||
id: 13,
|
id: 13,
|
||||||
|
slug: 'ele-atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -702,6 +770,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義上限',
|
ja: '奥義上限',
|
||||||
},
|
},
|
||||||
id: 8,
|
id: 8,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -712,6 +781,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '渾身',
|
ja: '渾身',
|
||||||
},
|
},
|
||||||
id: 12,
|
id: 12,
|
||||||
|
slug: 'stamina',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 3,
|
maxValue: 3,
|
||||||
},
|
},
|
||||||
|
|
@ -723,6 +793,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '連撃率',
|
ja: '連撃率',
|
||||||
},
|
},
|
||||||
id: 4,
|
id: 4,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -733,6 +804,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '奥義ダメ',
|
ja: '奥義ダメ',
|
||||||
},
|
},
|
||||||
id: 3,
|
id: 3,
|
||||||
|
slug: 'ca-dmg',
|
||||||
minValue: 2,
|
minValue: 2,
|
||||||
maxValue: 4,
|
maxValue: 4,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -743,6 +815,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '全属性攻撃力',
|
ja: '全属性攻撃力',
|
||||||
},
|
},
|
||||||
id: 13,
|
id: 13,
|
||||||
|
slug: 'ele-atk',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 5,
|
maxValue: 5,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -753,6 +826,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'DA確率',
|
ja: 'DA確率',
|
||||||
},
|
},
|
||||||
id: 5,
|
id: 5,
|
||||||
|
slug: 'da',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -763,6 +837,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'TA確率',
|
ja: 'TA確率',
|
||||||
},
|
},
|
||||||
id: 6,
|
id: 6,
|
||||||
|
slug: 'ta',
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
maxValue: 2,
|
maxValue: 2,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -775,6 +850,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: 'EXP UP',
|
ja: 'EXP UP',
|
||||||
},
|
},
|
||||||
id: 18,
|
id: 18,
|
||||||
|
slug: 'exp',
|
||||||
minValue: 5,
|
minValue: 5,
|
||||||
maxValue: 10,
|
maxValue: 10,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
@ -785,6 +861,7 @@ export const axData: AxSkill[][] = [
|
||||||
ja: '獲得ルピ',
|
ja: '獲得ルピ',
|
||||||
},
|
},
|
||||||
id: 19,
|
id: 19,
|
||||||
|
slug: 'rupie',
|
||||||
minValue: 10,
|
minValue: 10,
|
||||||
maxValue: 20,
|
maxValue: 20,
|
||||||
suffix: '%',
|
suffix: '%',
|
||||||
|
|
|
||||||
34
utils/groupWeaponKeys.tsx
Normal file
34
utils/groupWeaponKeys.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { weaponKeyGroups } from './weaponKeyGroups'
|
||||||
|
|
||||||
|
export type GroupedWeaponKeys = {
|
||||||
|
[key: string]: WeaponKey[]
|
||||||
|
pendulum: WeaponKey[]
|
||||||
|
chain: WeaponKey[]
|
||||||
|
teluma: WeaponKey[]
|
||||||
|
gauph: WeaponKey[]
|
||||||
|
emblem: WeaponKey[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function groupWeaponKeys(keys: WeaponKey[]) {
|
||||||
|
console.log(keys)
|
||||||
|
const numGroups = Math.max.apply(
|
||||||
|
Math,
|
||||||
|
keys.map((key) => key.group)
|
||||||
|
)
|
||||||
|
|
||||||
|
let groupedKeys: GroupedWeaponKeys = {
|
||||||
|
pendulum: [],
|
||||||
|
chain: [],
|
||||||
|
teluma: [],
|
||||||
|
gauph: [],
|
||||||
|
emblem: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i <= numGroups; i++) {
|
||||||
|
groupedKeys[weaponKeyGroups[i].slug] = keys.filter((key) => key.group == i)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(groupedKeys)
|
||||||
|
|
||||||
|
return groupedKeys
|
||||||
|
}
|
||||||
52
utils/weaponKeyGroups.tsx
Normal file
52
utils/weaponKeyGroups.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
interface WeaponKeyGroup {
|
||||||
|
id: number
|
||||||
|
slug: string
|
||||||
|
name: {
|
||||||
|
[key: string]: string
|
||||||
|
en: string
|
||||||
|
ja: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const weaponKeyGroups: WeaponKeyGroup[] = [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
slug: 'pendulum',
|
||||||
|
name: {
|
||||||
|
en: 'Pendulum',
|
||||||
|
ja: 'ペンデュラム',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
slug: 'chain',
|
||||||
|
name: {
|
||||||
|
en: 'Chain',
|
||||||
|
ja: 'チェイン',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
slug: 'teluma',
|
||||||
|
name: {
|
||||||
|
en: 'Teluma',
|
||||||
|
ja: 'テルマ',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
slug: 'gauph',
|
||||||
|
name: {
|
||||||
|
en: 'Gauph Key',
|
||||||
|
ja: 'ガフスキー',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
slug: 'emblem',
|
||||||
|
name: {
|
||||||
|
en: 'Emblem',
|
||||||
|
ja: 'エンブレム',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
Loading…
Reference in a new issue