feat: click expected value + contribution display
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s

CockpitHeader: /clic shows expected value (double+crit included), amber.
ClickPanel: full breakdown with expected value, contribution estimate
(~5 clics/s → X/s + auto → Y% of total), formula visible.
Passif/clic distinction clear in the cockpit.
This commit is contained in:
2026-03-28 21:01:17 +01:00
parent 25768e3665
commit f4bc25b3b1
2 changed files with 48 additions and 15 deletions

View File

@@ -5,16 +5,44 @@
import CollapsiblePanel from './CollapsiblePanel.svelte'; import CollapsiblePanel from './CollapsiblePanel.svelte';
let b = $derived(getClickBreakdown(game.state)); let b = $derived(getClickBreakdown(game.state));
let expected = $derived(b.total * (1 + b.doubleChance + b.critChance * 9));
// Estimate: 5 clicks/sec manual → effective click production
const CLICKS_PER_SEC = 5;
let manualProd = $derived(expected * CLICKS_PER_SEC);
let totalWithClicks = $derived(game.productionPerSecond + b.effectivePerSec + manualProd);
let clickShare = $derived(totalWithClicks > 0 ? ((b.effectivePerSec + manualProd) / totalWithClicks * 100) : 0);
</script> </script>
<CollapsiblePanel title="Ponte (clic)" badge="{formatNumber(b.total)}/clic" accentClass="" defaultOpen={false}> <CollapsiblePanel title="Ponte (clic)" badge="{formatNumber(expected)}/clic" accentClass="gp-accent-amber" defaultOpen={false}>
<!-- Main click value --> <!-- Expected value -->
<div class="gp-row gp-row--active"> <div class="gp-row gp-row--active">
<div class="flex flex-col"> <div class="flex flex-col flex-1">
<span class="gp-value">Gain par clic</span> <span class="gp-value">Valeur attendue par clic</span>
<span class="gp-label">base {b.base} × prestige x{b.prestigeMult.toFixed(1)} × arbre x{b.treeMult.toFixed(1)}</span> <span class="gp-label">
{formatNumber(b.total)} base
{#if b.doubleChance > 0} + {(b.doubleChance * 100).toFixed(0)}% double{/if}
{#if b.critChance > 0} + {(b.critChance * 100).toFixed(0)}% crit x10{/if}
</span>
</div> </div>
<span class="gp-value gp-accent-green text-lg!">{formatNumber(b.total)}</span> <span class="gp-value gp-accent-amber text-lg!">{formatNumber(expected)}</span>
</div>
<!-- Click contribution estimate -->
<div class="gp-row" style="border-color: rgba(251,191,36,0.15); background: rgba(251,191,36,0.04);">
<div class="flex flex-col flex-1">
<span class="gp-value text-[0.7rem]!">Contribution clics</span>
<span class="gp-label">
~{CLICKS_PER_SEC} clics/s → {formatNumber(manualProd)}/s
{#if b.autoClicksPerSec > 0} + auto {formatNumber(b.effectivePerSec)}/s{/if}
</span>
</div>
<span class="gp-label gp-accent-amber">{clickShare.toFixed(0)}%</span>
</div>
<!-- Breakdown formula -->
<div class="flex flex-col gap-0.5 px-1">
<span class="gp-zone-label">Formule</span>
<span class="gp-label">base ({b.base}) × prestige (x{b.prestigeMult.toFixed(1)}) × arbre (x{b.treeMult.toFixed(1)}) = {formatNumber(b.total)}</span>
</div> </div>
<!-- Double ponte --> <!-- Double ponte -->
@@ -23,7 +51,7 @@
<span class="gp-value text-[0.7rem]!">Double Ponte</span> <span class="gp-value text-[0.7rem]!">Double Ponte</span>
<span class="gp-label"> <span class="gp-label">
{#if b.doubleChance > 0} {#if b.doubleChance > 0}
{(b.doubleChance * 100).toFixed(0)}% chance × 2 tetards {(b.doubleChance * 100).toFixed(0)}% chance de doubler
{:else} {:else}
Branche Ponte — "Double Ponte" (5 ADN) Branche Ponte — "Double Ponte" (5 ADN)
{/if} {/if}
@@ -42,7 +70,7 @@
<span class="gp-value text-[0.7rem]!">Ponte Critique</span> <span class="gp-value text-[0.7rem]!">Ponte Critique</span>
<span class="gp-label"> <span class="gp-label">
{#if b.critChance > 0} {#if b.critChance > 0}
{(b.critChance * 100).toFixed(0)}% chance × 10 tetards {(b.critChance * 100).toFixed(0)}% chance de x10
{:else} {:else}
Branche Ponte — "Ponte Critique" (20 ADN) Branche Ponte — "Ponte Critique" (20 ADN)
{/if} {/if}
@@ -61,7 +89,7 @@
<span class="gp-value text-[0.7rem]!">Auto-Ponte</span> <span class="gp-value text-[0.7rem]!">Auto-Ponte</span>
<span class="gp-label"> <span class="gp-label">
{#if b.autoClicksPerSec > 0} {#if b.autoClicksPerSec > 0}
{b.autoClicksPerSec.toFixed(1)}/s × {formatNumber(b.total)} = {formatNumber(b.effectivePerSec)}/s {b.autoClicksPerSec.toFixed(1)} clics/s auto → {formatNumber(b.effectivePerSec)}/s
{:else} {:else}
Capstone Ponte — "Ponte Automatique" (200 ADN) Capstone Ponte — "Ponte Automatique" (200 ADN)
{/if} {/if}
@@ -74,7 +102,7 @@
{/if} {/if}
</div> </div>
<!-- How to boost hint --> <!-- Hint -->
{#if b.treeMult <= 1} {#if b.treeMult <= 1}
<div class="text-center py-1"> <div class="text-center py-1">
<span class="gp-label gp-accent-amber">Depense ton ADN dans la branche Ponte pour booster tes clics</span> <span class="gp-label gp-accent-amber">Depense ton ADN dans la branche Ponte pour booster tes clics</span>

View File

@@ -1,17 +1,22 @@
<script lang="ts"> <script lang="ts">
import { game } from '$lib/stores/game.svelte'; import { game } from '$lib/stores/game.svelte';
import { getClickBreakdown } from '$lib/core/economy';
import { formatNumber } from '$lib/utils/formatNumber'; import { formatNumber } from '$lib/utils/formatNumber';
let cb = $derived(getClickBreakdown(game.state));
// Expected value per click = total × (1 + doubleChance + critChance × 9)
let expectedPerClick = $derived(cb.total * (1 + cb.doubleChance + cb.critChance * 9));
</script> </script>
<div class="gp"> <div class="gp">
<div class="grid grid-cols-5 gap-0.5 px-1"> <div class="grid grid-cols-5 gap-0.5 px-1">
<div class="gp-stat" title="Production automatique par seconde"> <div class="gp-stat" title="Production passive par seconde (generateurs)">
<span class="gp-label">Prod/s</span> <span class="gp-label">Passif</span>
<span class="gp-value gp-accent-green text-[0.8rem]!">{formatNumber(game.productionPerSecond)}</span> <span class="gp-value gp-accent-green text-[0.8rem]!">{formatNumber(game.productionPerSecond)}/s</span>
</div> </div>
<div class="gp-stat" title="Tetards gagnes par clic"> <div class="gp-stat" title="Valeur attendue par clic (double + crit inclus)">
<span class="gp-label">/clic</span> <span class="gp-label">/clic</span>
<span class="gp-value text-[0.8rem]!">{formatNumber(game.clickGain)}</span> <span class="gp-value gp-accent-amber text-[0.8rem]!">{formatNumber(expectedPerClick)}</span>
</div> </div>
<div class="gp-stat" title="Multiplicateur global (prestige)"> <div class="gp-stat" title="Multiplicateur global (prestige)">
<span class="gp-label">Mult</span> <span class="gp-label">Mult</span>