import type { RegionalName } from '$lib/regional-name'; /** * 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; /** * 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: 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 { const resp = await fetch('/api/global/conversation'); return resp.json(); } 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(), ); } export const locations: Record = { 110: { name: { en: 'right side front' }, group: 1 }, 120: { name: { en: 'right side front' }, group: 1 }, 130: { name: { en: 'right side front' }, group: 1 }, 210: { name: { en: 'left side table' }, group: 2 }, 220: { name: { en: 'left side table' }, group: 2 }, 310: { name: { en: 'center back seat' }, group: 3 }, 410: { name: { en: 'center posters' }, group: 4 }, 420: { name: { en: 'center posters' }, group: 4 }, 430: { name: { en: 'center posters' }, group: 4 }, 510: { name: { en: 'left side school map' }, group: 5 }, 520: { name: { en: 'left side school map' }, group: 5 }, 530: { name: { en: 'left side school map' }, group: 5 }, }; function locCharas(convos: Conversation[], locGroup: 1 | 2 | 3 | 4 | 5) { const m = convos .filter((c) => locations[c.location].group === locGroup) .flatMap((c) => [c.chara_1, c.chara_2, c.chara_3].filter((x) => x != null)) .reduce((m, id) => m.set(id, 1 + (m.get(id) ?? 0)), new Map()); return [...m].toSorted((a, b) => b[1] - a[1]); // descending } 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), }; }