diff --git a/components/CharacterHovercard/index.scss b/components/CharacterHovercard/index.scss
index e69de29b..1ab4b2bd 100644
--- a/components/CharacterHovercard/index.scss
+++ b/components/CharacterHovercard/index.scss
@@ -0,0 +1,53 @@
+.Character.HovercardContent {
+ .Mastery {
+ display: flex;
+ flex-direction: column;
+ gap: $unit;
+
+ ul {
+ display: flex;
+ flex-direction: column;
+ gap: $unit-half;
+
+ .ExtendedMastery {
+ align-items: center;
+ display: flex;
+ gap: $unit-half;
+
+ img {
+ width: $unit-3x;
+ }
+
+ strong {
+ font-weight: $bold;
+ }
+ }
+ }
+ }
+
+ .Awakening {
+ display: flex;
+ flex-direction: column;
+ gap: $unit;
+
+ & > div {
+ align-items: center;
+ display: flex;
+ gap: $unit-half;
+
+ img {
+ width: $unit-3x;
+ }
+
+ strong {
+ font-weight: $bold;
+ }
+ }
+ }
+
+ // .Footer {
+ // position: sticky;
+ // bottom: 0;
+ // left: 0;
+ // }
+}
diff --git a/components/CharacterHovercard/index.tsx b/components/CharacterHovercard/index.tsx
index bd2802d9..8a2989d5 100644
--- a/components/CharacterHovercard/index.tsx
+++ b/components/CharacterHovercard/index.tsx
@@ -10,7 +10,15 @@ import {
import WeaponLabelIcon from '~components/WeaponLabelIcon'
import UncapIndicator from '~components/UncapIndicator'
+import {
+ overMastery,
+ aetherialMastery,
+ permanentMastery,
+} from '~data/overMastery'
+import { ExtendedMastery } from '~types'
+
import './index.scss'
+import { characterAwakening } from '~data/awakening'
interface Props {
gridCharacter: GridCharacter
@@ -70,6 +78,128 @@ const CharacterHovercard = (props: Props) => {
return imgSrc
}
+ function masteryElement(dictionary: ItemSkill[], mastery: ExtendedMastery) {
+ const canonicalMastery = dictionary.find(
+ (item) => item.id === mastery.modifier
+ )
+
+ if (canonicalMastery) {
+ return (
+
+
+
+ {canonicalMastery.name[locale]}
+ {`+${mastery.strength}${canonicalMastery.suffix}`}
+
+
+ )
+ }
+ }
+
+ const overMasterySection = () => {
+ if (props.gridCharacter && props.gridCharacter.over_mastery) {
+ return (
+
+
+ {t('modals.characters.subtitles.ring')}
+
+
+ {[...Array(4)].map((e, i) => {
+ const ringIndex = i + 1
+ const ringStat: ExtendedMastery =
+ props.gridCharacter.over_mastery[i]
+ if (ringStat && ringStat.modifier && ringStat.modifier > 0) {
+ if (ringIndex === 1 || ringIndex === 2) {
+ return masteryElement(overMastery.a, ringStat)
+ } else if (ringIndex === 3) {
+ return masteryElement(overMastery.b, ringStat)
+ } else {
+ return masteryElement(overMastery.c, ringStat)
+ }
+ }
+ })}
+
+
+ )
+ }
+ }
+
+ const aetherialMasterySection = () => {
+ if (
+ props.gridCharacter &&
+ props.gridCharacter.aetherial_mastery &&
+ props.gridCharacter.aetherial_mastery.modifier > 0
+ ) {
+ return (
+
+
+ {t('modals.characters.subtitles.earring')}
+
+
+ {masteryElement(
+ aetherialMastery,
+ props.gridCharacter.aetherial_mastery
+ )}
+
+
+ )
+ }
+ }
+
+ const permanentMasterySection = () => {
+ if (props.gridCharacter && props.gridCharacter.perpetuity) {
+ return (
+
+
+ {t('modals.characters.subtitles.permanent')}
+
+
+ {[...Array(4)].map((e, i) => {
+ return masteryElement(permanentMastery, {
+ modifier: i + 1,
+ strength: permanentMastery[i].maxValue,
+ })
+ })}
+
+
+ )
+ }
+ }
+
+ const awakeningSection = () => {
+ const gridAwakening = props.gridCharacter.awakening
+ const awakening = characterAwakening.find(
+ (awakening) => awakening.id === gridAwakening?.type
+ )
+
+ if (gridAwakening && awakening) {
+ return (
+
+
+ {t('modals.characters.subtitles.awakening')}
+
+
+ {gridAwakening.type > 1 ? (
+
![{awakening.name[locale]}]({`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/awakening/character_${gridAwakening.type}.jpg`})
+ ) : (
+ ''
+ )}
+
+ {`${awakening.name[locale]}`}
+ {`Lv${gridAwakening.level}`}
+
+
+
+ )
+ }
+ }
+
return (
@@ -116,10 +246,15 @@ const CharacterHovercard = (props: Props) => {
/>
-
-
- {t('buttons.wiki')}
-
+ {awakeningSection()}
+ {overMasterySection()}
+ {aetherialMasterySection()}
+ {permanentMasterySection()}
+
)
diff --git a/components/Hovercard/index.scss b/components/Hovercard/index.scss
index 02f16458..8018b0c7 100644
--- a/components/Hovercard/index.scss
+++ b/components/Hovercard/index.scss
@@ -7,6 +7,8 @@
display: flex;
flex-direction: column;
gap: $unit-2x;
+ max-height: 30vh;
+ overflow-y: scroll;
padding: $unit-2x;
width: 300px;
diff --git a/data/overMastery.tsx b/data/overMastery.tsx
index 74aa353d..969dc942 100644
--- a/data/overMastery.tsx
+++ b/data/overMastery.tsx
@@ -330,3 +330,54 @@ export const aetherialMastery: ItemSkill[] = [
fractional: false,
},
]
+
+export const permanentMastery: ItemSkill[] = [
+ {
+ name: {
+ en: 'Extended Mastery Star Cap',
+ ja: 'LB強化回数上限',
+ },
+ id: 1,
+ slug: 'star-cap',
+ minValue: 10,
+ maxValue: 10,
+ suffix: '',
+ fractional: false,
+ },
+ {
+ name: {
+ en: 'ATK',
+ ja: '攻撃',
+ },
+ id: 2,
+ slug: 'atk',
+ minValue: 10,
+ maxValue: 10,
+ suffix: '%',
+ fractional: false,
+ },
+ {
+ name: {
+ en: 'HP',
+ ja: 'HP',
+ },
+ id: 3,
+ slug: 'hp',
+ minValue: 10,
+ maxValue: 10,
+ suffix: '',
+ fractional: false,
+ },
+ {
+ name: {
+ en: 'DMG Cap',
+ ja: 'ダメージ上限',
+ },
+ id: 4,
+ slug: 'dmg-cap',
+ minValue: 5,
+ maxValue: 5,
+ suffix: '%',
+ fractional: false,
+ },
+]