diff --git a/zenno/src/lib/StatChart.svelte b/zenno/src/lib/StatChart.svelte index 8415a90..af94804 100644 --- a/zenno/src/lib/StatChart.svelte +++ b/zenno/src/lib/StatChart.svelte @@ -55,39 +55,37 @@ let width = $state(0); let height = $state(0); - let expand = $state(false); - - const xLabel = $derived(Stat[stat]); + const xLabel = $derived(`Raw ${Stat[stat]}`); const xLines = $derived([xRule].flat(1)); const xMin = $derived(xRange?.[0] ?? 200); const xMax = $derived.by(() => { if (xRange?.[1] != null) { return xRange[1]; } - if (expand) { - return 2000; - } - return 100 * Math.ceil(Math.max(1200, ...xLines) / 100); + return 100 * Math.ceil(Math.max(2000, ...xLines) / 100); }); const xVal = $derived(d3.range(xMin, xMax + 1, 5)); // +1 because d3.range does not include the max const thrX = 1200; + function adj(x: number): number { + return Math.min(x, 1200) + 0.5 * (Math.max(x, 1200) - 1200); + } const series = $derived([y].flat(1).filter((s) => s != null)); const areas = $derived([yArea].flat(1).filter((s) => s != null)); - const vals = $derived(series.flatMap(({ y, label }) => xVal.map((x) => ({ x, y: y(x), label })))); - const areaVals = $derived(areas.flatMap(({ y1, y2, label }) => xVal.map((x) => ({ x, y1: y1(x), y2: y2(x), label })))); + const vals = $derived(series.flatMap(({ y, label }) => xVal.map((x) => ({ x, y: y(adj(x), x), label })))); + const areaVals = $derived(areas.flatMap(({ y1, y2, label }) => xVal.map((x) => ({ x, y1: y1(adj(x), x), y2: y2(adj(x), x), label })))); const yRange: [number, number] = $derived.by(() => { if (range != null) { if (range.length === 2) { return range; } - return [range[0], expand ? range[2] : range[1]]; + return [range[0], range[2]]; } const l = d3.min(vals, ({ y }) => y) ?? 0; const r = d3.max(vals, ({ y }) => y) ?? 1; return [l, r]; }); - const yLines = $derived(xLines.flatMap((x) => series.map(({ y, label }) => ({ y: y(x), label })))); + const yLines = $derived(xLines.flatMap((x) => series.map(({ y, label }) => ({ y: y(adj(x), x), label })))); const makeChart: Attachment = (el) => { $effect(() => { diff --git a/zenno/src/lib/chart.ts b/zenno/src/lib/chart.ts index d95c04b..1c24387 100644 --- a/zenno/src/lib/chart.ts +++ b/zenno/src/lib/chart.ts @@ -1,11 +1,11 @@ export interface ComputedSeries { - y: (x: number) => number; + y: (base: number, raw: number) => number; label: string; } export interface ComputedAreas { - y1: (x: number) => number; - y2: (x: number) => number; + y1: (base: number, raw: number) => number; + y2: (base: number, raw: number) => number; label: string; } diff --git a/zenno/src/lib/race.ts b/zenno/src/lib/race.ts index 874e340..708d03d 100644 --- a/zenno/src/lib/race.ts +++ b/zenno/src/lib/race.ts @@ -519,7 +519,8 @@ export function speedGain(speedBonus: number, dur: number, accel: number | null, * @returns Probability per candidate to accept */ export function reducedSpurtChance(witStat: number): number { - return 0.15 + 0.0005 * witStat; + // 1900 wit style S exceeds 100% chance if we don't explicitly cap. + return Math.min(0.15 + 0.0005 * witStat, 1); } /** diff --git a/zenno/src/routes/doc/frbm/+page.svelte b/zenno/src/routes/doc/frbm/+page.svelte index 8a1e502..acc7c15 100644 --- a/zenno/src/routes/doc/frbm/+page.svelte +++ b/zenno/src/routes/doc/frbm/+page.svelte @@ -414,8 +414,8 @@ never happen, its duration also scales with the guts stat. Unlike skills, its duration does not scale with race distance.

- - + +

Spot struggle also greatly increases HP consumption. For normal front runners, the rate is slightly less than Rushed. For @@ -443,7 +443,7 @@ y={laneComboSeries} yLabel="Speed Boost" yRule={lcYRule} - range={[0.2, 0.5]} + range={[0.2, 0.6]} />

@@ -530,7 +530,7 @@ stat={Stat.Wit} y={downhillSeries} yLabel="Entry Chance (% each second)" - range={[0, 60]} + range={[0, 75]} />

@@ -550,7 +550,7 @@ stat={Stat.Wit} yArea={secSpeedSeries} yLabel="Section Speed (m/s)" - range={[17.5, 22.5]} + range={[17, 23]} plotOptions={{ color: { legend: true } }} />

