zenno: implement character picker

This commit is contained in:
2026-03-30 12:13:20 -04:00
parent cc3128d65a
commit 34e8c1f812
5 changed files with 104 additions and 1 deletions

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { character } from '$lib/data/character'
interface Props {
id: string
value: number
label?: string
region?: keyof typeof character
required?: boolean
}
let { id, value = $bindable(), label, region = 'global', required = false }: Props = $props()
</script>
{#if label}
<label for={id}>{label}</label>
{/if}
<select id={id} bind:value={value} required={required}>
{#if !required}
<option value=0></option>
{/if}
{#each character[region] as c}
<option value={c.chara_id}>{c.name}</option>
{/each}
</select>

View File

@@ -0,0 +1,23 @@
import type { RegionalName } from '$lib/regional-name'
import globalJSON from '../../../../global/character.json'
/**
* Character definitions.
*/
export interface Character {
/**
* Character ID.
*/
chara_id: number
/**
* Regional name of the character.
* E.g., Special Week for Global, or スペシャルウィーク for JP.
*/
name: string
}
export const character = {
global: globalJSON as Character[],
}
export const charaNames = globalJSON.reduce((m, c) => m.set(c.chara_id, {en: c.name}), new Map<Character['chara_id'], RegionalName>());

View File

@@ -0,0 +1,40 @@
import convoJSON from '../../../../global/conversation.json'
/**
* Lobby conversation data.
*/
export interface Conversation {
/**
* Character who owns the conversation as a gallery entry.
*/
chara_id: number;
/**
* Number of the conversation within the character's conversation gallery.
*/
number: number;
/**
* 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.
*/
chara_1: number;
/**
* Second character, if present.
*/
chara_2?: number;
/**
* Third character, if present.
*/
chara_3?: number;
/**
* Some unknown number in the game's local database.
*/
condition_type: 0 | 1 | 2 | 3 | 4;
}

View File

@@ -0,0 +1,7 @@
/**
* Names accounting for regions.
* Currently English is the only supported language.
*/
export interface RegionalName {
en: string
}

View File

@@ -1,3 +1,11 @@
<script lang="ts">
import CharaPick from "$lib/CharaPick.svelte";
let selChara = $state(0);
</script>
<h1>Welcome to SvelteKit</h1>
<CharaPick id="test-chara" bind:value={selChara} />
<p>selected character is id {selChara}</p>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<p>Lorem ipsum (/ ˌ l ɔː. r ə m ˈ ɪ p. s ə m/ LOR-əm IP-səm) is a dummy or placeholder text commonly used in graphic design, publishing, and web development. It is typically a corrupted version of De finibus bonorum et malorum, a 1st-century BC text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical and improper Latin. The first two words are the truncation of dolorem ipsum ("pain itself"). Lorem ipsum's purpose is to permit a page layout to be designed, independently of the copy that will subsequently populate it, or to demonstrate various fonts of a typeface without meaningful text that could be distracting. Versions of the Lorem ipsum text have been used in typesetting since the 1960s, when advertisements for Letraset transfer sheets popularized it. Lorem ipsum was introduced to the digital world in the mid-1980s, when Aldus employed it in graphic and word-processing templates for its desktop publishing program PageMaker. Other popular word processors, including Pages and Microsoft Word, have since adopted Lorem ipsum, as have many LaTeX packages, web content</p>