feat: click upgrades — buy click power with tadpoles, tied to generators
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
5 click upgrades, each linked to a generator type: - Nid Douillet (+1/clic, 50 base) — requires owning a Nid - Eau Fertile (+3/clic, 500 base) — requires a Mare - Spores Actives (+8/clic, 5k base) — requires a Marecage - Courant Vital (+20/clic, 50k base) — requires an Etang - Source Ancestrale (+50/clic, 500k base) — requires a Lac Cost scales x1.2 per level. Reset at prestige (like generators). Click gain = (base + upgradePower) × prestige × tree × infraBonus. ClickPanel shows upgrade shop with level badges and gen requirements. Adds tadpole sink for active play — strategic choice vs buying generators.
This commit is contained in:
@@ -1,34 +1,36 @@
|
|||||||
<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 { getClickBreakdown, clickUpgradeCost } 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';
|
||||||
|
|
||||||
let b = $derived(getClickBreakdown(game.state));
|
let b = $derived(getClickBreakdown(game.state));
|
||||||
let expected = $derived(b.total * (1 + b.doubleChance + b.critChance * 9));
|
let expected = $derived(b.total * (1 + b.doubleChance + b.critChance * 9));
|
||||||
// Estimate: 5 clicks/sec manual → effective click production
|
|
||||||
const CLICKS_PER_SEC = 5;
|
const CLICKS_PER_SEC = 5;
|
||||||
let manualProd = $derived(expected * CLICKS_PER_SEC);
|
let manualProd = $derived(expected * CLICKS_PER_SEC);
|
||||||
let totalWithClicks = $derived(game.productionPerSecond + b.effectivePerSec + manualProd);
|
let totalWithClicks = $derived(game.productionPerSecond + b.effectivePerSec + manualProd);
|
||||||
let clickShare = $derived(totalWithClicks > 0 ? ((b.effectivePerSec + manualProd) / totalWithClicks * 100) : 0);
|
let clickShare = $derived(totalWithClicks > 0 ? ((b.effectivePerSec + manualProd) / totalWithClicks * 100) : 0);
|
||||||
|
|
||||||
|
// Generator names for display
|
||||||
|
const GEN_NAMES: Record<string, string> = {
|
||||||
|
nid: 'Nid', mare: 'Mare', marecage: 'Marecage', etang: 'Etang', lac: 'Lac',
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CollapsiblePanel title="Ponte (clic)" badge="{formatNumber(expected)}" accentClass="gp-accent-amber" defaultOpen={false}>
|
<CollapsiblePanel title="Ponte (clic)" badge="{formatNumber(b.total)}" accentClass="gp-accent-amber" defaultOpen={false}>
|
||||||
<!-- Gain par clic -->
|
<!-- Gain par clic -->
|
||||||
<div class="gp-row gp-row--active">
|
<div class="gp-row gp-row--active">
|
||||||
<div class="flex flex-col flex-1">
|
<div class="flex flex-col flex-1">
|
||||||
<span class="gp-value">Gain par clic</span>
|
<span class="gp-value">Gain par clic</span>
|
||||||
<span class="gp-label">
|
<span class="gp-label">
|
||||||
x{b.prestigeMult.toFixed(1)} prestige · x{b.treeMult.toFixed(0)} arbre · x{b.genBonus.toFixed(1)} infra
|
base {b.base} × x{b.prestigeMult.toFixed(1)} × x{b.treeMult.toFixed(0)} × x{b.genBonus.toFixed(1)}
|
||||||
</span>
|
|
||||||
<span class="gp-label" style="opacity: 0.5;">
|
|
||||||
{b.genTypes} types (+{b.genTypes * 2}) · {b.genTotal} unites (+{(b.genTotal * 0.05).toFixed(1)})
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="gp-value gp-accent-amber text-lg!">{formatNumber(b.total)}</span>
|
<span class="gp-value gp-accent-amber text-lg!">{formatNumber(b.total)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Click contribution estimate -->
|
<!-- Click contribution -->
|
||||||
<div class="gp-row" style="border-color: rgba(251,191,36,0.15); background: rgba(251,191,36,0.04);">
|
<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">
|
<div class="flex flex-col flex-1">
|
||||||
<span class="gp-value text-[0.7rem]!">Contribution clics</span>
|
<span class="gp-value text-[0.7rem]!">Contribution clics</span>
|
||||||
@@ -40,67 +42,80 @@
|
|||||||
<span class="gp-label gp-accent-amber">{clickShare.toFixed(0)}%</span>
|
<span class="gp-label gp-accent-amber">{clickShare.toFixed(0)}%</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Double ponte -->
|
<!-- Click upgrades shop -->
|
||||||
|
{#if (game.state.clickUpgrades ?? []).length > 0}
|
||||||
|
<span class="gp-zone-label mt-1">Ameliorations de ponte</span>
|
||||||
|
{#each game.state.clickUpgrades ?? [] as upgrade}
|
||||||
|
{@const gen = game.state.generators.find((g) => g.id === upgrade.generatorId)}
|
||||||
|
{@const hasGen = gen && gen.owned > 0}
|
||||||
|
{@const cost = clickUpgradeCost(upgrade)}
|
||||||
|
{@const canAfford = hasGen && game.state.resources >= cost}
|
||||||
|
<div class="gp-row {canAfford ? 'gp-row--active' : 'gp-row--locked'}">
|
||||||
|
<div class="flex flex-col min-w-0 flex-1">
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<span class="gp-value text-[0.7rem]!">{upgrade.name}</span>
|
||||||
|
{#if upgrade.level > 0}
|
||||||
|
<span
|
||||||
|
class="gp-label px-1.5 py-0 rounded-full text-[0.6rem]!"
|
||||||
|
style="background: rgba(251,191,36,0.15); color: var(--color-gp-accent-amber);"
|
||||||
|
>
|
||||||
|
nv.{upgrade.level}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<span class="gp-label">
|
||||||
|
{#if hasGen}
|
||||||
|
+{upgrade.baseClickPower}/clic par niveau ({GEN_NAMES[upgrade.generatorId]})
|
||||||
|
{:else}
|
||||||
|
Necessite un {GEN_NAMES[upgrade.generatorId]}
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{#if hasGen}
|
||||||
|
<button
|
||||||
|
onclick={() => game.buyClickUpgrade(upgrade.id)}
|
||||||
|
disabled={!canAfford}
|
||||||
|
class="gp-btn {canAfford ? 'gp-btn--buy' : 'gp-btn--disabled'}"
|
||||||
|
>
|
||||||
|
{formatNumber(cost)}
|
||||||
|
</button>
|
||||||
|
{:else}
|
||||||
|
<span class="gp-label">—</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- Double/Crit/Auto -->
|
||||||
|
<span class="gp-zone-label mt-1">Bonus (arbre)</span>
|
||||||
|
|
||||||
<div class="gp-row {b.doubleChance > 0 ? 'gp-row--unlocked' : 'gp-row--locked'}">
|
<div class="gp-row {b.doubleChance > 0 ? 'gp-row--unlocked' : 'gp-row--locked'}">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<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}
|
{b.doubleChance > 0 ? `${(b.doubleChance * 100).toFixed(0)}% chance de doubler` : 'Branche Ponte — 5 ADN'}
|
||||||
{(b.doubleChance * 100).toFixed(0)}% chance de doubler
|
|
||||||
{:else}
|
|
||||||
Branche Ponte — "Double Ponte" (5 ADN)
|
|
||||||
{/if}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{#if b.doubleChance > 0}
|
<span class="gp-label {b.doubleChance > 0 ? 'gp-accent-purple' : ''}">{b.doubleChance > 0 ? `${(b.doubleChance * 100).toFixed(0)}%` : '—'}</span>
|
||||||
<span class="gp-label gp-accent-purple">{(b.doubleChance * 100).toFixed(0)}%</span>
|
|
||||||
{:else}
|
|
||||||
<span class="gp-label">—</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Crit -->
|
|
||||||
<div class="gp-row {b.critChance > 0 ? 'gp-row--unlocked' : 'gp-row--locked'}">
|
<div class="gp-row {b.critChance > 0 ? 'gp-row--unlocked' : 'gp-row--locked'}">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<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}
|
{b.critChance > 0 ? `${(b.critChance * 100).toFixed(0)}% chance de x10` : 'Branche Ponte — 20 ADN'}
|
||||||
{(b.critChance * 100).toFixed(0)}% chance de x10
|
|
||||||
{:else}
|
|
||||||
Branche Ponte — "Ponte Critique" (20 ADN)
|
|
||||||
{/if}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{#if b.critChance > 0}
|
<span class="gp-label {b.critChance > 0 ? 'gp-accent-amber' : ''}">{b.critChance > 0 ? `${(b.critChance * 100).toFixed(0)}%` : '—'}</span>
|
||||||
<span class="gp-label gp-accent-amber">{(b.critChance * 100).toFixed(0)}%</span>
|
|
||||||
{:else}
|
|
||||||
<span class="gp-label">—</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Auto-click -->
|
|
||||||
<div class="gp-row {b.autoClicksPerSec > 0 ? 'gp-row--unlocked' : 'gp-row--locked'}">
|
<div class="gp-row {b.autoClicksPerSec > 0 ? 'gp-row--unlocked' : 'gp-row--locked'}">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<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}
|
{b.autoClicksPerSec > 0 ? `${b.autoClicksPerSec.toFixed(1)} clics/s → ${formatNumber(b.effectivePerSec)}/s` : 'Capstone Ponte — 200 ADN'}
|
||||||
{b.autoClicksPerSec.toFixed(1)} clics/s auto → {formatNumber(b.effectivePerSec)}/s
|
|
||||||
{:else}
|
|
||||||
Capstone Ponte — "Ponte Automatique" (200 ADN)
|
|
||||||
{/if}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{#if b.autoClicksPerSec > 0}
|
<span class="gp-label {b.autoClicksPerSec > 0 ? 'gp-accent-green' : ''}">{b.autoClicksPerSec > 0 ? `${formatNumber(b.effectivePerSec)}/s` : '—'}</span>
|
||||||
<span class="gp-label gp-accent-green">{formatNumber(b.effectivePerSec)}/s</span>
|
|
||||||
{:else}
|
|
||||||
<span class="gp-label">—</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Hint -->
|
|
||||||
{#if b.treeMult <= 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>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</CollapsiblePanel>
|
</CollapsiblePanel>
|
||||||
|
|||||||
@@ -86,11 +86,39 @@ export interface RunStats {
|
|||||||
} | null;
|
} | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Click Upgrades (achetables en têtards, liés aux générateurs) ---
|
||||||
|
|
||||||
|
export interface ClickUpgrade {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
generatorId: string; // lié à quel générateur
|
||||||
|
baseClickPower: number; // bonus clic par niveau
|
||||||
|
baseCost: number; // coût de base
|
||||||
|
level: number; // niveaux achetés
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_CLICK_UPGRADES: ClickUpgrade[] = [
|
||||||
|
{ id: "nid_douillet", name: "Nid Douillet", generatorId: "nid", baseClickPower: 1, baseCost: 50, level: 0 },
|
||||||
|
{ id: "eau_fertile", name: "Eau Fertile", generatorId: "mare", baseClickPower: 3, baseCost: 500, level: 0 },
|
||||||
|
{ id: "spores_actives", name: "Spores Actives", generatorId: "marecage", baseClickPower: 8, baseCost: 5_000, level: 0 },
|
||||||
|
{ id: "courant_vital", name: "Courant Vital", generatorId: "etang", baseClickPower: 20, baseCost: 50_000, level: 0 },
|
||||||
|
{ id: "source_ancestrale", name: "Source Ancestrale", generatorId: "lac", baseClickPower: 50, baseCost: 500_000, level: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function clickUpgradeCost(upgrade: ClickUpgrade): number {
|
||||||
|
return Math.floor(upgrade.baseCost * Math.pow(1.2, upgrade.level));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function totalClickUpgradePower(clickUpgrades: ClickUpgrade[]): number {
|
||||||
|
return clickUpgrades.reduce((sum, u) => sum + u.baseClickPower * u.level, 0);
|
||||||
|
}
|
||||||
|
|
||||||
export interface GameState {
|
export interface GameState {
|
||||||
saveVersion: number;
|
saveVersion: number;
|
||||||
resources: number;
|
resources: number;
|
||||||
clickMultiplier: number;
|
clickMultiplier: number;
|
||||||
generators: Generator[];
|
generators: Generator[];
|
||||||
|
clickUpgrades: ClickUpgrade[];
|
||||||
lastTick: number; // timestamp ms — lazy calc reference
|
lastTick: number; // timestamp ms — lazy calc reference
|
||||||
lastOnline: number; // timestamp ms — dernière activité réelle (tick actif)
|
lastOnline: number; // timestamp ms — dernière activité réelle (tick actif)
|
||||||
prestigeCount: number;
|
prestigeCount: number;
|
||||||
@@ -618,11 +646,32 @@ export function getGeneratorClickBonus(generators: Generator[]): number {
|
|||||||
return 1 + typesOwned * 2 + totalOwned * 0.05;
|
return 1 + typesOwned * 2 + totalOwned * 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gain par clic — scaling propre : base × prestige × arbre × generateurs
|
// Gain par clic — base + upgrades, le tout multiplié par prestige × arbre × infra
|
||||||
export function getClickGain(state: GameState): number {
|
export function getClickGain(state: GameState): number {
|
||||||
const treeClickMult = getClickMultiplierFromTree(state.evolutionTree);
|
const treeClickMult = getClickMultiplierFromTree(state.evolutionTree);
|
||||||
const genBonus = getGeneratorClickBonus(state.generators);
|
const genBonus = getGeneratorClickBonus(state.generators);
|
||||||
return Math.floor(state.clickMultiplier * state.prestigeMultiplier * treeClickMult * genBonus);
|
const upgradePower = totalClickUpgradePower(state.clickUpgrades ?? []);
|
||||||
|
const base = state.clickMultiplier + upgradePower;
|
||||||
|
return Math.floor(base * state.prestigeMultiplier * treeClickMult * genBonus);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Achat d'un click upgrade (coûte des têtards)
|
||||||
|
export function buyClickUpgrade(state: GameState, upgradeId: string): GameState | null {
|
||||||
|
const idx = (state.clickUpgrades ?? []).findIndex((u) => u.id === upgradeId);
|
||||||
|
if (idx === -1) return null;
|
||||||
|
|
||||||
|
const upgrade = state.clickUpgrades[idx];
|
||||||
|
// Requires owning the linked generator
|
||||||
|
const gen = state.generators.find((g) => g.id === upgrade.generatorId);
|
||||||
|
if (!gen || gen.owned === 0) return null;
|
||||||
|
|
||||||
|
const cost = clickUpgradeCost(upgrade);
|
||||||
|
if (state.resources < cost) return null;
|
||||||
|
|
||||||
|
const updatedUpgrades = [...state.clickUpgrades];
|
||||||
|
updatedUpgrades[idx] = { ...upgrade, level: upgrade.level + 1 };
|
||||||
|
|
||||||
|
return { ...state, resources: state.resources - cost, clickUpgrades: updatedUpgrades };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Breakdown complet du clic (pour affichage cockpit)
|
// Breakdown complet du clic (pour affichage cockpit)
|
||||||
@@ -641,7 +690,8 @@ export interface ClickBreakdown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getClickBreakdown(state: GameState): ClickBreakdown {
|
export function getClickBreakdown(state: GameState): ClickBreakdown {
|
||||||
const base = state.clickMultiplier;
|
const upgradePower = totalClickUpgradePower(state.clickUpgrades ?? []);
|
||||||
|
const base = state.clickMultiplier + upgradePower;
|
||||||
const prestigeMult = state.prestigeMultiplier;
|
const prestigeMult = state.prestigeMultiplier;
|
||||||
const treeMult = getClickMultiplierFromTree(state.evolutionTree);
|
const treeMult = getClickMultiplierFromTree(state.evolutionTree);
|
||||||
const genBonus = getGeneratorClickBonus(state.generators);
|
const genBonus = getGeneratorClickBonus(state.generators);
|
||||||
@@ -817,6 +867,8 @@ export function applyPrestige(state: GameState): GameState {
|
|||||||
},
|
},
|
||||||
freeResetAvailable: true, // 1 reset gratuit offert par prestige
|
freeResetAvailable: true, // 1 reset gratuit offert par prestige
|
||||||
extraResetsUsed: 0,
|
extraResetsUsed: 0,
|
||||||
|
// Click upgrades reset au prestige (comme les générateurs)
|
||||||
|
clickUpgrades: (state.clickUpgrades ?? DEFAULT_CLICK_UPGRADES).map((u) => ({ ...u, level: 0 })),
|
||||||
// evolutionTree persiste — jamais reset
|
// evolutionTree persiste — jamais reset
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -835,6 +887,7 @@ export const DEFAULT_STATE: GameState = {
|
|||||||
resources: 0,
|
resources: 0,
|
||||||
clickMultiplier: 1,
|
clickMultiplier: 1,
|
||||||
generators: DEFAULT_GENERATORS,
|
generators: DEFAULT_GENERATORS,
|
||||||
|
clickUpgrades: DEFAULT_CLICK_UPGRADES,
|
||||||
lastTick: Date.now(),
|
lastTick: Date.now(),
|
||||||
lastOnline: Date.now(),
|
lastOnline: Date.now(),
|
||||||
prestigeCount: 0,
|
prestigeCount: 0,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
// Chaque sprint ajoute un step (v2→v3, etc.)
|
// Chaque sprint ajoute un step (v2→v3, etc.)
|
||||||
|
|
||||||
import { CURRENT_SAVE_VERSION } from "./balance";
|
import { CURRENT_SAVE_VERSION } from "./balance";
|
||||||
import type { GameState } from "./economy";
|
import type { GameState, ClickUpgrade } from "./economy";
|
||||||
import { DEFAULT_EVOLUTION_TREE, DEFAULT_GENERATORS } from "./economy";
|
import { DEFAULT_EVOLUTION_TREE, DEFAULT_GENERATORS, DEFAULT_CLICK_UPGRADES } from "./economy";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Détecte la version d'une save et applique les migrations nécessaires.
|
* Détecte la version d'une save et applique les migrations nécessaires.
|
||||||
@@ -32,6 +32,11 @@ export function migrateSave(raw: Record<string, unknown>): GameState {
|
|||||||
state.generators as Array<Record<string, unknown>> | undefined
|
state.generators as Array<Record<string, unknown>> | undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Click upgrades — merge with defaults (preserves levels, adds new upgrades)
|
||||||
|
state.clickUpgrades = mergeClickUpgrades(
|
||||||
|
state.clickUpgrades as Array<Record<string, unknown>> | undefined
|
||||||
|
);
|
||||||
|
|
||||||
return state as unknown as GameState;
|
return state as unknown as GameState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,3 +154,25 @@ function mergeGenerators(
|
|||||||
return { ...defaultGen };
|
return { ...defaultGen };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge les click upgrades sauvegardés avec DEFAULT_CLICK_UPGRADES.
|
||||||
|
* Conserve le level, met à jour les stats de base.
|
||||||
|
*/
|
||||||
|
function mergeClickUpgrades(
|
||||||
|
saved: Array<Record<string, unknown>> | undefined
|
||||||
|
): ClickUpgrade[] {
|
||||||
|
if (!saved || !Array.isArray(saved)) {
|
||||||
|
return DEFAULT_CLICK_UPGRADES.map((u) => ({ ...u }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const savedById = new Map(saved.map((u) => [u.id as string, u]));
|
||||||
|
|
||||||
|
return DEFAULT_CLICK_UPGRADES.map((def) => {
|
||||||
|
const s = savedById.get(def.id);
|
||||||
|
if (s) {
|
||||||
|
return { ...def, level: typeof s.level === "number" ? s.level : 0 };
|
||||||
|
}
|
||||||
|
return { ...def };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
totalProductionPerSecond,
|
totalProductionPerSecond,
|
||||||
generatorCost as genCost,
|
generatorCost as genCost,
|
||||||
computeOfflineGains,
|
computeOfflineGains,
|
||||||
|
buyClickUpgrade as buyClickUpgradeFn,
|
||||||
} from '$lib/core/economy';
|
} from '$lib/core/economy';
|
||||||
import { migrateSave } from '$lib/core/migrateSave';
|
import { migrateSave } from '$lib/core/migrateSave';
|
||||||
import { toast } from './toast.svelte';
|
import { toast } from './toast.svelte';
|
||||||
@@ -133,6 +134,12 @@ class Game {
|
|||||||
if (updated) this.applyState(updated);
|
if (updated) this.applyState(updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buyClickUpgrade(upgradeId: string) {
|
||||||
|
if (!this.ready) return;
|
||||||
|
const updated = buyClickUpgradeFn(this.state, upgradeId);
|
||||||
|
if (updated) this.applyState(updated);
|
||||||
|
}
|
||||||
|
|
||||||
buyNode(nodeId: string) {
|
buyNode(nodeId: string) {
|
||||||
if (!this.ready) return;
|
if (!this.ready) return;
|
||||||
const updated = buyEvolutionNode(this.state, nodeId);
|
const updated = buyEvolutionNode(this.state, nodeId);
|
||||||
|
|||||||
Reference in New Issue
Block a user