Compare commits

...
2 Commits
Author SHA1 Message Date
zephyr ad02e0711d zenno/chara/convo: include character icons
ci/woodpecker/push/zenno Pipeline failed
ci/woodpecker/push/horsebot Pipeline was successful
2026-09-06 14:21:09 -04:00
zephyr 869235a8c2 zenno/chara/convo: use condition_type
Fixes #8.
2026-09-06 11:56:50 -04:00
2 changed files with 70 additions and 39 deletions
+23 -1
View File
@@ -32,7 +32,29 @@ export interface Conversation {
/**
* Some unknown number in the game's local database.
*/
condition_type: 0 | 1 | 2 | 3 | 4;
condition_type: Required;
}
export enum Required {
None = 0,
All = 1,
Chara1 = 2,
Chara2 = 3,
Chara3 = 4,
}
export function convoCharas(c: Conversation): number[] {
return [c.chara_1, c.chara_2, c.chara_3].filter((id) => id != null);
}
export function requiredCharas(c: Conversation): number[] {
switch (c.condition_type) {
case Required.None: return []
case Required.All: return convoCharas(c);
case Required.Chara1: return [c.chara_1];
case Required.Chara2: return [c.chara_2!];
case Required.Chara3: return [c.chara_3!];
}
}
export async function conversation(): Promise<Conversation[]> {
+33 -24
View File
@@ -1,15 +1,24 @@
<script lang="ts">
import { character, charaNames, type Character } from '$lib/data/character';
import { byChara, locations, groupPopulars, conversation, type Conversation } from '$lib/data/convo';
import {
byChara,
locations,
groupPopulars,
conversation,
type Conversation,
requiredCharas,
convoCharas,
} from '$lib/data/convo';
import CharaPick from '$lib/CharaPick.svelte';
import { onMount } from 'svelte';
import CharaIcon from '$lib/CharaIcon.svelte';
let conversations: Conversation[] = $state([]);
const convoMap = $derived(byChara(conversations));
const popular = $derived(groupPopulars(conversations));
let characters: Character[] = $state([]);
const selCharas = $derived(characters.filter((c) => convoMap.has(c.chara_id)));
const names = $derived(charaNames(characters ?? []));
const names = $derived(charaNames(characters));
const minSuggest = 8;
onMount(async () => {
@@ -21,11 +30,9 @@
const options = $derived(convoMap.get(chara?.chara_id ?? 0) ?? []);
const cur = $derived(options.find((c) => c.number === convo));
const cur1Name = $derived(cur?.chara_1 && names.get(cur.chara_1)?.en);
const cur2Name = $derived(cur?.chara_2 && names.get(cur.chara_2)?.en);
const cur3Name = $derived(cur?.chara_3 && names.get(cur.chara_3)?.en);
const alone = $derived([cur?.chara_1, cur?.chara_2, cur?.chara_3].filter((x) => x != null).length == 1 ? ' alone' : '');
const suggested = $derived.by(async () => {
const charaIDs = $derived(cur != null ? convoCharas(cur) : []);
const charas = $derived(charaIDs.map((id) => names.get(id)!));
const suggested = $derived.by(() => {
if (cur == null) {
return [];
}
@@ -36,6 +43,7 @@
return r.map(([chara_id, count]) => ({ chara_id, chara_name: names.get(chara_id), count }));
});
const curLoc = $derived(cur != null ? locations[cur.location] : null);
const req = $derived(cur != null ? requiredCharas(cur) : []);
</script>
<h1 class="text-4xl">Lobby Conversations</h1>
@@ -53,23 +61,25 @@
</select>
</div>
</div>
{#await suggested}
<div class="mt-4 w-full text-center text-3xl">Loading...</div>
{:then suggested}
{#if cur}
{#if cur}
<div class="shadow-sm transition-shadow hover:shadow-md">
<div class="mt-8 flex text-center text-lg">
<span class="flex-1">{cur1Name}{alone}</span>
{#if cur2Name}
<span class="flex-1">{cur2Name}</span>
{/if}
{#if cur3Name}
<span class="flex-1">{cur3Name}</span>
{/if}
<div class="mt-8 flex flex-col text-center text-lg md:flex-row">
{#each charaIDs as id, i (id)}
<span class={{ 'flex-1': true, 'font-bold italic': req.includes(id) }}>
<CharaIcon chara_id={id} size={64} />
{charas[i].en}
</span>
{/each}
</div>
<div class="flex w-full text-center text-lg">
<span class="flex-1">at {curLoc?.name.en}</span>
<div class="block w-full text-center text-lg">
at the {curLoc?.name.en}
</div>
{#if req.length > 0}
<span class="mx-auto mt-4 block text-center text-sm">
The conversation will not appear unless you own a trainee or support card of all characters with names in
<span class="font-bold italic">bold italics</span>.
</span>
{/if}
</div>
<div class="mt-4 block text-center">
<span>Other characters who appear here most often:</span>
@@ -81,9 +91,8 @@
</div>
<div class="mt-4 block text-center">
<span>
Set these characters to fixed positions (main, upgrades, story, races) to maximize the chance of getting this
Setting these characters to fixed positions (main, upgrades, story, races) may maximize the chance of getting this
conversation.
</span>
</div>
{/if}
{/await}
{/if}