diff --git a/zenno/src/routes/doc/race/+page.svelte b/zenno/src/routes/doc/race/+page.svelte index 253604a..603a7b5 100644 --- a/zenno/src/routes/doc/race/+page.svelte +++ b/zenno/src/routes/doc/race/+page.svelte @@ -67,10 +67,13 @@ ]); const laneChange: ComputedSeries[] = [{ label: 'Lane Change Target Speed', y: (x) => race.laneChangeSpeed(x) }]; const gutsSpurt: Array = $derived([ - { label: `Speed 1200`, y: (x) => race.spurtSpeed(1200, x, style, distanceApt, raceLen) }, { label: `Speed 600`, y: (x) => race.spurtSpeed(600, x, style, distanceApt, raceLen) }, + { label: `Speed 1200`, y: (x) => race.spurtSpeed(1200, x, style, distanceApt, raceLen) }, + // NOTE(zeph): The label is 1600 despite the input being 1400 + // for raw vs final difference. + { label: `Speed 1600`, y: (x) => race.spurtSpeed(1400, x, style, distanceApt, raceLen) }, distanceApt !== race.AptitudeLevel.A - ? { label: `${raceLenType} A, Speed 1200`, y: (x) => race.spurtSpeed(1200, x, style, race.AptitudeLevel.A, raceLen) } + ? { label: `${raceLenType} A, Speed 1600`, y: (x) => race.spurtSpeed(1400, x, style, race.AptitudeLevel.A, raceLen) } : null, ]); const minSpeed: ComputedSeries[] = $derived([{ label: 'Minimum Speed', y: (x) => race.minSpeed(raceLen, x) }]); @@ -241,7 +244,7 @@ Spurt Speed

Target speed during the Uma's last spurt. See also the effect of Guts.

- {@render statChart(race.Stat.Speed, spurtSpeed, 'Spurt Speed (m/s)', [20, 26], { len: true, style: true, dist: true })} + {@render statChart(race.Stat.Speed, spurtSpeed, 'Spurt Speed (m/s)', [20, 26.5], { len: true, style: true, dist: true })} Late Race Speed

Base target speed during late race when the Uma is not spurting (but not dead yet).

@@ -261,7 +264,7 @@ href={resolve('/doc/frbm#lane-combo')}>lane combo.

- {@render statChart(race.Stat.Power, moveLane, 'Target Speed Modifier (m/s)', [0.2, 0.5])} + {@render statChart(race.Stat.Power, moveLane, 'Target Speed Modifier (m/s)', [0.2, 0.6])} Uphill Target Speed Loss

Target speed modifier while running uphill.

@@ -269,7 +272,7 @@ Acceleration

Acceleration.

- {@render statChart(race.Stat.Power, accel, 'Acceleration (m/s²)', [0.1, 0.5], { style: true })} + {@render statChart(race.Stat.Power, accel, 'Acceleration (m/s²)', [0.1, 0.55], { style: true })} Lane Change Target Speed

Horizontal (rather than forward) target speed of changing lanes.

@@ -279,7 +282,7 @@ stat={race.Stat.Power} y={laneChange} yLabel="Lane Change Target Speed (CW/s)" - range={[0.01, 0.03]} + range={[0.01, 0.04]} />
@@ -287,11 +290,11 @@ Spurt Speed

Target speed during the Uma's last spurt. See also the effect of Speed.

- {@render statChart(race.Stat.Guts, gutsSpurt, 'Spurt Speed (m/s)', [20, 26], { len: true, style: true, dist: true })} + {@render statChart(race.Stat.Guts, gutsSpurt, 'Spurt Speed (m/s)', [20, 26.5], { len: true, style: true, dist: true })} Minimum Speed

Forced minimum speed, as well as target speed when out of HP.

- {@render statChart(race.Stat.Guts, minSpeed, 'Target Speed (m/s)', [15.8, 18.4], { len: true })} + {@render statChart(race.Stat.Guts, minSpeed, 'Target Speed (m/s)', [15.8, 18.5], { len: true })} Late Race HP Consumption Rate Modifier

Multiplier on HP consumption rate during late race and last spurt phase.

@@ -300,15 +303,15 @@ Spot Struggle

Speed boost and duration of spot struggle.

- - + +
Dueling

Speed boost and acceleration boost of dueling.

- - + +
Wit @@ -321,7 +324,7 @@ stat={race.Stat.Wit} yArea={secSpeed} yLabel="Section Speed (m/s)" - range={[17.5, 22.5]} + range={[17, 23]} plotOptions={{ color: { legend: true } }} />
@@ -347,7 +350,7 @@ Downhill Accel Mode Chance

Chance each second to enter downhill accel mode when eligible.

- {@render statChart(race.Stat.Wit, downhill, 'Entry Chance (% each second)', [0, 60])} + {@render statChart(race.Stat.Wit, downhill, 'Entry Chance (% each second)', [0, 75])} Reduced Spurt Accept Chance

Chance to accept each checked spurt delay and speed when not full spurting.

diff --git a/zenno/src/routes/race/mspeed/+page.svelte b/zenno/src/routes/race/mspeed/+page.svelte index d879f86..802c9a0 100644 --- a/zenno/src/routes/race/mspeed/+page.svelte +++ b/zenno/src/routes/race/mspeed/+page.svelte @@ -169,7 +169,7 @@ stat={Stat.Guts} y={ssY} yLabel="Lengths Gained" - range={[0, 1.5, 2.5]} + range={[0, 2]} xRule={gutsStat} yRule={ssYRule} /> @@ -178,7 +178,7 @@ stat={Stat.Power} y={lcY} yLabel="Lengths Gained" - range={[0, 1.5, 2.5]} + range={[0, 1.1]} xRule={powerStat} yRule={lcYRule} />