Add a console.

This commit is contained in:
Ryan Lanny Jenkins 2025-05-18 23:15:05 -05:00
parent 8035aa92d4
commit 9644cc4b4a
4 changed files with 83 additions and 1 deletions

View file

@ -11,6 +11,7 @@ import Warehouse from './components/Warehouse'
import Market from './components/Market'
import { ActionCooldown } from './components/ActionCooldown'
import { useSaveSystem } from './store/useSaveSystem'
import { Console } from './components/Console'
const appContainerStyle: React.CSSProperties = {
maxWidth: '1200px',
@ -51,6 +52,7 @@ function App() {
<Market />
</TabsContent>
</Tabs>
<Console />
</div>
</div>
)

View file

@ -0,0 +1,43 @@
import React from 'react'
import { useGameStore } from '../store/useGameStore'
const consoleContainerStyle: React.CSSProperties = {
marginTop: '2rem',
padding: '1rem',
backgroundColor: '#1a1a1a',
borderRadius: '0.5rem',
maxHeight: '200px',
overflowY: 'auto',
}
const messageStyle: React.CSSProperties = {
color: '#e0e0e0',
fontSize: '0.9rem',
marginBottom: '0.5rem',
fontFamily: 'monospace',
}
const timestampStyle: React.CSSProperties = {
color: '#666',
marginRight: '0.5rem',
}
export const Console: React.FC = () => {
const messages = useGameStore((state) => state.consoleMessages)
return (
<div style={consoleContainerStyle}>
{messages.map((message) => (
<div key={message.id} style={messageStyle}>
<span style={timestampStyle}>
{new Date(message.timestamp).toLocaleTimeString()}
</span>
{message.text}
</div>
))}
{messages.length === 0 && (
<div style={messageStyle}>No messages yet...</div>
)}
</div>
)
}

View file

@ -10,7 +10,7 @@ import {
COOLDOWN_DURATION,
MARKET_ITEMS,
} from '../constants'
import { GameState, PlotState, FieldTool } from '../types'
import { GameState, PlotState } from '../types'
const initializeField = (size: number): PlotState[][] => {
return Array(size)
@ -53,6 +53,18 @@ export const hasSaveInSlot = (slot: number): boolean => {
return !!localStorage.getItem(`${SAVE_SLOT_PREFIX}${slot}`)
}
const addConsoleMessage = (state: GameState, text: string) => (
state.consoleMessages = [
{
id: Math.random().toString(36).substring(7),
text,
timestamp: Date.now(),
},
...state.consoleMessages,
].slice(0, 50)
)
export const useGameStore = create<
GameState & {
plant: (row: number, col: number) => void
@ -78,6 +90,7 @@ export const useGameStore = create<
gameSpeed: INITIAL_GAME_SPEED,
actionCooldown: 0,
tickCount: 0,
consoleMessages: [],
assignCrop: (row, col, cropId) => {
set(
@ -182,6 +195,14 @@ export const useGameStore = create<
const crop = CROPS[plot.current.cropId]
const waterNeeded = crop.waterPerTick
// Check if water is running low (less than 25% of what's needed)
if (plot.moisture < waterNeeded * 0.25 && plot.moisture > 0) {
addConsoleMessage(
state,
`Plot (${rowIndex + 1},${colIndex + 1}) ${crop.name} is running low on water!`,
)
}
// Only grow if fertility is above 0.2
if (plot.moisture >= waterNeeded && plot.fertility >= 0.2) {
let growthRate = 1
@ -196,6 +217,15 @@ export const useGameStore = create<
state.plots[rowIndex][colIndex].moisture =
plot.moisture - waterNeeded
state.plots[rowIndex][colIndex].current.progress = newProgress
// If the plot just became mature, add a message
if (mature && !plot.current.mature) {
addConsoleMessage(
state,
`Plot (${rowIndex + 1},${colIndex + 1}) ${crop.name} is ready to harvest!`,
)
}
state.plots[rowIndex][colIndex].current.mature = mature
}
})

View file

@ -30,6 +30,12 @@ export interface InventoryItem {
export type FieldTool = 'mark' | 'plant' | 'water' | 'harvest' | 'inspect'
export interface ConsoleMessage {
id: string
text: string
timestamp: number
}
export interface GameState {
cash: number
inventory: Record<string, number>
@ -39,6 +45,7 @@ export interface GameState {
plots: PlotState[][]
gameSpeed: number
actionCooldown: number
consoleMessages: ConsoleMessage[]
}
export interface MarketTransaction {