zenno/doc/spark: spark explorer
This commit is contained in:
+100
-6
@@ -28,22 +28,116 @@ export interface Spark {
|
||||
* Spark type.
|
||||
* Roughly the spark color, with extra subdivisions for white sparks.
|
||||
*/
|
||||
type: 1 | 2 | 5 | 4 | 6 | 7 | 10 | 8 | 11 | 9 | 3;
|
||||
type: Type;
|
||||
/**
|
||||
* Possible effects applied by the spark during inspiration.
|
||||
* A random element is selected from this list according to unknown
|
||||
* distributions, then all effects in that selection are applied.
|
||||
*/
|
||||
effects: SparkEffect[][];
|
||||
effects: Effect[][];
|
||||
}
|
||||
|
||||
/**
|
||||
* Spark types.
|
||||
* Roughly the spark color, with extra subdivisions for white sparks.
|
||||
*/
|
||||
export enum Type {
|
||||
Stat = 1,
|
||||
Aptitude = 2,
|
||||
Unique = 3,
|
||||
Skill = 4,
|
||||
Race = 5,
|
||||
Scenario = 6,
|
||||
CarnivalBonus = 7,
|
||||
Distance = 8,
|
||||
Hidden = 9,
|
||||
Surface = 10,
|
||||
Style = 11,
|
||||
}
|
||||
|
||||
/** Mapping of spark types to their names. */
|
||||
export const TYPE_NAMES: Readonly<Record<Type, string>> = {
|
||||
[Type.Stat]: 'Stat (Blue)',
|
||||
[Type.Aptitude]: 'Aptitude (Pink)',
|
||||
[Type.Unique]: 'Unique (Green)',
|
||||
[Type.Skill]: 'Skill',
|
||||
[Type.Race]: 'Race',
|
||||
[Type.Scenario]: 'Scenario',
|
||||
[Type.CarnivalBonus]: 'Carnival Bonus (Scarlet)',
|
||||
[Type.Distance]: 'Distance (White)',
|
||||
[Type.Hidden]: 'Hidden (White)',
|
||||
[Type.Surface] : 'Surface (White)',
|
||||
[Type.Style] : 'Style (White)',
|
||||
};
|
||||
|
||||
/**
|
||||
* Spark effect types.
|
||||
*/
|
||||
export enum Target {
|
||||
Speed = 1,
|
||||
Stamina = 2,
|
||||
Power = 3,
|
||||
Guts = 4,
|
||||
Wit = 5,
|
||||
SkillPoints = 6,
|
||||
RandomStat = 7,
|
||||
Turf = 11,
|
||||
Dirt = 12,
|
||||
FrontRunner = 21,
|
||||
PaceChaser = 22,
|
||||
LateSurger = 23,
|
||||
EndCloser = 24,
|
||||
Sprint = 31,
|
||||
Mile = 32,
|
||||
Medium = 33,
|
||||
Long = 34,
|
||||
Skill = 41,
|
||||
CarnivalBonus = 51,
|
||||
SpeedCap = 61,
|
||||
StaminaCap = 62,
|
||||
PowerCap = 63,
|
||||
GutsCap = 64,
|
||||
WitCap = 65,
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of spark target types to their names.
|
||||
* Note that Skill does not include the skill name.
|
||||
*/
|
||||
export const TARGET_NAMES: Readonly<Record<Target, string>> = {
|
||||
[Target.Speed]: 'Speed',
|
||||
[Target.Stamina]: 'Stamina',
|
||||
[Target.Power]: 'Power',
|
||||
[Target.Guts]: 'Guts',
|
||||
[Target.Wit]: 'Wit',
|
||||
[Target.SkillPoints]: 'SP',
|
||||
[Target.RandomStat]: 'Random Stat',
|
||||
[Target.Turf]: 'Turf aptitude',
|
||||
[Target.Dirt]: 'Dirt aptitude',
|
||||
[Target.FrontRunner]: 'Front Runner aptitude',
|
||||
[Target.PaceChaser]: 'Pace Chaser aptitude',
|
||||
[Target.LateSurger]: 'Late Surger aptitude',
|
||||
[Target.EndCloser]: 'End Closer aptitude',
|
||||
[Target.Sprint]: 'Sprint aptitude',
|
||||
[Target.Mile]: 'Mile aptitude',
|
||||
[Target.Medium]: 'Medium aptitude',
|
||||
[Target.Long]: 'Long aptitude',
|
||||
[Target.Skill]: 'hint level',
|
||||
[Target.CarnivalBonus]: 'Carnival Bonus level',
|
||||
[Target.SpeedCap]: 'Speed cap',
|
||||
[Target.StaminaCap]: 'Stamina cap',
|
||||
[Target.PowerCap]: 'Power cap',
|
||||
[Target.GutsCap]: 'Guts cap',
|
||||
[Target.WitCap]: 'Wit cap',
|
||||
}
|
||||
|
||||
/**
|
||||
* Effects that a spark can apply.
|
||||
*/
|
||||
export interface SparkEffect {
|
||||
target: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 41 | 51 | 61 | 62 | 63 | 64 | 65;
|
||||
value1?: number;
|
||||
value2: number;
|
||||
export interface Effect {
|
||||
target: Target;
|
||||
value1: number;
|
||||
value2?: number;
|
||||
}
|
||||
|
||||
export async function sparks(): Promise<Spark[]> {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<script lang="ts">
|
||||
import * as skill from '$lib/data/skill';
|
||||
import * as spark from '$lib/data/spark';
|
||||
import { onMount } from 'svelte';
|
||||
import { SvelteMap } from 'svelte/reactivity';
|
||||
|
||||
let sparks: spark.Spark[] = $state([]);
|
||||
let skills: SvelteMap<number, skill.Skill> = new SvelteMap();
|
||||
onMount(async () => {
|
||||
const [sp, sk] = await Promise.all([spark.sparks(), skill.skills()]);
|
||||
sparks = sp;
|
||||
for (const s of sk) {
|
||||
skills.set(s.skill_id, s);
|
||||
}
|
||||
});
|
||||
|
||||
let group = $state(1);
|
||||
|
||||
const groups = $derived.by(() => {
|
||||
const m = new Map<number, spark.Spark[]>();
|
||||
for (const s of sparks) {
|
||||
const l = m.get(s.spark_group) ?? [];
|
||||
l.push(s);
|
||||
m.set(s.spark_group, l);
|
||||
}
|
||||
return [...m.entries()];
|
||||
});
|
||||
function describe(eff: spark.Effect) {
|
||||
if (eff.target === spark.Target.Skill) {
|
||||
const sk = skills.get(eff.value1);
|
||||
return `${sk?.name} ${spark.TARGET_NAMES[eff.target]} +${eff.value2}`;
|
||||
}
|
||||
return `${spark.TARGET_NAMES[eff.target]} +${eff.value1}`;
|
||||
}
|
||||
const cur = $derived(sparks.find((s) => s.spark_group === group));
|
||||
const curEffectGroups = $derived(cur?.effects ?? []);
|
||||
const curDescriptions = $derived(curEffectGroups.map((g) => g.map((e) => describe(e))));
|
||||
</script>
|
||||
|
||||
<h1 class="text-4xl">Spark Explorer</h1>
|
||||
<form class="mx-auto mt-8 p-4 rounded-md text-center shadow-md ring md:max-w-2xl">
|
||||
<select class="w-full" bind:value={group}>
|
||||
{#each groups as [id, s] (id)}
|
||||
<option value={id}>{s[0].name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</form>
|
||||
<svelte:boundary>
|
||||
<div class="mx-auto mt-8 max-w-md flex-1 flex-col rounded-md border p-2 text-center shadow-sm transition-shadow hover:shadow-md">
|
||||
<span class="block text-xl">{cur?.name}</span>
|
||||
<span class="block">{cur?.description}</span>
|
||||
</div>
|
||||
<table class="mx-auto w-full max-w-xl mt-8 table-fixed">
|
||||
<caption class="text-xl">Possible Effects</caption>
|
||||
<tbody>
|
||||
{#each curDescriptions as s (s)}
|
||||
<tr class="text-center even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td>
|
||||
{#each s as n (n)}
|
||||
<span class="block">{n}</span>
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{#snippet pending()}
|
||||
<div>Loading data...</div>
|
||||
{/snippet}
|
||||
</svelte:boundary>
|
||||
Reference in New Issue
Block a user