Add elf pages
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
import { assetsBucketBaseUrl } from '../../lib/consts'
|
||||||
|
import ResizedImage from './ResizedImage'
|
||||||
|
|
||||||
|
interface ElfIconProps {
|
||||||
|
icon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ElfIcon = ({ icon }: ElfIconProps) => {
|
||||||
|
return (
|
||||||
|
<ResizedImage
|
||||||
|
src={`${assetsBucketBaseUrl}/raw/elfcardicons/${icon}.png`}
|
||||||
|
originalHeight={120}
|
||||||
|
originalWidth={140}
|
||||||
|
ratio={0.8}
|
||||||
|
alignItems="end"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ElfIcon
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Box, Flex } from 'theme-ui'
|
||||||
|
import { assetsBucketBaseUrl } from '../../lib/consts'
|
||||||
|
import { repeat } from '../../lib/utils'
|
||||||
|
|
||||||
|
interface RarityBarProps {
|
||||||
|
rarity: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const starSize = 16
|
||||||
|
|
||||||
|
const RarityBar = ({ rarity }: RarityBarProps) => {
|
||||||
|
return (
|
||||||
|
<Flex sx={{ marginTop: -starSize / 2, justifyContent: 'center', width: '100%' }}>
|
||||||
|
{repeat(rarity, index => (
|
||||||
|
<Box
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
width: starSize,
|
||||||
|
height: starSize,
|
||||||
|
zIndex: 1,
|
||||||
|
background: `no-repeat 50% / 100% url(${assetsBucketBaseUrl}/raw-misc/StarBig.png)`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RarityBar
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/* eslint-disable jsx-a11y/alt-text */
|
||||||
|
import { Box, Flex, Image } from 'theme-ui'
|
||||||
|
|
||||||
|
interface ResizedImageProps {
|
||||||
|
src: string | string[]
|
||||||
|
originalWidth: number
|
||||||
|
originalHeight: number
|
||||||
|
ratio?: number
|
||||||
|
alignItems?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ResizedImage = ({ src, originalWidth, originalHeight, ratio = 1, alignItems = 'center' }: ResizedImageProps) => {
|
||||||
|
if (typeof src === 'string') {
|
||||||
|
src = [src]
|
||||||
|
}
|
||||||
|
const targetWidth = originalWidth * ratio
|
||||||
|
const targetHeight = originalHeight * ratio
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: targetWidth, height: targetHeight, position: 'relative' }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
left: (targetWidth - originalWidth) / 2,
|
||||||
|
top: (targetHeight - originalHeight) / 2
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{src.map((aSrc, index) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
width: originalWidth,
|
||||||
|
height: originalHeight,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
zIndex: 1,
|
||||||
|
transform: `scale(${ratio})`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image src={aSrc} />
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ResizedImage
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
import { Box, Flex } from 'theme-ui'
|
import { Box } from 'theme-ui'
|
||||||
import { assetsBucketBaseUrl } from '../../lib/consts'
|
import { assetsBucketBaseUrl } from '../../lib/consts'
|
||||||
import { repeat } from '../../lib/utils'
|
import RarityBar from './RarityBar'
|
||||||
|
|
||||||
interface WeaponIconProps {
|
interface WeaponIconProps {
|
||||||
icon: string
|
icon: string
|
||||||
rarity?: number
|
rarity?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const starSize = 16
|
|
||||||
|
|
||||||
const WeaponIcon = ({ icon: fileName, rarity }: WeaponIconProps) => {
|
const WeaponIcon = ({ icon: fileName, rarity }: WeaponIconProps) => {
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: 112 }}>
|
<Box sx={{ width: 112 }}>
|
||||||
@@ -22,20 +20,7 @@ const WeaponIcon = ({ icon: fileName, rarity }: WeaponIconProps) => {
|
|||||||
)}`
|
)}`
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{rarity != null && (
|
{rarity != null && <RarityBar rarity={rarity} />}
|
||||||
<Flex sx={{ marginTop: -starSize / 2, justifyContent: 'center', width: '100%' }}>
|
|
||||||
{repeat(rarity, index => (
|
|
||||||
<Box
|
|
||||||
key={index}
|
|
||||||
sx={{
|
|
||||||
width: starSize,
|
|
||||||
height: starSize,
|
|
||||||
background: `no-repeat 50% / 100% url(${assetsBucketBaseUrl}/raw-misc/StarBig.png)`
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Flex>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,35 @@ export function repeat<N>(count: number, rendererFn: (index: number) => N) {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ListMap<K, V> {
|
||||||
|
map: Map<K, V[]>
|
||||||
|
constructor(mapOrEntries?: Map<K, V[]> | [K, V[]][]) {
|
||||||
|
if (mapOrEntries == null) {
|
||||||
|
this.map = new Map()
|
||||||
|
} else {
|
||||||
|
this.map = new Map(mapOrEntries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key: K) {
|
||||||
|
return this.map.get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: K, value: V) {
|
||||||
|
let list = this.map.get(key)
|
||||||
|
if (list == null) {
|
||||||
|
list = []
|
||||||
|
this.map.set(key, list)
|
||||||
|
}
|
||||||
|
list.push(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
entries() {
|
||||||
|
return this.map.entries()
|
||||||
|
}
|
||||||
|
|
||||||
|
values() {
|
||||||
|
return this.map.values()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -307,3 +307,53 @@ export interface ErSigil {
|
|||||||
unlockHint: string
|
unlockHint: string
|
||||||
type: number
|
type: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Elf {
|
||||||
|
cardIcon: string
|
||||||
|
id: string
|
||||||
|
fullName: string
|
||||||
|
icon: string
|
||||||
|
chibiIcon: string
|
||||||
|
figureImage: string
|
||||||
|
rarity: number
|
||||||
|
cardId: number
|
||||||
|
fragmentId: number
|
||||||
|
storyDesc: string
|
||||||
|
ultSkillCd: number
|
||||||
|
ultSkillCost: number
|
||||||
|
skillBg: string
|
||||||
|
tags: {
|
||||||
|
type: TagType
|
||||||
|
comment: string
|
||||||
|
}[]
|
||||||
|
captainSkillIds: string[]
|
||||||
|
skills: ElfSkill[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ElfSkill {
|
||||||
|
id: string
|
||||||
|
elfId: string
|
||||||
|
name: string
|
||||||
|
info: string
|
||||||
|
skillType: string
|
||||||
|
skillTypeId: string
|
||||||
|
icon: string
|
||||||
|
row: number
|
||||||
|
col: number
|
||||||
|
unlockStar: number
|
||||||
|
maxLv: number
|
||||||
|
paramBase1: number
|
||||||
|
paramBase2: number
|
||||||
|
paramBase3: number
|
||||||
|
paramAdd1: number
|
||||||
|
paramAdd2: number
|
||||||
|
paramAdd3: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ElfCatalogItem {
|
||||||
|
id: string
|
||||||
|
fullName: string
|
||||||
|
cardIcon: string
|
||||||
|
chibiIcon: string
|
||||||
|
rarity: number
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { ListMap } from '../../../utils'
|
||||||
|
import { Elf, ElfSkill } from '../../data/types'
|
||||||
|
import { getRawElfDataMap } from '../raw/elfData'
|
||||||
|
import { getRawElfSkillDataMap } from '../raw/elfSkillData'
|
||||||
|
import { convertTagType, getText } from './utils'
|
||||||
|
|
||||||
|
export function compileElfData() {
|
||||||
|
const rawElfDataMap = getRawElfDataMap()
|
||||||
|
const rawElfSkillDataMap = getRawElfSkillDataMap()
|
||||||
|
|
||||||
|
const rawElfSkillMap = Object.entries(rawElfSkillDataMap).reduce<ListMap<string, ElfSkill>>(
|
||||||
|
(map, [id, rawSkillData]) => {
|
||||||
|
const elfId = rawSkillData.ElfID.toString()
|
||||||
|
map.set(elfId, {
|
||||||
|
id,
|
||||||
|
elfId,
|
||||||
|
name: getText(rawSkillData.Name),
|
||||||
|
info: getText(rawSkillData.Info),
|
||||||
|
skillType: getText(rawSkillData.SkillTypeTag),
|
||||||
|
skillTypeId: rawSkillData.SkillType.toString(),
|
||||||
|
icon: rawSkillData.IconPath.split('/').pop()!,
|
||||||
|
row: rawSkillData.UIPointRow,
|
||||||
|
col: rawSkillData.UIPointColumn,
|
||||||
|
unlockStar: rawSkillData.UnlockStar,
|
||||||
|
maxLv: rawSkillData.MaxLv,
|
||||||
|
paramBase1: rawSkillData.AbilityParamBase_1,
|
||||||
|
paramBase2: rawSkillData.AbilityParamBase_2,
|
||||||
|
paramBase3: rawSkillData.AbilityParamBase_3,
|
||||||
|
paramAdd1: rawSkillData.AbilityParamAdd_1,
|
||||||
|
paramAdd2: rawSkillData.AbilityParamAdd_2,
|
||||||
|
paramAdd3: rawSkillData.AbilityParamAdd_3
|
||||||
|
})
|
||||||
|
return map
|
||||||
|
},
|
||||||
|
new ListMap()
|
||||||
|
)
|
||||||
|
|
||||||
|
const elfs = Object.entries(rawElfDataMap).map<Elf>(([id, rawData]) => {
|
||||||
|
const skills = rawElfSkillMap.get(id) || []
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
fullName: getText(rawData.FullName),
|
||||||
|
icon: rawData.IconPath.split('/').pop()!,
|
||||||
|
cardIcon: rawData.StoryBGImg.split('/').pop()!,
|
||||||
|
chibiIcon: rawData.ElfChibiIcon.split('/').pop()!,
|
||||||
|
figureImage: rawData.StoryBGImg.split('/').pop()!,
|
||||||
|
rarity: rawData.Rarity,
|
||||||
|
cardId: rawData.ElfCardID,
|
||||||
|
fragmentId: rawData.ElfFragmentID,
|
||||||
|
storyDesc: getText(rawData.StoryDesc),
|
||||||
|
ultSkillCd: rawData.UltraSkillCD,
|
||||||
|
ultSkillCost: rawData.UltraSkillSPCost,
|
||||||
|
skillBg: rawData.SkillTabBGImg.split('/').pop()!,
|
||||||
|
tags: rawData.TagList.map(rawTag => {
|
||||||
|
return {
|
||||||
|
type: convertTagType(rawTag.TagID),
|
||||||
|
comment: getText(rawTag.TagComment)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
captainSkillIds: rawData.CaptainSkillIDs.map(rawId => rawId.toString()),
|
||||||
|
skills
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return elfs
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ import path from 'path'
|
|||||||
import YAML from 'yaml'
|
import YAML from 'yaml'
|
||||||
import {
|
import {
|
||||||
BattlesuitCatalogItem,
|
BattlesuitCatalogItem,
|
||||||
|
Elf,
|
||||||
|
ElfCatalogItem,
|
||||||
ErBattlesuit,
|
ErBattlesuit,
|
||||||
ErBattlesuitCatalogItem,
|
ErBattlesuitCatalogItem,
|
||||||
ErSigil,
|
ErSigil,
|
||||||
@@ -35,6 +37,9 @@ export const erSignetsDir = path.join(dataDir, 'er-signets')
|
|||||||
export const erSupportsPath = path.join(dataDir, 'er-supports.yaml')
|
export const erSupportsPath = path.join(dataDir, 'er-supports.yaml')
|
||||||
export const erSigilsPath = path.join(dataDir, 'er-sigils.yaml')
|
export const erSigilsPath = path.join(dataDir, 'er-sigils.yaml')
|
||||||
|
|
||||||
|
export const elfsDir = path.join(dataDir, 'elfs')
|
||||||
|
export const elfCatalogPath = path.join(dataDir, 'elf-catalog.yaml')
|
||||||
|
|
||||||
export function loadBattlesuitCatalog(): BattlesuitCatalogItem[] {
|
export function loadBattlesuitCatalog(): BattlesuitCatalogItem[] {
|
||||||
return readYamlFile(battlesuitCatalogPath)
|
return readYamlFile(battlesuitCatalogPath)
|
||||||
}
|
}
|
||||||
@@ -93,6 +98,15 @@ export function loadErSigils(): ErSigil[] {
|
|||||||
return readYamlFile(erSigilsPath)
|
return readYamlFile(erSigilsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function loadElfCatalog(): ElfCatalogItem[] {
|
||||||
|
return readYamlFile(elfCatalogPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadElfData(id: string): Elf {
|
||||||
|
const elfDataPath = path.join(elfsDir, `${id}.yaml`)
|
||||||
|
return readYamlFile(elfDataPath)
|
||||||
|
}
|
||||||
|
|
||||||
function readYamlFile(pathname: string) {
|
function readYamlFile(pathname: string) {
|
||||||
return YAML.parse(fs.readFileSync(pathname).toString())
|
return YAML.parse(fs.readFileSync(pathname).toString())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import { loadRawData } from './loadRawData'
|
||||||
|
|
||||||
|
export function getRawElfDataMap(): RawElfDataMap {
|
||||||
|
return loadRawData('ElfData.json')
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RawElfDataMap = {
|
||||||
|
[key: string]: RawElfData
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RawElfData {
|
||||||
|
Index: number
|
||||||
|
FullName: number
|
||||||
|
ElfRegistryKey: string
|
||||||
|
ElfUIModelPath: string
|
||||||
|
ElfUIModelPosition: {
|
||||||
|
X: 0.135
|
||||||
|
Y: -0.32
|
||||||
|
Z: 3.74
|
||||||
|
}
|
||||||
|
ElfUIModelRotation: {
|
||||||
|
X: 0
|
||||||
|
Y: -7.2
|
||||||
|
Z: 0
|
||||||
|
}
|
||||||
|
IconPath: string // 'SpriteOutput/ElfIcon/Elf_01'
|
||||||
|
ElfChibiIcon: string // 'SpriteOutput/AvatarChibiIcons/Elf_10001'
|
||||||
|
PortraitCommonIcon: string // 'SpriteOutput/ElfCardIcons/Elf_10001'
|
||||||
|
StoryBGImg: string // 'SpriteOutput/ElfCardFigures/Elf_10001'
|
||||||
|
PresentBGImg: string // 'SpriteOutput/ElfCardFigures/Elf_10001'
|
||||||
|
AIName: string // 'Behavior_Elf_01'
|
||||||
|
IsFlight: number
|
||||||
|
UnlockStar: number
|
||||||
|
Rarity: number
|
||||||
|
ElfCardID: number
|
||||||
|
ElfFragmentID: number
|
||||||
|
CarryPlayerLevel: number
|
||||||
|
UISoundbankName: string
|
||||||
|
StoryDesc: number
|
||||||
|
RGBCGID: number
|
||||||
|
AlphaCGID: number
|
||||||
|
UltraSkillCD: number
|
||||||
|
UltraSkillSPCost: number
|
||||||
|
AttackSkillCD: number
|
||||||
|
SkillTabBGImg: string // 'SpriteOutput/ElfTalentBg/TalentBg1'
|
||||||
|
TalentTabBGImg: string // 'SpriteOutput/ElfTalentBg/TalentBg1'
|
||||||
|
SelectAudio: string // 'VO_Elf_01_BloodEmbrace_SwitchIn'
|
||||||
|
LevelUpAudio: string // 'VO_Elf_01_BloodEmbrace_LevelUp'
|
||||||
|
CombatPointRarity: number
|
||||||
|
TagList: {
|
||||||
|
TagID: number
|
||||||
|
TagComment: number
|
||||||
|
}[]
|
||||||
|
FeatureBrief: number
|
||||||
|
TrialStageActivityList: number[]
|
||||||
|
CaptainSkillIDs: number[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { loadRawData } from './loadRawData'
|
||||||
|
|
||||||
|
export function getRawElfSkillDataMap(): RawElfSkillDataMap {
|
||||||
|
return loadRawData('ElfSkillData.json')
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RawElfSkillDataMap = {
|
||||||
|
[key: string]: RawElfSkillData
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RawElfSkillData {
|
||||||
|
ElfID: number
|
||||||
|
Name: number
|
||||||
|
Info: number
|
||||||
|
SkillTypeTag: number
|
||||||
|
MaxLv: number
|
||||||
|
SkillType: number
|
||||||
|
IconPath: string //'SpriteOutput/Elf_Skill_Icon/Skill_Elf_Attack_101'
|
||||||
|
IconType: number
|
||||||
|
UnlockStar: number
|
||||||
|
UIPointRow: number
|
||||||
|
UIPointColumn: number
|
||||||
|
TagList: { TagID: number; TagComment: number }[]
|
||||||
|
IconSpecial: number
|
||||||
|
AbilityParamBase_1: number
|
||||||
|
AbilityParamAdd_1: number
|
||||||
|
AbilityParamBase_2: number
|
||||||
|
AbilityParamAdd_2: number
|
||||||
|
AbilityParamBase_3: number
|
||||||
|
AbilityParamAdd_3: number
|
||||||
|
HasNoRestrictionAbility: number
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import { NextPageContext } from 'next'
|
||||||
|
import { Box, Card, Flex, Heading } from 'theme-ui'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
import { Elf, ElfSkill } from '../../../lib/v2-pre/data/types'
|
||||||
|
import { loadElfCatalog, loadElfData } from '../../../lib/v2-pre/server/loadData'
|
||||||
|
import SquareImage from '../../../components/v2-pre/SquareImage'
|
||||||
|
import TagIcon from '../../../components/v2-pre/TagIcon'
|
||||||
|
import { assetsBucketBaseUrl } from '../../../lib/consts'
|
||||||
|
import { ListMap } from '../../../lib/utils'
|
||||||
|
import FormattedText from '../../../components/v2-pre/FormattedText'
|
||||||
|
import { formatSubSkillInfo } from '../../../lib/v2-pre/data/formatText'
|
||||||
|
|
||||||
|
interface ElfShowPageProps {
|
||||||
|
elf: Elf
|
||||||
|
}
|
||||||
|
|
||||||
|
const ElfShowPage = ({ elf }: ElfShowPageProps) => {
|
||||||
|
const skillRows = useMemo(() => {
|
||||||
|
const rowSkillListMap = elf.skills.reduce<ListMap<string, ElfSkill>>((map, skill) => {
|
||||||
|
map.set(skill.row.toString(), skill)
|
||||||
|
return map
|
||||||
|
}, new ListMap())
|
||||||
|
|
||||||
|
return [...rowSkillListMap.values()]
|
||||||
|
}, [elf.skills])
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Heading as="h1">{elf.fullName}</Heading>
|
||||||
|
<SquareImage
|
||||||
|
src={`${assetsBucketBaseUrl}/raw/elfcardfigures/${elf.figureImage}.png`}
|
||||||
|
originalSize={720}
|
||||||
|
size={480}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card mb={3}>
|
||||||
|
<Box sx={{ p: 1, borderBottom: 'default' }}>
|
||||||
|
<Flex>
|
||||||
|
{elf.tags.map(tag => {
|
||||||
|
return (
|
||||||
|
<Box key={tag.type} mr={1}>
|
||||||
|
<TagIcon type={tag.type} />
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
<Box p={1}>
|
||||||
|
Ult CD: {elf.ultSkillCd} / Ult SP Cost: {elf.ultSkillCost}
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Heading as="h2">Skills</Heading>
|
||||||
|
|
||||||
|
{skillRows.map((row, index) => {
|
||||||
|
return (
|
||||||
|
<Card key={index} mb={2}>
|
||||||
|
{row.map(skill => {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
key={skill.id}
|
||||||
|
sx={{
|
||||||
|
borderBottom: 'default',
|
||||||
|
'&:last-child': {
|
||||||
|
borderBottom: 'none'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ borderBottom: 'default', p: 1 }}>
|
||||||
|
<Flex sx={{ alignItems: 'center' }}>
|
||||||
|
<Box sx={{ flexShrink: 0 }}>
|
||||||
|
<SquareImage
|
||||||
|
src={`${assetsBucketBaseUrl}/raw/elf_skill_icon/${skill.icon}.png`}
|
||||||
|
originalSize={40}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Heading as={'h3'} sx={{ my: 0, ml: 1 }}>
|
||||||
|
<FormattedText>{skill.name}</FormattedText>
|
||||||
|
</Heading>
|
||||||
|
{/* {skill.id} */}
|
||||||
|
<Box sx={{ color: 'textMuted', ml: 1 }}>({skill.skillType})</Box>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ p: 1 }}>
|
||||||
|
<FormattedText>{formatSubSkillInfo(skill)}</FormattedText>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ElfShowPage
|
||||||
|
|
||||||
|
export async function getStaticProps({ locale, params }: NextPageContext & { params: { elfId: string } }) {
|
||||||
|
const elf = loadElfData(params.elfId)
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: { elf }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const elfCatalog = loadElfCatalog()
|
||||||
|
|
||||||
|
return {
|
||||||
|
paths: elfCatalog.map(catalogItem => {
|
||||||
|
return {
|
||||||
|
params: { elfId: catalogItem.id }
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
fallback: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/** @jsxImportSource theme-ui */
|
||||||
|
import { Box, Card } from '@theme-ui/components'
|
||||||
|
import { NextPageContext } from 'next'
|
||||||
|
import { Flex, Link } from 'theme-ui'
|
||||||
|
import { ElfCatalogItem } from '../../../lib/v2-pre/data/types'
|
||||||
|
import { loadElfCatalog } from '../../../lib/v2-pre/server/loadData'
|
||||||
|
import RarityBar from '../../../components/v2-pre/RarityBar'
|
||||||
|
import ElfIcon from '../../../components/v2-pre/ElfIcon'
|
||||||
|
|
||||||
|
interface ElfListPageProps {
|
||||||
|
elfs: ElfCatalogItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const ElfListPage = ({ elfs }: ElfListPageProps) => {
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<h1>Elfs</h1>
|
||||||
|
<Flex sx={{ flexWrap: 'wrap' }}>
|
||||||
|
{elfs
|
||||||
|
.sort((a, b) => {
|
||||||
|
const aId = getId(a.id)
|
||||||
|
const bId = getId(b.id)
|
||||||
|
return bId - aId
|
||||||
|
|
||||||
|
function getId(id: string): number {
|
||||||
|
return parseInt(id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(elf => {
|
||||||
|
return (
|
||||||
|
<Box key={elf.id} m={2}>
|
||||||
|
<Link href={`/v2-pre/elfs/${elf.id}`}>
|
||||||
|
<Card p={1}>
|
||||||
|
<Box>
|
||||||
|
<ElfIcon icon={elf.cardIcon} />
|
||||||
|
<RarityBar rarity={elf.rarity} />
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{ textAlign: 'center', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}
|
||||||
|
>
|
||||||
|
{elf.fullName}
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ElfListPage
|
||||||
|
|
||||||
|
export async function getStaticProps({ locale }: NextPageContext) {
|
||||||
|
const elfs = loadElfCatalog()
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: { elfs }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
battlesuitCatalogPath,
|
battlesuitCatalogPath,
|
||||||
battlesuitsDir,
|
battlesuitsDir,
|
||||||
dataDir,
|
dataDir,
|
||||||
|
elfCatalogPath,
|
||||||
|
elfsDir,
|
||||||
erBattlesuitCatalogPath,
|
erBattlesuitCatalogPath,
|
||||||
erBattlesuitsDir,
|
erBattlesuitsDir,
|
||||||
erSigilsPath,
|
erSigilsPath,
|
||||||
@@ -21,6 +23,7 @@ import {
|
|||||||
} from '../lib/v2-pre/server/loadData'
|
} from '../lib/v2-pre/server/loadData'
|
||||||
import {
|
import {
|
||||||
BattlesuitCatalogItem,
|
BattlesuitCatalogItem,
|
||||||
|
ElfCatalogItem,
|
||||||
StigmataCatalogItem,
|
StigmataCatalogItem,
|
||||||
StigmataSetCatalogItem,
|
StigmataSetCatalogItem,
|
||||||
WeaponCatalogItem
|
WeaponCatalogItem
|
||||||
@@ -29,6 +32,7 @@ import { compileBattlesuitData } from '../lib/v2-pre/server/compileData/compileB
|
|||||||
import { compileWeaponData } from '../lib/v2-pre/server/compileData/compileWeaponData'
|
import { compileWeaponData } from '../lib/v2-pre/server/compileData/compileWeaponData'
|
||||||
import { compileStigmataData } from '../lib/v2-pre/server/compileData/compileStigmataData'
|
import { compileStigmataData } from '../lib/v2-pre/server/compileData/compileStigmataData'
|
||||||
import { compileGodWarData } from '../lib/v2-pre/server/compileData/compileGodWarData'
|
import { compileGodWarData } from '../lib/v2-pre/server/compileData/compileGodWarData'
|
||||||
|
import { compileElfData } from '../lib/v2-pre/server/compileData/compileElfData'
|
||||||
|
|
||||||
runScript(async () => {
|
runScript(async () => {
|
||||||
createDirIfNotExist(dataDir)
|
createDirIfNotExist(dataDir)
|
||||||
@@ -36,6 +40,7 @@ runScript(async () => {
|
|||||||
writeWeaponData()
|
writeWeaponData()
|
||||||
writeStigmataData()
|
writeStigmataData()
|
||||||
writeErData()
|
writeErData()
|
||||||
|
writeElfData()
|
||||||
})
|
})
|
||||||
|
|
||||||
function writeBattlesuitData() {
|
function writeBattlesuitData() {
|
||||||
@@ -158,3 +163,26 @@ function writeErData() {
|
|||||||
fs.writeFileSync(erSupportsPath, YAML.stringify(supportAvatarList))
|
fs.writeFileSync(erSupportsPath, YAML.stringify(supportAvatarList))
|
||||||
fs.writeFileSync(erSigilsPath, YAML.stringify(sigilList))
|
fs.writeFileSync(erSigilsPath, YAML.stringify(sigilList))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function writeElfData() {
|
||||||
|
const elfs = compileElfData()
|
||||||
|
|
||||||
|
const elfCatalogList = elfs.map<ElfCatalogItem>(elf => {
|
||||||
|
return {
|
||||||
|
id: elf.id,
|
||||||
|
fullName: elf.fullName,
|
||||||
|
cardIcon: elf.cardIcon,
|
||||||
|
icon: elf.icon,
|
||||||
|
chibiIcon: elf.chibiIcon,
|
||||||
|
rarity: elf.rarity
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
fs.writeFileSync(elfCatalogPath, YAML.stringify(elfCatalogList))
|
||||||
|
|
||||||
|
createDirIfNotExist(elfsDir)
|
||||||
|
for (const elf of elfs) {
|
||||||
|
const elfDataPath = path.join(elfsDir, `${elf.id}.yaml`)
|
||||||
|
fs.writeFileSync(elfDataPath, YAML.stringify(elf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,4 +26,5 @@ dump/sprite2-dump-67/assets/asbres/spriteoutput/rogue/godcloseup \
|
|||||||
dump/sprite2-dump-67/assets/asbres/spriteoutput/weaponicons \
|
dump/sprite2-dump-67/assets/asbres/spriteoutput/weaponicons \
|
||||||
dump/sprite2-dump-67/assets/asbres/spriteoutput/weapontypeicons \
|
dump/sprite2-dump-67/assets/asbres/spriteoutput/weapontypeicons \
|
||||||
dump/sprite2-dump-67/assets/asbres/spriteoutput/materialfigures \
|
dump/sprite2-dump-67/assets/asbres/spriteoutput/materialfigures \
|
||||||
|
dump/sprite2-dump-67/assets/asbres/spriteoutput/elf_skill_icon \
|
||||||
assets/raw
|
assets/raw
|
||||||
|
|||||||
Reference in New Issue
Block a user