diff --git a/src/App.tsx b/src/App.tsx index 6d0a114..95de417 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,5 @@ import { ResourceDisplay } from './components/ResourceDisplay' import { BuildingButton } from './components/BuildingButton' -import { MultiplierShop } from './components/MultiplierShop' import { NextBuildingPreview } from './components/NextBuildingPreview' import { ResetButton } from './components/ResetButton' import { useGameStore } from './store/gameStore' @@ -35,79 +34,6 @@ type BuildingId = 'mouseFarms' | 'keyboardFactories' | 'monitorDisplays' | 'offi type BuildingLevelKey = `${BuildingId}Level` -const BUILDING_INFO = { - mouseFarms: { - title: 'Mouse Farm', - description: 'A basic facility that produces computer mice. Each mouse farm generates points automatically.', - production: { points: 0.1 } - }, - keyboardFactories: { - title: 'Keyboard Factory', - description: 'Manufactures mechanical keyboards and generates tech parts. Essential for advanced upgrades.', - production: { techParts: 0.05 } - }, - monitorDisplays: { - title: 'Monitor Display', - description: 'High-resolution displays that generate both points and tech parts. A balanced production facility.', - production: { points: 0.2, techParts: 0.1 } - }, - serverRooms: { - title: 'Server Room', - description: 'A powerful facility that generates significant amounts of both resources. Requires proper cooling.', - production: { points: 1, techParts: 0.5 } - }, - dataCenters: { - title: 'Data Center', - description: 'The ultimate production facility. Generates massive amounts of resources but requires significant investment.', - production: { points: 5, techParts: 2 } - }, - dataCities: { - title: 'Data City', - description: 'A massive network of data centers spanning an entire city. Requires level 5 to unlock.', - production: { points: 25, techParts: 10 } - }, - dataCountries: { - title: 'Data Country', - description: 'A country-wide network of data cities. Requires level 10 to unlock.', - production: { points: 100, techParts: 40 } - }, - dataContinents: { - title: 'Data Continent', - description: 'A continent-spanning network of data countries. Requires level 20 to unlock.', - production: { points: 500, techParts: 200 } - }, - dataWorlds: { - title: 'Data World', - description: 'A world-wide network of data continents. Requires level 30 to unlock.', - production: { points: 2500, techParts: 1000 } - }, - dataMoons: { - title: 'Data Moon', - description: 'A moon-sized data processing facility. Requires level 40 to unlock.', - production: { points: 10000, techParts: 4000 } - }, - dataSolarSystems: { - title: 'Data Solar System', - description: 'A solar system-wide network of data moons. Requires level 50 to unlock.', - production: { points: 50000, techParts: 20000 } - }, - dataGalaxies: { - title: 'Data Galaxy', - description: 'A galaxy-spanning network of data solar systems. Requires level 60 to unlock.', - production: { points: 250000, techParts: 100000 } - }, - dataUniverses: { - title: 'Data Universe', - description: 'A universe-wide network of data galaxies. Requires level 70 to unlock.', - production: { points: 1000000, techParts: 400000 } - }, - dataGods: { - title: 'Data God', - description: 'The ultimate data processing entity. Requires level 80 to unlock.', - production: { points: 5000000, techParts: 2000000 } - } -} - function App() { const { points, @@ -184,7 +110,7 @@ function App() { onClick={() => useGameStore.getState().buyBuilding(building.id as BuildingId)} description={building.description} production={building.production} - buildingType={building.id} + buildingType={building.id!} levelRequirement={building.levelRequirement} /> ))} @@ -226,8 +152,6 @@ function App() { - - diff --git a/src/components/ResourceDisplay.tsx b/src/components/ResourceDisplay.tsx index c63be5a..dcbfdea 100644 --- a/src/components/ResourceDisplay.tsx +++ b/src/components/ResourceDisplay.tsx @@ -4,10 +4,7 @@ import logoImg from '../assets/logo.png' import { ResetButton } from './ResetButton' export function ResourceDisplay() { - const { points, pointsPerSecond, clickPower, getTotalMultiplier, activeMultipliers, playerLevel } = useGameStore() - - const totalMultiplier = getTotalMultiplier() - const actualClickPower = clickPower * totalMultiplier + const { points, pointsPerSecond, clickPower, playerLevel } = useGameStore() // Calculate progress to next level const currentLevelPPS = Math.pow(10, playerLevel - 1) @@ -91,10 +88,7 @@ export function ResourceDisplay() { {/* Click Power */} Click Power - {actualClickPower} - {activeMultipliers.length > 0 && ( - {totalMultiplier}x Active - )} + {clickPower} diff --git a/src/store/gameStore.ts b/src/store/gameStore.ts index 93b1a0c..bd02430 100644 --- a/src/store/gameStore.ts +++ b/src/store/gameStore.ts @@ -1,8 +1,9 @@ import { create } from 'zustand' import { persist } from 'zustand/middleware' -interface BuildingInfo { - id: string +// Building information interface +export interface BuildingInfo { + id?: string cost: number levelRequirement: number title: string @@ -58,12 +59,6 @@ interface GameState { // Production rates pointsPerSecond: number - // Special purchases - activeMultipliers: Array<{ - multiplier: number - endTime: number - }> - // Player level playerLevel: number @@ -73,14 +68,112 @@ interface GameState { buyUpgrade: (upgradeType: UpgradeType) => void resetGame: () => void tick: () => void - buyMultiplier: (duration: number, multiplier: number) => void upgradeBuilding: (buildingType: BuildingType) => void // New getter for available buildings getAvailableBuildings: () => BuildingInfo[] - - // Add getter for total multiplier - getTotalMultiplier: () => number +} + +// Building information with costs and requirements +export const BUILDING_INFO: Record> = { + mouseFarms: { + title: 'Mouse Farm', + description: 'A basic facility that produces computer mice. Each mouse farm generates points automatically.', + production: { points: 0.1 }, + cost: 10, + levelRequirement: 1 + }, + keyboardFactories: { + title: 'Keyboard Factory', + description: 'Manufactures mechanical keyboards and generates tech parts. Essential for advanced upgrades.', + production: { points: 0.2 }, + cost: 50, + levelRequirement: 1 + }, + monitorDisplays: { + title: 'Monitor Display', + description: 'High-resolution displays that generate both points and tech parts. A balanced production facility.', + production: { points: 0.2 }, + cost: 100, + levelRequirement: 1 + }, + serverRooms: { + title: 'Server Room', + description: 'A powerful facility that generates significant amounts of both resources. Requires proper cooling.', + production: { points: 5 }, + cost: 1000, + levelRequirement: 1 + }, + dataCenters: { + title: 'Data Center', + description: 'The ultimate production facility. Generates massive amounts of resources but requires significant investment.', + production: { points: 25 }, + cost: 5000, + levelRequirement: 5 + }, + dataCities: { + title: 'Data City', + description: 'A massive network of data centers spanning an entire city. Requires level 10 to unlock.', + production: { points: 100 }, + cost: 25000, + levelRequirement: 10 + }, + dataCountries: { + title: 'Data Country', + description: 'A country-wide network of data cities. Requires level 20 to unlock.', + production: { points: 500 }, + cost: 100000, + levelRequirement: 20 + }, + dataContinents: { + title: 'Data Continent', + description: 'A continent-spanning network of data countries. Requires level 30 to unlock.', + production: { points: 2500 }, + cost: 500000, + levelRequirement: 30 + }, + dataWorlds: { + title: 'Data World', + description: 'A world-wide network of data continents. Requires level 40 to unlock.', + production: { points: 10000 }, + cost: 2000000, + levelRequirement: 40 + }, + dataMoons: { + title: 'Data Moon', + description: 'A moon-sized data processing facility. Requires level 50 to unlock.', + production: { points: 50000 }, + cost: 10000000, + levelRequirement: 50 + }, + dataSolarSystems: { + title: 'Data Solar System', + description: 'A solar system-wide network of data moons. Requires level 60 to unlock.', + production: { points: 250000 }, + cost: 50000000, + levelRequirement: 60 + }, + dataGalaxies: { + title: 'Data Galaxy', + description: 'A galaxy-spanning network of data solar systems. Requires level 70 to unlock.', + production: { points: 1000000 }, + cost: 200000000, + levelRequirement: 70 + }, + dataUniverses: { + title: 'Data Universe', + description: 'A universe-wide network of data galaxies. Requires level 80 to unlock.', + production: { points: 5000000 }, + cost: 1000000000, + levelRequirement: 80 + }, + dataGods: { + title: 'Data God', + description: 'The ultimate data processing entity. Requires level 90 to unlock.', + production: { points: 25000000 }, + cost: 5000000000, + levelRequirement: 90 + } } const initialState = { @@ -118,7 +211,6 @@ const initialState = { autoClickers: 0, clickPower: 1, pointsPerSecond: 0, - activeMultipliers: [], playerLevel: 1, } @@ -179,34 +271,12 @@ const BUILDING_LEVEL_REQUIREMENTS = { dataGods: 90, } -// Special multiplier purchases -const MULTIPLIER_PURCHASES = [ - { duration: 30, multiplier: 2, cost: 100, name: '30s 2x Click Power' }, - { duration: 60, multiplier: 2, cost: 150, name: '1m 2x Click Power' }, - { duration: 30, multiplier: 3, cost: 250, name: '30s 3x Click Power' }, - { duration: 60, multiplier: 3, cost: 350, name: '1m 3x Click Power' }, - { duration: 30, multiplier: 5, cost: 500, name: '30s 5x Click Power' }, - { duration: 60, multiplier: 5, cost: 750, name: '1m 5x Click Power' }, -] - // Calculate upgrade cost based on current level const calculateUpgradeCost = (buildingType: BuildingType, currentLevel: number): number => { const baseCost = BUILDING_COSTS[buildingType] return Math.floor(baseCost * Math.pow(1.5, currentLevel - 1)) } -// Building costs and level requirements -export interface BuildingInfo { - cost: number - levelRequirement: number - title: string - description: string - production: { - points: number - } - id?: string -} - type BuildingType = keyof typeof BUILDING_COSTS type UpgradeType = 'autoClickers' | 'clickPower' @@ -227,9 +297,8 @@ export const useGameStore = create()( ...initialState, click: () => { - const { clickPower, autoClickers, getTotalMultiplier } = get() - const totalMultiplier = getTotalMultiplier() - const pointsPerClick = clickPower * (1 + autoClickers * 0.1) * totalMultiplier + const { clickPower, autoClickers } = get() + const pointsPerClick = clickPower * (1 + autoClickers * 0.1) set((state) => ({ points: state.points + pointsPerClick, })) @@ -253,217 +322,71 @@ export const useGameStore = create()( } }, + buyUpgrade: (upgradeType: UpgradeType) => { + const state = get() + + // Handle upgrade purchase + if (upgradeType === 'clickPower' && state.points >= 20) { + set((state) => ({ + points: state.points - 20, + clickPower: state.clickPower + 1 + })) + } + }, + upgradeBuilding: (buildingType: BuildingType) => { const state = get() const currentLevel = state[`${buildingType}Level` as keyof GameState] as number - const upgradeCost = calculateUpgradeCost(buildingType, currentLevel) + const cost = calculateUpgradeCost(buildingType, currentLevel) - if (state.points >= upgradeCost) { + if (state.points >= cost && state[buildingType] > 0) { set((state) => { + const newLevel = (state[`${buildingType}Level` as keyof GameState] as number) + 1 const rates = PRODUCTION_RATES[buildingType] const count = state[buildingType] - const newLevel = currentLevel + 1 + + // Calculate the new points per second + const oldProduction = rates.points * (newLevel - 1) * count + const newProduction = rates.points * newLevel * count + const productionDifference = newProduction - oldProduction return { - points: state.points - upgradeCost, + points: state.points - cost, [`${buildingType}Level`]: newLevel, - pointsPerSecond: state.pointsPerSecond + rates.points * count, + pointsPerSecond: state.pointsPerSecond + productionDifference, } }) } }, - - buyUpgrade: (upgradeType: UpgradeType) => { - const state = get() - const upgradeCosts: Record = { - autoClickers: 50, - clickPower: 20, - } - - const cost = upgradeCosts[upgradeType] - if (state.points >= cost) { - set((state) => ({ - points: state.points - cost, - [upgradeType]: state[upgradeType] + 1, - })) - } - }, - - buyMultiplier: (duration: number, multiplier: number) => { - const state = get() - const purchase = MULTIPLIER_PURCHASES.find( - p => p.duration === duration && p.multiplier === multiplier - ) - - if (purchase && state.points >= purchase.cost) { - const now = Date.now() - set((state) => ({ - points: state.points - purchase.cost, - activeMultipliers: [ - ...state.activeMultipliers, - { - multiplier, - endTime: now + duration * 1000 - } - ] - })) - } - }, - - tick: () => { - const state = get() - const now = Date.now() - - // Check for expired multipliers - const activeMultipliers = state.activeMultipliers.filter(m => m.endTime > now) - if (activeMultipliers.length !== state.activeMultipliers.length) { - set({ activeMultipliers }) - } - - // Update player level based on points per second - const newLevel = Math.floor(Math.log10(state.pointsPerSecond + 1)) + 1 - if (newLevel !== state.playerLevel) { - set({ playerLevel: newLevel }) - } - - // Calculate resources gained in this tick (1/10th of a second) - const pointsGained = state.pointsPerSecond / 10 - - set({ - points: state.points + pointsGained, - }) - }, - + resetGame: () => { set(initialState) }, - // Add new getter for available buildings - getAvailableBuildings: () => { + tick: () => { const state = get() - return getAvailableBuildings(state.playerLevel) + + // Add production from buildings + if (state.pointsPerSecond > 0) { + set((state) => ({ + points: state.points + state.pointsPerSecond / 10, // 10 ticks per second + })) + } + + // Update player level based on points per second + const playerLevel = Math.max(1, Math.floor(Math.log10(state.pointsPerSecond) + 1)) + if (playerLevel !== state.playerLevel) { + set({ playerLevel }) + } }, - // Add getter for total multiplier - getTotalMultiplier: () => { - const state = get() - const now = Date.now() - return state.activeMultipliers - .filter(m => m.endTime > now) - .reduce((total, m) => total + (m.multiplier - 1), 1) // Subtract 1 from each multiplier and add 1 at the end + getAvailableBuildings: () => { + const { playerLevel } = get() + return getAvailableBuildings(playerLevel) }, }), { - name: 'game-storage', + name: 'clicker-game', } ) -) - -// Building costs and level requirements -export const BUILDING_INFO: Record> = { - mouseFarms: { - cost: 10, - levelRequirement: 1, - title: 'Mouse Farm', - description: 'A basic facility that produces computer mice. Each mouse farm generates points automatically.', - production: { points: 0.1 } - }, - keyboardFactories: { - cost: 50, - levelRequirement: 1, - title: 'Keyboard Factory', - description: 'Manufactures mechanical keyboards. Generates points automatically.', - production: { points: 0.2 } - }, - monitorDisplays: { - cost: 100, - levelRequirement: 1, - title: 'Monitor Display', - description: 'High-resolution displays that generate points. A balanced production facility.', - production: { points: 0.2 } - }, - officeSpace: { - cost: 500, - levelRequirement: 1, - title: 'Office Space', - description: 'A productive workspace filled with computers. Generates a significant amount of points.', - production: { points: 1 } - }, - serverRooms: { - cost: 1000, - levelRequirement: 1, - title: 'Server Room', - description: 'A powerful facility that generates substantial amounts of points. Requires proper cooling.', - production: { points: 5 } - }, - dataCenters: { - cost: 5000, - levelRequirement: 5, - title: 'Data Center', - description: 'The ultimate production facility. Generates massive amounts of points but requires significant investment.', - production: { points: 25 } - }, - dataCities: { - cost: 25000, - levelRequirement: 10, - title: 'Data City', - description: 'A massive network of data centers spanning an entire city. Requires level 10 to unlock.', - production: { points: 100 } - }, - dataCountries: { - cost: 100000, - levelRequirement: 20, - title: 'Data Country', - description: 'A country-wide network of data cities. Requires level 20 to unlock.', - production: { points: 500 } - }, - dataContinents: { - cost: 500000, - levelRequirement: 30, - title: 'Data Continent', - description: 'A continent-spanning network of data countries. Requires level 30 to unlock.', - production: { points: 2500 } - }, - dataWorlds: { - cost: 2000000, - levelRequirement: 40, - title: 'Data World', - description: 'A world-wide network of data continents. Requires level 40 to unlock.', - production: { points: 10000 } - }, - dataMoons: { - cost: 10000000, - levelRequirement: 50, - title: 'Data Moon', - description: 'A moon-sized data processing facility. Requires level 50 to unlock.', - production: { points: 50000 } - }, - dataSolarSystems: { - cost: 50000000, - levelRequirement: 60, - title: 'Data Solar System', - description: 'A solar system-wide network of data moons. Requires level 60 to unlock.', - production: { points: 250000 } - }, - dataGalaxies: { - cost: 200000000, - levelRequirement: 70, - title: 'Data Galaxy', - description: 'A galaxy-spanning network of data solar systems. Requires level 70 to unlock.', - production: { points: 1000000 } - }, - dataUniverses: { - cost: 1000000000, - levelRequirement: 80, - title: 'Data Universe', - description: 'A universe-wide network of data galaxies. Requires level 80 to unlock.', - production: { points: 5000000 } - }, - dataGods: { - cost: 5000000000, - levelRequirement: 90, - title: 'Data God', - description: 'The ultimate data processing entity. Requires level 90 to unlock.', - production: { points: 25000000 } - } -} \ No newline at end of file +) \ No newline at end of file