- {idx} |
+ {idx + 1} |
|
- {levelData.spData.initSp} |
- {levelData.spData.spCost} |
+ {levelData.spData.initSp > 0 ? levelData.spData.initSp : "-"} |
+ {levelData.spData.spCost > 0 ? levelData.spData.spCost : "-"} |
{levelData.duration > 0 ? `${levelData.duration}s` : "-"} |
-
+ |
{strings.blackboard}
diff --git a/src/lib/logic/operators.ts b/src/lib/logic/operators.ts
index 4789ed6..cc294d3 100644
--- a/src/lib/logic/operators.ts
+++ b/src/lib/logic/operators.ts
@@ -30,7 +30,23 @@ type RawCharSkill = {
levelUpCostCond: RawSkillMasteryData[]
}
-type RawCharTrait = {}
+type RawCharTrait = {
+ unlockCondition: PhaseData
+ requiredPotentialRank: number
+ blackboard: BlackboardEntry[] | undefined
+ overrideDescripton: string | undefined // true HG fashion typo
+}
+
+type RawCharTalent = {
+ name: string
+ description: string
+
+ unlockCondition: PhaseData
+ requiredPotentialRank: number
+
+ blackboard: BlackboardEntry[] | undefined
+ isHideTalent: boolean
+}
type RawCharacter = {
rarity: string
@@ -47,7 +63,8 @@ type RawCharacter = {
subProfessionId: string
skills: RawCharSkill[]
- trait: RawCharTrait[] | undefined
+ trait: { candidates: RawCharTrait[] } | undefined
+ talents: { candidates: RawCharTalent[] }[] | undefined
}
type RawCharacterTable = { [id: string]: RawCharacter }
@@ -82,12 +99,23 @@ export type ParsedSkill = {
masteryCosts: RawSkillMasteryData[]
}
+type ParsedTrait = {
+ unlockCondition: PhaseData
+ requiredPotentialRank: number
+ blackboard: BlackboardEntry[] | undefined
+ description: string
+}
+
+type ParsedTalent = {
+ name: string
+ candidates: RawCharTalent[]
+}
+
type ParsedCharacter = {
charId: string
rarity: string
name: string
- trait: string
appellation: string
code: string
@@ -98,6 +126,8 @@ type ParsedCharacter = {
subProfession: string
skills: ParsedSkill[]
+ traits: ParsedTrait[]
+ talents: ParsedTalent[]
}
type CharacterTable = { [id: string]: ParsedCharacter }
@@ -151,12 +181,58 @@ for (const region of SERVERS) {
}
}
+ // parse traits
+ const traits: ParsedTrait[] = []
+
+ {
+ if (rawChar.trait) {
+ for (const candidate of rawChar.trait.candidates) {
+ const parsedTrait: ParsedTrait = {
+ description: candidate.overrideDescripton || rawChar.description || "",
+ blackboard: candidate.blackboard,
+ requiredPotentialRank: candidate.requiredPotentialRank,
+ unlockCondition: candidate.unlockCondition
+ }
+
+ traits.push(parsedTrait)
+ }
+ } else {
+ traits.push({
+ description: rawChar.description || "",
+ blackboard: undefined,
+ requiredPotentialRank: 0,
+ unlockCondition: {
+ phase: "PHASE_0",
+ level: 1
+ }
+ })
+ }
+ }
+
+ // parse talents
+ let talents: ParsedTalent[] = []
+
+ {
+ if (rawChar.talents) {
+ for (const rawTalent of rawChar.talents) {
+ // why does Ulpianus have an invalid talent...
+ if (rawTalent.candidates[0].isHideTalent) {
+ continue
+ }
+
+ talents.push({
+ name: rawTalent.candidates[0].name,
+ candidates: rawTalent.candidates
+ })
+ }
+ }
+ }
+
const parsedChar: ParsedCharacter = {
charId: charId,
rarity: rawChar.rarity,
name: rawChar.name || "",
- trait: rawChar.description || "",
appellation: rawChar.appellation || "",
code: rawChar.displayNumber || "",
@@ -166,7 +242,9 @@ for (const region of SERVERS) {
profession: rawChar.profession,
subProfession: rawChar.subProfessionId,
- skills: skills
+ skills: skills,
+ traits: traits,
+ talents: talents
}
Data[region][charId] = parsedChar
diff --git a/src/lib/logic/richtext.ts b/src/lib/logic/richtext.ts
index d6f3974..1d629e7 100644
--- a/src/lib/logic/richtext.ts
+++ b/src/lib/logic/richtext.ts
@@ -28,7 +28,11 @@ export function ParseRichtextToNodes(text: string): RichtextNode[] {
})
const nodes: RichtextNode[] = []
- const obj = parser.parse(`${EscapeNonHTMLRichtext(text)}`)
+
+ // EXPERIMENTAL: some CN data has an escaped linebreak (ie. \\n), which will result in invalid
+ // HTML rendering (no linebreaks, just a literal \n character)
+ // we escape those \\n here, but I can't foresee if this would break anything...
+ const obj = parser.parse(`${EscapeNonHTMLRichtext(text.replaceAll("\\n", "\n"))}`)
// biome-ignore lint/suspicious/noExplicitAny: too lazy to type lol
function parseNode(root: any, parentNodeData: RichtextNode | undefined) {
diff --git a/src/routes/[region]/operators/[charId]/+page.svelte b/src/routes/[region]/operators/[charId]/+page.svelte
index e9e687d..9ec7fe3 100644
--- a/src/routes/[region]/operators/[charId]/+page.svelte
+++ b/src/routes/[region]/operators/[charId]/+page.svelte
@@ -1,10 +1,18 @@
-
@@ -43,9 +51,94 @@
-
+
+ {#each charData.traits as traitData}
+
+
+
+
+ Lv. {traitData.unlockCondition.level}
+
+
+
+
+ {#if traitData.blackboard}
+
+ {data.strings.blackboard}
+
+
+ {/if}
+
+ {/each}
+
+
+
+ {#each charData.talents as talentData}
+
+
+
+ {talentData.name} |
+
+
+ {#each talentData.candidates as candidate}
+
+
+
+
+
+ {#if candidate.requiredPotentialRank > 0}
+
+ {/if}
+
+ {#if candidate.unlockCondition.level > 1}
+ Lv. {candidate.unlockCondition.level}
+ {/if}
+
+ |
+
+
+ |
+
+ {/each}
+
+
+ {/each}
+
{#each charData.skills as skillData}
{/each}
+
+
|