feat: show effective production per generator with all bonuses
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s
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:
@@ -2,6 +2,7 @@
|
|||||||
import { scale } from 'svelte/transition';
|
import { scale } from 'svelte/transition';
|
||||||
import { quintOut } from 'svelte/easing';
|
import { quintOut } from 'svelte/easing';
|
||||||
import { game } from '$lib/stores/game.svelte';
|
import { game } from '$lib/stores/game.svelte';
|
||||||
|
import { generatorEffectiveProduction } from '$lib/core/economy';
|
||||||
import { formatNumber } from '$lib/utils/formatNumber';
|
import { formatNumber } from '$lib/utils/formatNumber';
|
||||||
import CollapsiblePanel from './CollapsiblePanel.svelte';
|
import CollapsiblePanel from './CollapsiblePanel.svelte';
|
||||||
</script>
|
</script>
|
||||||
@@ -14,12 +15,14 @@
|
|||||||
{#each game.state.generators as gen, i}
|
{#each game.state.generators as gen, i}
|
||||||
{@const cost = game.generatorCostWithTree(gen)}
|
{@const cost = game.generatorCostWithTree(gen)}
|
||||||
{@const canAfford = game.state.resources >= cost}
|
{@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
|
<div
|
||||||
class="gp-row {canAfford ? 'gp-row--active' : 'gp-row--locked'}"
|
class="gp-row {canAfford ? 'gp-row--active' : 'gp-row--locked'}"
|
||||||
in:scale={{ delay: i * 30, duration: 200, start: 0.95, easing: quintOut }}
|
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">
|
<div class="flex items-center gap-1.5">
|
||||||
<span class="gp-value">{gen.name}</span>
|
<span class="gp-value">{gen.name}</span>
|
||||||
{#if gen.owned > 0}
|
{#if gen.owned > 0}
|
||||||
@@ -31,12 +34,19 @@
|
|||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<span class="gp-label">
|
{#if gen.owned > 0}
|
||||||
+{gen.baseProduction}/s
|
<div class="flex items-center gap-1">
|
||||||
{#if gen.owned > 0}
|
<span class="gp-label gp-accent-green">{formatNumber(effectiveProd)}/s</span>
|
||||||
<span class="gp-accent-green"> · {formatNumber(currentProd)}/s</span>
|
<span class="gp-label">·</span>
|
||||||
{/if}
|
<span class="gp-label">{share.toFixed(0)}%</span>
|
||||||
</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}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onclick={() => game.buy(gen.id)}
|
onclick={() => game.buy(gen.id)}
|
||||||
|
|||||||
@@ -575,20 +575,19 @@ export function generatorCost(gen: Generator, tree?: EvolutionNode[]): number {
|
|||||||
return Math.max(1, Math.floor(base * (1 - reduction)));
|
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
|
// Production totale par seconde de tous les générateurs
|
||||||
export function totalProductionPerSecond(state: GameState): number {
|
export function totalProductionPerSecond(state: GameState): number {
|
||||||
const nidBoost = getGeneratorBoostFromTree(state.evolutionTree);
|
return state.generators.reduce((sum, gen) => sum + generatorEffectiveProduction(gen, state), 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lazy calculation : ressources accumulées depuis lastTick
|
// Lazy calculation : ressources accumulées depuis lastTick
|
||||||
|
|||||||
Reference in New Issue
Block a user