/**
* Characters, and one character's optimizer view.
*
* The list is every character the capture saw. Seven codenames have no everness
* record at all (`Chiichan073`, `Female051`, `Jin`, `Kuhara`, `Mint019`,
* `Mitsuki`, `Oneiroi`), so the card has to work without artwork, a grid or stat
* curves rather than assuming they exist.
*/
import { esperFor, type LoadedData } from "../state/gamedata.ts";
import { CharacterView } from "./CharacterView.tsx";
import { Icon } from "./Icon.tsx";
import { equipmentOf } from "../db/store.ts";
import type { CharacterRow } from "../db/schema.ts";
import { hashFor, type Route } from "./router.ts";
import { useAppState, useStore } from "./useStore.ts";
export function CharactersTab({
data,
route,
unnamedGroups,
}: {
data: LoadedData;
route: Route;
unnamedGroups: string[];
}) {
const state = useAppState();
const db = state.data.db;
if (route.id) return ;
return (
{unnamedGroups.length > 0 && (
)}
);
}
/**
* What to call a character in the naming dropdown.
*
* Two espers are both published as "Zero", so a bare display name can send a
* whole loadout to the wrong character; where a name is shared the codename
* disambiguates it. Seven of the captured roster have no everness record at
* all, so their codename is all there is - which is also why the options come
* from the capture rather than from the esper list: a character the game says
* you own must be nameable even when the game database has never heard of it.
*/
function ownerLabel(
data: LoadedData,
characters: CharacterRow[],
characterId: string,
): string {
const esper = esperFor(data.gamedata, characterId);
if (!esper) return characterId;
const shared = characters.some(
(other) =>
other.characterId !== characterId &&
esperFor(data.gamedata, other.characterId)?.name === esper.name,
);
return shared ? `${esper.name} (${characterId})` : esper.name;
}
/**
* The owner groups nobody has named.
*
* Seven of thirteen cannot be matched from the capture at all - three sets of
* characters share both their module shapes and their cartridge set - so the
* player names them once, keyed on values that are stable across exports.
*/
function UnidentifiedGroups({ groups, data }: { groups: string[]; data: LoadedData }) {
const store = useStore();
const state = useAppState();
const db = state.data.db;
return (
Unidentified groups
The capture says these items are worn together, but not by whom. Name each group once
and it sticks.