zenno: use data from api
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
characters: Character[];
|
||||
characters: Character[] | null;
|
||||
value: number;
|
||||
class?: ClassValue | null;
|
||||
optionClass?: ClassValue | null;
|
||||
@@ -18,7 +18,7 @@
|
||||
{#if !required}
|
||||
<option value="0" class={optionClass}></option>
|
||||
{/if}
|
||||
{#each characters as c (c.chara_id)}
|
||||
{#each characters ?? [] as c (c.chara_id)}
|
||||
<option value={c.chara_id} class={optionClass}>{c.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
+15
-17
@@ -3,39 +3,37 @@
|
||||
ABILITY_SCALE_NAME,
|
||||
ABILITY_TYPE_FORMAT,
|
||||
DURATION_SCALE_NAME,
|
||||
skills,
|
||||
Target,
|
||||
TARGET_FORMAT,
|
||||
tenThousandths,
|
||||
ZERO_SKILL,
|
||||
type Ability,
|
||||
type Skill,
|
||||
} from './data/skill';
|
||||
|
||||
interface CommonProps {
|
||||
hint?: string;
|
||||
interface Props {
|
||||
skill: Skill | null | undefined;
|
||||
mention?: boolean;
|
||||
}
|
||||
|
||||
type Props = CommonProps & ({ skill: number; name?: never } | { name: string; skill?: never });
|
||||
const ZERO_SKILL: Skill = {
|
||||
skill_id: 0,
|
||||
name: 'Skill data is loading...',
|
||||
description: 'Skill data is still loading, or else something went wrong.',
|
||||
group: 0,
|
||||
rarity: 1,
|
||||
group_rate: 1,
|
||||
wit_check: false,
|
||||
activations: [],
|
||||
icon_id: 0,
|
||||
};
|
||||
|
||||
let { hint, mention, skill, name }: Props = $props();
|
||||
let { mention, skill }: Props = $props();
|
||||
|
||||
function splitCond(c: string): string[] {
|
||||
return c.replaceAll('&', ' & ').split('@');
|
||||
}
|
||||
|
||||
const s: Readonly<Skill> = $derived.by(() => {
|
||||
const l =
|
||||
skill != null ? skills.global.filter((s) => s.skill_id === skill) : skills.global.filter((s) => s.name.includes(name!));
|
||||
if (name != null) {
|
||||
console.warn(`skills specified as ${name} (${hint}):`, l);
|
||||
}
|
||||
if (l.length === 0) {
|
||||
return ZERO_SKILL;
|
||||
}
|
||||
return l[0];
|
||||
});
|
||||
const s = $derived(skill ?? ZERO_SKILL);
|
||||
const activationClass = $derived(s.activations.length === 1 ? null : 'block my-2 border rounded-md');
|
||||
|
||||
const spanClass = $derived(mention ? 'italic' : 'font-bold');
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { sparks } from '$lib/data/spark';
|
||||
import { type Spark } from '$lib/data/spark';
|
||||
|
||||
interface Props {
|
||||
spark: number;
|
||||
region?: keyof typeof sparks;
|
||||
spark: Spark | null | undefined;
|
||||
}
|
||||
|
||||
const { spark, region = 'global' }: Props = $props();
|
||||
const { spark }: Props = $props();
|
||||
|
||||
const cur = $derived(sparks[region].find((s) => s.spark_id === spark));
|
||||
const curClass = $derived.by(() => {
|
||||
if (cur == null) {
|
||||
if (spark == null) {
|
||||
return [];
|
||||
}
|
||||
switch (cur.type) {
|
||||
switch (spark.type) {
|
||||
case 1:
|
||||
return ['stat'];
|
||||
case 2:
|
||||
@@ -32,17 +30,17 @@
|
||||
return [];
|
||||
}
|
||||
});
|
||||
const stars = $derived('★'.repeat(cur?.rarity ?? 0));
|
||||
const stars = $derived('★'.repeat(spark?.rarity ?? 0));
|
||||
</script>
|
||||
|
||||
{#if cur != null}
|
||||
{#if spark != null}
|
||||
<div
|
||||
class={[
|
||||
curClass,
|
||||
'spark mx-1 flex items-center rounded-xl px-2 py-1 transition ease-in hover:shadow-md hover:ease-out motion-safe:duration-75 motion-safe:hover:-translate-y-0.5 dark:shadow-neutral-950',
|
||||
]}
|
||||
>
|
||||
<span>{cur.name}</span>
|
||||
<span>{spark.name}</span>
|
||||
<span class="ml-2 text-xl text-amber-800 text-shadow-md dark:text-amber-300">{stars}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import globalJSON from '../../../../global/affinity.json';
|
||||
|
||||
/**
|
||||
* Precomputed character pair and trio affinity.
|
||||
*/
|
||||
@@ -24,9 +22,10 @@ export interface Affinity {
|
||||
affinity: number;
|
||||
}
|
||||
|
||||
export const affinity = {
|
||||
global: globalJSON as Affinity[],
|
||||
} as const;
|
||||
export async function affinity(): Promise<Affinity[]> {
|
||||
const resp = await fetch('/api/global/affinity');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export function lookup(aff: Affinity[], chara_a: number, chara_b: number, chara_c?: number): number {
|
||||
const [a, b, c] = [chara_a, chara_b, chara_c ?? Infinity].sort((a, b) => a - b);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { RegionalName } from '$lib/regional-name';
|
||||
import globalJSON from '../../../../global/character.json';
|
||||
|
||||
/**
|
||||
* Character definitions.
|
||||
@@ -16,11 +15,11 @@ export interface Character {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const character = {
|
||||
global: globalJSON as Character[],
|
||||
};
|
||||
export async function character(): Promise<Character[]> {
|
||||
const resp = await fetch('/api/global/character');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export const charaNames = globalJSON.reduce(
|
||||
(m, c) => m.set(c.chara_id, { en: c.name }),
|
||||
new Map<Character['chara_id'], RegionalName>(),
|
||||
);
|
||||
export function charaNames(charas: Character[]) {
|
||||
return charas.reduce((m, c) => m.set(c.chara_id, { en: c.name }), new Map<number, RegionalName>());
|
||||
}
|
||||
|
||||
+18
-22
@@ -1,5 +1,4 @@
|
||||
import type { RegionalName } from '$lib/regional-name';
|
||||
import globalJSON from '../../../../global/conversation.json';
|
||||
|
||||
/**
|
||||
* Lobby conversation data.
|
||||
@@ -17,10 +16,6 @@ export interface Conversation {
|
||||
* Location ID of the conversation.
|
||||
*/
|
||||
location: 110 | 120 | 130 | 210 | 220 | 310 | 410 | 420 | 430 | 510 | 520 | 530;
|
||||
/**
|
||||
* English name of the location, for convenience.
|
||||
*/
|
||||
location_name: string;
|
||||
/**
|
||||
* First character in the conversation.
|
||||
* Not necessarily equal to chara_id.
|
||||
@@ -40,16 +35,17 @@ export interface Conversation {
|
||||
condition_type: 0 | 1 | 2 | 3 | 4;
|
||||
}
|
||||
|
||||
export const conversation = {
|
||||
global: globalJSON as Conversation[],
|
||||
};
|
||||
export async function conversation(): Promise<Conversation[]> {
|
||||
const resp = await fetch('/api/global/conversation');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export const byChara = {
|
||||
global: globalJSON.reduce(
|
||||
export function byChara(convos: Conversation[]) {
|
||||
return convos.reduce(
|
||||
(m, c) => m.set(c.chara_id, (m.get(c.chara_id) ?? []).concat(c as Conversation)),
|
||||
new Map<Conversation['chara_id'], Conversation[]>(),
|
||||
),
|
||||
};
|
||||
new Map<number, Conversation[]>(),
|
||||
);
|
||||
}
|
||||
|
||||
export const locations: Record<Conversation['location'], { name: RegionalName; group: 1 | 2 | 3 | 4 | 5 }> = {
|
||||
110: { name: { en: 'right side front' }, group: 1 },
|
||||
@@ -74,12 +70,12 @@ function locCharas(convos: Conversation[], locGroup: 1 | 2 | 3 | 4 | 5) {
|
||||
return [...m].toSorted((a, b) => b[1] - a[1]); // descending
|
||||
}
|
||||
|
||||
export const groupPopulars = {
|
||||
global: {
|
||||
1: locCharas(conversation.global, 1),
|
||||
2: locCharas(conversation.global, 2),
|
||||
3: locCharas(conversation.global, 3),
|
||||
4: locCharas(conversation.global, 4),
|
||||
5: locCharas(conversation.global, 5),
|
||||
},
|
||||
};
|
||||
export function groupPopulars(convos: Conversation[]) {
|
||||
return {
|
||||
1: locCharas(convos, 1),
|
||||
2: locCharas(convos, 2),
|
||||
3: locCharas(convos, 3),
|
||||
4: locCharas(convos, 4),
|
||||
5: locCharas(convos, 5),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import skillGlobal from '../../../../global/skill.json';
|
||||
import groupGlobal from '../../../../global/skill-group.json';
|
||||
|
||||
/**
|
||||
* Skill data.
|
||||
*/
|
||||
@@ -323,22 +320,12 @@ export interface SkillGroup {
|
||||
skill_bad?: number;
|
||||
}
|
||||
|
||||
export const skills = {
|
||||
global: skillGlobal as Skill[],
|
||||
} as const;
|
||||
export async function skills(): Promise<Skill[]> {
|
||||
const resp = await fetch('/api/global/skill');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export const skillGroups = {
|
||||
global: groupGlobal as SkillGroup[],
|
||||
} as const;
|
||||
|
||||
export const ZERO_SKILL: Readonly<Skill> = {
|
||||
skill_id: 0,
|
||||
name: 'invalid skill',
|
||||
description: 'an invalid skill was specified',
|
||||
group: 0,
|
||||
rarity: 1,
|
||||
group_rate: 1,
|
||||
wit_check: false,
|
||||
activations: [],
|
||||
icon_id: 0,
|
||||
} as const;
|
||||
export async function skillGroups(): Promise<SkillGroup[]> {
|
||||
const resp = await fetch('/api/global/skill-group');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import globalJSON from '../../../../global/spark.json';
|
||||
|
||||
/**
|
||||
* Sparks, or succession factors.
|
||||
*/
|
||||
@@ -48,6 +46,7 @@ export interface SparkEffect {
|
||||
value2: number;
|
||||
}
|
||||
|
||||
export const sparks = {
|
||||
global: globalJSON as Spark[],
|
||||
} as const;
|
||||
export async function sparks(): Promise<Spark[]> {
|
||||
const resp = await fetch('/api/global/spark');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import globalJSON from '../../../../global/uma.json';
|
||||
|
||||
/**
|
||||
* Uma or character card definitions.
|
||||
*/
|
||||
@@ -70,6 +68,7 @@ export interface Uma {
|
||||
|
||||
export type AptitudeLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
||||
|
||||
export const uma = {
|
||||
global: globalJSON as Uma[],
|
||||
};
|
||||
export async function uma(): Promise<Uma[]> {
|
||||
const resp = await fetch('/api/global/uma');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user