Add the basis of the fertility system.
This commit is contained in:
parent
9a9ec999ff
commit
b38cc9762e
|
|
@ -164,10 +164,20 @@ const FieldComponent: React.FC = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBgColor = (hasCrop: boolean, isMature: boolean) => {
|
const getBgColor = (
|
||||||
|
hasCrop: boolean,
|
||||||
|
isMature: boolean,
|
||||||
|
fertility: number,
|
||||||
|
) => {
|
||||||
if (isMature) return '#22c55e'
|
if (isMature) return '#22c55e'
|
||||||
if (hasCrop) return '#86efac'
|
if (hasCrop) return '#86efac'
|
||||||
return '#92400e'
|
|
||||||
|
// For empty plots, show fertility level through color
|
||||||
|
// Convert fertility (0-1) to a color between light grey-brown and dark brown
|
||||||
|
const r = Math.floor(146 + (73 - 146) * fertility) // 146 to 73
|
||||||
|
const g = Math.floor(131 + (47 - 131) * fertility) // 131 to 47
|
||||||
|
const b = Math.floor(120 + (23 - 120) * fertility) // 120 to 23
|
||||||
|
return `rgb(${r}, ${g}, ${b})`
|
||||||
}
|
}
|
||||||
|
|
||||||
const availableSpeeds = [1, 2, 4, 8, 16, 32, 64]
|
const availableSpeeds = [1, 2, 4, 8, 16, 32, 64]
|
||||||
|
|
@ -233,7 +243,7 @@ const FieldComponent: React.FC = () => {
|
||||||
row.slice(0, fieldSize).map((plot, colIndex) => {
|
row.slice(0, fieldSize).map((plot, colIndex) => {
|
||||||
const hasCrop = !!plot.current
|
const hasCrop = !!plot.current
|
||||||
const isMature = !!plot.current?.mature
|
const isMature = !!plot.current?.mature
|
||||||
const bgColor = getBgColor(hasCrop, isMature)
|
const bgColor = getBgColor(hasCrop, isMature, plot.fertility)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import React, { useEffect, useState, useImperativeHandle, forwardRef } from 'react'
|
import React, {
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
useImperativeHandle,
|
||||||
|
forwardRef,
|
||||||
|
} from 'react'
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
id: string
|
id: string
|
||||||
|
|
@ -20,12 +25,12 @@ const FloatingMessages = forwardRef<FloatingMessagesHandle>((_, ref) => {
|
||||||
text,
|
text,
|
||||||
position,
|
position,
|
||||||
}
|
}
|
||||||
setMessages(prev => [...prev, newMessage])
|
setMessages((prev) => [...prev, newMessage])
|
||||||
}
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const handleAnimationEnd = (messageId: string) => {
|
const handleAnimationEnd = (messageId: string) => {
|
||||||
setMessages(prev => prev.filter(msg => msg.id !== messageId))
|
setMessages((prev) => prev.filter((msg) => msg.id !== messageId))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -52,7 +57,7 @@ const FloatingMessages = forwardRef<FloatingMessagesHandle>((_, ref) => {
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
{messages.map(message => (
|
{messages.map((message) => (
|
||||||
<div
|
<div
|
||||||
key={message.id}
|
key={message.id}
|
||||||
className="floating-message"
|
className="floating-message"
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ const MarketComponent: React.FC = () => {
|
||||||
|
|
||||||
floatingMessagesRef.current?.addMessage(
|
floatingMessagesRef.current?.addMessage(
|
||||||
`+1 ${item.emoji} ${item.name}`,
|
`+1 ${item.emoji} ${item.name}`,
|
||||||
position
|
position,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +107,7 @@ const MarketComponent: React.FC = () => {
|
||||||
|
|
||||||
floatingMessagesRef.current?.addMessage(
|
floatingMessagesRef.current?.addMessage(
|
||||||
`-1 ${item.emoji} ${item.name}`,
|
`-1 ${item.emoji} ${item.name}`,
|
||||||
position
|
position,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ export const CROPS: CropDefinitions = {
|
||||||
waterPerTick: 1 / 20,
|
waterPerTick: 1 / 20,
|
||||||
yield: 1,
|
yield: 1,
|
||||||
yieldType: 'celery',
|
yieldType: 'celery',
|
||||||
|
fertilityDepletion: 0.1,
|
||||||
},
|
},
|
||||||
corn: {
|
corn: {
|
||||||
id: 'corn',
|
id: 'corn',
|
||||||
|
|
@ -29,6 +30,7 @@ export const CROPS: CropDefinitions = {
|
||||||
waterPerTick: 1 / 40,
|
waterPerTick: 1 / 40,
|
||||||
yield: 5,
|
yield: 5,
|
||||||
yieldType: 'corn',
|
yieldType: 'corn',
|
||||||
|
fertilityDepletion: 0.3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const initializeField = (size: number): PlotState[][] => {
|
||||||
.fill(0)
|
.fill(0)
|
||||||
.map(() => ({
|
.map(() => ({
|
||||||
moisture: 0,
|
moisture: 0,
|
||||||
|
fertility: 1,
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -175,6 +176,10 @@ export const useGameStore = create<
|
||||||
state.plots[row][col].current = undefined
|
state.plots[row][col].current = undefined
|
||||||
state.inventory[yieldItem] =
|
state.inventory[yieldItem] =
|
||||||
(state.inventory[yieldItem] || 0) + yieldAmount
|
(state.inventory[yieldItem] || 0) + yieldAmount
|
||||||
|
state.plots[row][col].fertility = Math.max(
|
||||||
|
0,
|
||||||
|
state.plots[row][col].fertility - crop.fertilityDepletion,
|
||||||
|
)
|
||||||
state.actionCooldown = COOLDOWN_DURATION
|
state.actionCooldown = COOLDOWN_DURATION
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
@ -190,6 +195,14 @@ export const useGameStore = create<
|
||||||
// Update plots
|
// Update plots
|
||||||
state.plots.forEach((row: PlotState[], rowIndex: number) => {
|
state.plots.forEach((row: PlotState[], rowIndex: number) => {
|
||||||
row.forEach((plot: PlotState, colIndex: number) => {
|
row.forEach((plot: PlotState, colIndex: number) => {
|
||||||
|
// Regenerate fertility every 100 ticks
|
||||||
|
if (state.tickCount % 100 === 0 && plot.fertility < 1) {
|
||||||
|
state.plots[rowIndex][colIndex].fertility = Math.min(
|
||||||
|
1,
|
||||||
|
plot.fertility + 0.1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (!plot.current || plot.current.mature) {
|
if (!plot.current || plot.current.mature) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -197,8 +210,15 @@ export const useGameStore = create<
|
||||||
const crop = CROPS[plot.current.cropId]
|
const crop = CROPS[plot.current.cropId]
|
||||||
const waterNeeded = crop.waterPerTick
|
const waterNeeded = crop.waterPerTick
|
||||||
|
|
||||||
if (plot.moisture >= waterNeeded) {
|
// Only grow if fertility is above 0.2
|
||||||
const newProgress = plot.current.progress + 1
|
if (plot.moisture >= waterNeeded && plot.fertility >= 0.2) {
|
||||||
|
let growthRate = 1
|
||||||
|
// Half growth rate if fertility is between 0.2 and 0.5
|
||||||
|
if (plot.fertility < 0.5) {
|
||||||
|
growthRate = 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
const newProgress = plot.current.progress + growthRate
|
||||||
const mature = newProgress >= crop.growthTicks
|
const mature = newProgress >= crop.growthTicks
|
||||||
|
|
||||||
state.plots[rowIndex][colIndex].moisture =
|
state.plots[rowIndex][colIndex].moisture =
|
||||||
|
|
@ -257,7 +277,7 @@ export const useGameStore = create<
|
||||||
const { cash } = get()
|
const { cash } = get()
|
||||||
const item = MARKET_ITEMS[itemId]
|
const item = MARKET_ITEMS[itemId]
|
||||||
|
|
||||||
if (!item || item.buyPrice === null) {
|
if (!item || item.buyPrice === null || item.buyPrice === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,7 +287,7 @@ export const useGameStore = create<
|
||||||
|
|
||||||
set(
|
set(
|
||||||
produce((state) => {
|
produce((state) => {
|
||||||
state.cash -= item.buyPrice
|
state.cash -= item.buyPrice!
|
||||||
state.inventory[itemId] = (state.inventory[itemId] || 0) + 1
|
state.inventory[itemId] = (state.inventory[itemId] || 0) + 1
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from "react"
|
import { useEffect } from 'react'
|
||||||
import { hasSaveInSlot, useGameStore } from "./useGameStore"
|
import { hasSaveInSlot, useGameStore } from './useGameStore'
|
||||||
|
|
||||||
export const useSaveSystem = () => {
|
export const useSaveSystem = () => {
|
||||||
const { saveToSlot, loadFromSlot } = useGameStore()
|
const { saveToSlot, loadFromSlot } = useGameStore()
|
||||||
|
|
@ -31,7 +31,6 @@ export const useSaveSystem = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.addEventListener('keydown', handleKeyDown)
|
window.addEventListener('keydown', handleKeyDown)
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
saveToSlot(0)
|
saveToSlot(0)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ export interface Crop {
|
||||||
waterPerTick: number
|
waterPerTick: number
|
||||||
yield: number
|
yield: number
|
||||||
yieldType: string
|
yieldType: string
|
||||||
|
fertilityDepletion: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CropDefinitions {
|
export interface CropDefinitions {
|
||||||
|
|
@ -19,6 +20,7 @@ export interface PlotState {
|
||||||
mature: boolean
|
mature: boolean
|
||||||
}
|
}
|
||||||
moisture: number
|
moisture: number
|
||||||
|
fertility: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InventoryItem {
|
export interface InventoryItem {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue