zenno/doc/tagged-skills: new page
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
group_rate: 1,
|
||||
wit_check: false,
|
||||
activations: [],
|
||||
tags: [],
|
||||
icon_id: 0,
|
||||
};
|
||||
|
||||
|
||||
@@ -79,6 +79,11 @@ export const PAGES = {
|
||||
name: 'Spark Explorer',
|
||||
description: 'View all possible inheritance effects of any spark.',
|
||||
},
|
||||
{
|
||||
route: resolve('/doc/tagged-skills'),
|
||||
name: 'Tagged Skills Explorer',
|
||||
description: 'View skills matching the tags internal to the game.',
|
||||
},
|
||||
] satisfies Page[],
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ export interface Skill {
|
||||
* SP cost to purchase the skill, if applicable.
|
||||
*/
|
||||
sp_cost?: number;
|
||||
/**
|
||||
* Numeric tags applied to the skill, for effects which select skill types.
|
||||
*/
|
||||
tags: number[];
|
||||
/**
|
||||
* Skill icon ID.
|
||||
*/
|
||||
@@ -329,3 +333,55 @@ export async function skillGroups(): Promise<SkillGroup[]> {
|
||||
const resp = await fetch('/api/global/skill-group');
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export const TAGS = [
|
||||
{ name: 'Front Runner', tag: 101 },
|
||||
{ name: 'Pace Chaser', tag: 102 },
|
||||
{ name: 'Late Surger', tag: 103 },
|
||||
{ name: 'End Closer', tag: 104 },
|
||||
{ name: 'Sprint', tag: 201 },
|
||||
{ name: 'Mile', tag: 202 },
|
||||
{ name: 'Medium', tag: 203 },
|
||||
{ name: 'Long', tag: 204 },
|
||||
{ name: 'Early Race', tag: 301 },
|
||||
{ name: 'Mid Race', tag: 302 },
|
||||
{ name: 'Late Race', tag: 303 },
|
||||
{ name: 'Speed Stat or Velocity', tag: 401 },
|
||||
{ name: 'Stamina Stat or HP', tag: 402 },
|
||||
{ name: 'Power Stat or Acceleration', tag: 403 },
|
||||
{ name: 'Guts Stat', tag: 404 },
|
||||
{ name: 'Wit Stat or Vision', tag: 405 },
|
||||
{ name: 'Debuff', tag: 406 },
|
||||
{ name: 'Gate Delay', tag: 407 },
|
||||
{ name: 'Turf', tag: 501 },
|
||||
{ name: 'Dirt', tag: 502 },
|
||||
{ name: 'Ground Condition Passive', tag: 601 },
|
||||
{ name: 'Weather Passive', tag: 602 },
|
||||
{ name: 'Season Passive', tag: 603 },
|
||||
{ name: 'Racecourse Passive', tag: 604 },
|
||||
{ name: 'Time of Day Passive', tag: 605 },
|
||||
{ name: 'Exchange Race Passive', tag: 606 },
|
||||
{ name: 'Distance Passive', tag: 607 },
|
||||
{ name: 'Corner-Based Passive', tag: 608 },
|
||||
{ name: 'Gate Position Passive', tag: 609 },
|
||||
{ name: 'Ground Type Passive', tag: 610 },
|
||||
{ name: 'Popularity Passive', tag: 611 },
|
||||
{ name: 'Running Style Passive', tag: 612 },
|
||||
{ name: "Passive Depending on Other Horses' Styles or Skills", tag: 613 },
|
||||
{ name: 'Base Stat Threshold Passive', tag: 614 },
|
||||
{ name: 'Mood Passive', tag: 615 },
|
||||
{ name: 'URA', tag: 801 },
|
||||
{ name: 'Unity Cup', tag: 802 },
|
||||
{ name: 'Trackblazer', tag: 804 },
|
||||
// { name: 'Our Grand Concert', tag: ? },
|
||||
// { name: 'Grand Masters', tag: ? },
|
||||
// { name: "Project L'Arc", tag: ? },
|
||||
// { name: 'U.A.F.', tag: ? },
|
||||
// { name: 'Great Food Festival', tag: ? },
|
||||
// { name: 'Run, Mecha Umamusume!', tag: ? },
|
||||
// { name: 'The Twinkle Legends', tag: ? },
|
||||
// { name: 'Design Your Island', tag: ? },
|
||||
// { name: 'Yukoma Hot Springs', tag: ? },
|
||||
// { name: 'Beyond Dreams', tag: ? },
|
||||
// { name: 'Tracen-Ken', tag: ? },
|
||||
] as const;
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import * as skill from '$lib/data/skill';
|
||||
|
||||
let rare = $state(false);
|
||||
let unique = $state(false);
|
||||
|
||||
let allSkillsList: skill.Skill[] = $state([]);
|
||||
onMount(async () => {
|
||||
allSkillsList = await skill.skills();
|
||||
});
|
||||
|
||||
const tagTypes = $state([
|
||||
{
|
||||
name: 'Running Style',
|
||||
includes: skill.TAGS.filter((t) => 101 <= t.tag && t.tag <= 199).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
{
|
||||
name: 'Distance',
|
||||
includes: skill.TAGS.filter((t) => 201 <= t.tag && t.tag <= 299).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
{
|
||||
name: 'Surface',
|
||||
includes: skill.TAGS.filter((t) => 501 <= t.tag && t.tag <= 599).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
{
|
||||
name: 'Timing',
|
||||
includes: skill.TAGS.filter((t) => 301 <= t.tag && t.tag <= 399).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
{
|
||||
name: 'Effects',
|
||||
includes: skill.TAGS.filter((t) => 401 <= t.tag && t.tag <= 499).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
{
|
||||
name: 'Passive Types',
|
||||
includes: skill.TAGS.filter((t) => 601 <= t.tag && t.tag <= 699).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
{
|
||||
name: 'Scenario Skills',
|
||||
includes: skill.TAGS.filter((t) => 801 <= t.tag && t.tag <= 899).map((t) => ({ ...t, on: false })),
|
||||
},
|
||||
]);
|
||||
const tags = $derived(tagTypes.flatMap((v) => v.includes.filter((t) => t.on).map((t) => t.tag)));
|
||||
const skills = $derived(
|
||||
allSkillsList.filter(
|
||||
(s) =>
|
||||
(rare || s.group_rate === 1) &&
|
||||
(unique || (s.rarity < 3 && s.unique_owner == null)) &&
|
||||
tags.some((t) => s.tags.includes(t)),
|
||||
),
|
||||
);
|
||||
</script>
|
||||
|
||||
<h1 class="text-4xl">Tagged Skills Explorer</h1>
|
||||
<form class="mx-auto my-8 rounded-md p-4 text-center shadow-md ring md:max-w-4xl">
|
||||
<div class="flex w-full gap-4">
|
||||
<div class="my-auto inline-block flex-1">
|
||||
<input id="rare" type="checkbox" role="switch" class="min-h-6 min-w-6 align-middle" bind:checked={rare} />
|
||||
<label for="rare">Include All Levels and Rarities</label>
|
||||
</div>
|
||||
<div class="my-auto inline-block flex-1">
|
||||
<input id="unique" type="checkbox" role="switch" class="min-h-6 min-w-6 align-middle" bind:checked={unique} />
|
||||
<label for="unique">Include Uniques</label>
|
||||
</div>
|
||||
</div>
|
||||
{#each tagTypes as { name, includes } (name)}
|
||||
<div class="mt-1 flex flex-row">
|
||||
<span class="my-auto h-0 flex-1 border"></span>
|
||||
<span class="m-2 flex-none text-sm italic">{name}</span>
|
||||
<span class="my-auto h-0 flex-1 border"></span>
|
||||
</div>
|
||||
<div class="flex w-full flex-wrap place-content-center-safe gap-6 md:grid-cols-4">
|
||||
{#each includes as t (t.tag)}
|
||||
<div class="inline-block">
|
||||
<input id={t.name} type="checkbox" class="min-h-6 min-w-6 align-middle" bind:checked={t.on} />
|
||||
<label for={t.name} class="align-middle">{t.name}</label>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</form>
|
||||
|
||||
<span class="mb-4 block text-center text-2xl">{skills.length} skills selected</span>
|
||||
<div class="grid max-w-7xl grid-cols-1 gap-2 md:grid-cols-3">
|
||||
{#each skills as s (s.skill_id)}
|
||||
<div class="rounded-md border px-2 pt-1 pb-2 text-center shadow-sm transition-shadow hover:shadow-md">
|
||||
<span class="block text-xl">{s.name}</span>
|
||||
<span class="block italic">{s.description}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="mx-auto mt-12 w-full max-w-4xl border-t pt-4 md:mt-8">
|
||||
<ul class="ml-4 list-disc">
|
||||
<li>
|
||||
To see skills that can be received from MANT/Trackblazer rivals, select the running style used and the distance and surface
|
||||
of the race.
|
||||
</li>
|
||||
<li>Skills for each tag are auto-generated from the game's local database.</li>
|
||||
<li>Tag names are inferred from the skills that have them.</li>
|
||||
</ul>
|
||||
</div>
|
||||
Reference in New Issue
Block a user