feat: show effective production per generator with all bonuses
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s

New generatorEffectiveProduction() — applies prestige mult, tree mult,
nid boost, synergy, and convergence to per-generator production.

GeneratorShop now shows:
- Effective prod/s (green, with all bonuses)
- % share of total production
- Mini progress bar per generator
- When owned=0: shows effective prod per unit (so you see upgrade impact)
This commit is contained in:
2026-03-28 20:47:24 +01:00
parent 39921aa8fc
commit 9d27cb6648
2 changed files with 29 additions and 20 deletions

View File

@@ -2,6 +2,7 @@
import { scale } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
import { game } from '$lib/stores/game.svelte';
import { generatorEffectiveProduction } from '$lib/core/economy';
import { formatNumber } from '$lib/utils/formatNumber';
import CollapsiblePanel from './CollapsiblePanel.svelte';
</script>
@@ -14,12 +15,14 @@
{#each game.state.generators as gen, i}
{@const cost = game.generatorCostWithTree(gen)}
{@const canAfford = game.state.resources >= cost}
{@const currentProd = gen.baseProduction * gen.owned}
{@const effectiveProd = generatorEffectiveProduction(gen, game.state)}
{@const nextUnitProd = generatorEffectiveProduction({ ...gen, owned: 1 }, game.state)}
{@const share = game.productionPerSecond > 0 ? (effectiveProd / game.productionPerSecond * 100) : 0}
<div
class="gp-row {canAfford ? 'gp-row--active' : 'gp-row--locked'}"
in:scale={{ delay: i * 30, duration: 200, start: 0.95, easing: quintOut }}
>
<div class="flex flex-col min-w-0">
<div class="flex flex-col min-w-0 flex-1">
<div class="flex items-center gap-1.5">
<span class="gp-value">{gen.name}</span>
{#if gen.owned > 0}
@@ -31,12 +34,19 @@
</span>
{/if}
</div>
<span class="gp-label">
+{gen.baseProduction}/s
{#if gen.owned > 0}
<span class="gp-accent-green"> · {formatNumber(currentProd)}/s</span>
<div class="flex items-center gap-1">
<span class="gp-label gp-accent-green">{formatNumber(effectiveProd)}/s</span>
<span class="gp-label">·</span>
<span class="gp-label">{share.toFixed(0)}%</span>
</div>
<!-- Mini progress showing share of total production -->
<div class="h-[2px] rounded-full mt-0.5" style="background: rgba(255,255,255,0.06);">
<div class="h-full rounded-full" style="width: {Math.min(share, 100)}%; background: var(--color-gp-accent-green); opacity: 0.5;"></div>
</div>
{:else}
<span class="gp-label">+{formatNumber(nextUnitProd)}/s par unite</span>
{/if}
</span>
</div>
<button
onclick={() => game.buy(gen.id)}

View File

@@ -575,20 +575,19 @@ export function generatorCost(gen: Generator, tree?: EvolutionNode[]): number {
return Math.max(1, Math.floor(base * (1 - reduction)));
}
// Production effective d'un seul générateur (avec tous les bonus appliqués)
export function generatorEffectiveProduction(gen: Generator, state: GameState): number {
if (gen.owned === 0) return 0;
const nidBoost = gen.id === "nid" ? getGeneratorBoostFromTree(state.evolutionTree) : 1;
const treeMultiplier = getProductionMultiplierFromTree(state.evolutionTree);
const synergyMult = getGeneratorSynergyMultiplier(state.evolutionTree, state.generators);
const convergenceBoost = getAllEffectsBoost(state.evolutionTree);
return gen.baseProduction * gen.owned * nidBoost * state.prestigeMultiplier * treeMultiplier * synergyMult * convergenceBoost;
}
// Production totale par seconde de tous les générateurs
export function totalProductionPerSecond(state: GameState): number {
const nidBoost = getGeneratorBoostFromTree(state.evolutionTree);
const synergyMult = getGeneratorSynergyMultiplier(state.evolutionTree, state.generators);
const base = state.generators.reduce(
(sum, gen) => {
const boost = gen.id === "nid" ? nidBoost : 1;
return sum + gen.baseProduction * gen.owned * boost;
},
0
);
const treeMultiplier = getProductionMultiplierFromTree(state.evolutionTree);
const convergenceBoost = getAllEffectsBoost(state.evolutionTree);
return base * state.prestigeMultiplier * treeMultiplier * synergyMult * convergenceBoost;
return state.generators.reduce((sum, gen) => sum + generatorEffectiveProduction(gen, state), 0);
}
// Lazy calculation : ressources accumulées depuis lastTick