@jeremyckahn/farmhand 1.23.2 → 1.23.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/assets/{index-DNPchtK9.js → index-Dihg7UqQ.js} +15 -15
- package/dist/assets/{index-DNPchtK9.js.map → index-Dihg7UqQ.js.map} +1 -1
- package/dist/index.html +1 -1
- package/dist/service-worker.js +1 -1
- package/dist/service-worker.js.map +1 -1
- package/package.json +4 -5
- package/src/common/services/randomNumber.test.ts +61 -1
- package/src/common/services/randomNumber.ts +36 -1
- package/src/common/utils.ts +22 -13
- package/src/components/AccountingView/AccountingView.tsx +4 -12
- package/src/components/Achievement/Achievement.tsx +0 -13
- package/src/components/AchievementsView/AchievementsView.tsx +2 -7
- package/src/components/AnimatedNumber/AnimatedNumber.tsx +0 -6
- package/src/components/AppBar/AppBar.tsx +0 -10
- package/src/components/Cellar/Cellar.tsx +0 -2
- package/src/components/Cellar/CellarInventoryTabPanel.tsx +0 -6
- package/src/components/Cellar/FermentationTabPanel.tsx +0 -6
- package/src/components/Cellar/Keg.tsx +0 -5
- package/src/components/Cellar/TabPanel/index.tsx +0 -7
- package/src/components/Cellar/WinemakingTabPanel.tsx +0 -6
- package/src/components/ContextPane/ContextPane.tsx +0 -6
- package/src/components/CowCard/Bloodline/Bloodline.tsx +0 -5
- package/src/components/CowCard/CowCard.tsx +0 -26
- package/src/components/CowCard/Subheader/Subheader.tsx +11 -26
- package/src/components/CowPen/CowPen.tsx +4 -15
- package/src/components/CowPenContextMenu/CowPenContextMenu.tsx +0 -16
- package/src/components/CowPenContextMenu/TabPanel/index.tsx +0 -7
- package/src/components/Farmhand/Farmhand.context.tsx +4 -3
- package/src/components/Farmhand/Farmhand.tsx +4 -11
- package/src/components/Farmhand/FarmhandReducers.tsx +1 -2
- package/src/components/Farmhand/FarmhandService.test.ts +6 -9
- package/src/components/Farmhand/hooks/useFarmhandDayAdvancement.ts +2 -6
- package/src/components/Farmhand/hooks/useFarmhandNetwork.test.ts +2 -2
- package/src/components/Farmhand/hooks/useFarmhandNetwork.ts +15 -31
- package/src/components/Farmhand/useFarmhand.test.ts +7 -5
- package/src/components/Farmhand/useFarmhand.ts +12 -13
- package/src/components/FermentationRecipeList/FermentationRecipe.tsx +0 -5
- package/src/components/FermentationRecipeList/FermentationRecipeList.test.tsx +10 -11
- package/src/components/FermentationRecipeList/FermentationRecipeList.tsx +2 -3
- package/src/components/Field/Field.tsx +13 -48
- package/src/components/Forest/Forest.tsx +10 -7
- package/src/components/ForestPlot/ForestPlot.tsx +5 -5
- package/src/components/ForestQuickSelect/ForestQuickSelect.tsx +0 -12
- package/src/components/Home/Home.tsx +0 -6
- package/src/components/Home/SnowBackground.tsx +1 -1
- package/src/components/IngredientsList/IngredientsList.tsx +0 -7
- package/src/components/Inventory/Inventory.test.tsx +4 -4
- package/src/components/Inventory/Inventory.tsx +3 -11
- package/src/components/Item/Item.tsx +0 -21
- package/src/components/ItemList/ItemList.tsx +4 -11
- package/src/components/KeybindingsView/KeybindingsView.tsx +0 -2
- package/src/components/LogView/LogView.tsx +0 -6
- package/src/components/Navigation/DayAndProgressContainer.tsx +0 -7
- package/src/components/Navigation/Navigation.tsx +0 -23
- package/src/components/NotificationSystem/NotificationSystem.test.tsx +4 -1
- package/src/components/NotificationSystem/NotificationSystem.tsx +5 -12
- package/src/components/OnlinePeersView/OnlinePeer/OnlinePeer.test.tsx +2 -2
- package/src/components/OnlinePeersView/OnlinePeer/OnlinePeer.tsx +0 -11
- package/src/components/OnlinePeersView/OnlinePeersView.tsx +0 -10
- package/src/components/Plot/Plot.tsx +3 -3
- package/src/components/PriceEventView/PriceEventView.tsx +0 -6
- package/src/components/ProgressBar/ProgressBar.tsx +0 -5
- package/src/components/QuantityInput/QuantityInput.tsx +0 -9
- package/src/components/QuickSelect/QuickSelect.tsx +0 -10
- package/src/components/Recipe/Recipe.tsx +0 -9
- package/src/components/RecipeList/RecipeList.tsx +0 -6
- package/src/components/SearchBar/SearchBar.tsx +0 -6
- package/src/components/SettingsView/RandomSeedInput.test.tsx +2 -4
- package/src/components/SettingsView/RandomSeedInput.tsx +5 -8
- package/src/components/SettingsView/SettingsView.test.tsx +21 -0
- package/src/components/SettingsView/SettingsView.tsx +24 -16
- package/src/components/Shop/Shop.tsx +0 -20
- package/src/components/Shop/TabPanel/index.tsx +0 -7
- package/src/components/Stage/Stage.tsx +11 -20
- package/src/components/StatsView/StatsView.tsx +0 -15
- package/src/components/TierPurchase/TierPurchase.tsx +0 -12
- package/src/components/Toolbelt/Toolbelt.tsx +5 -10
- package/src/components/UpgradePurchase/UpgradePurchase.tsx +0 -10
- package/src/components/WineRecipeList/WineRecipe.test.tsx +2 -2
- package/src/components/WineRecipeList/WineRecipe.tsx +0 -5
- package/src/components/WineRecipeList/WineRecipeList.tsx +2 -3
- package/src/components/Workshop/ForgeTabPanel.tsx +0 -8
- package/src/components/Workshop/KitchenTabPanel.tsx +0 -7
- package/src/components/Workshop/RecyclingTabPanel.tsx +0 -7
- package/src/components/Workshop/TabPanel/index.tsx +0 -7
- package/src/components/Workshop/WoodChipperTabPanel.tsx +0 -7
- package/src/components/Workshop/Workshop.tsx +0 -9
- package/src/components/Workshop/getUpgradesAvailable.ts +1 -1
- package/src/constants.ts +18 -13
- package/src/data/crops/grape.ts +13 -15
- package/src/data/maps.test.ts +3 -4
- package/src/data/maps.ts +27 -29
- package/src/enums.ts +47 -19
- package/src/factories/OreFactory.ts +2 -1
- package/src/farmhand.d.ts +2 -3
- package/src/game-logic/reducers/applyPrecipitation.ts +4 -4
- package/src/game-logic/reducers/generatePriceEvents.ts +6 -3
- package/src/game-logic/reducers/harvestForestPlot.ts +1 -2
- package/src/game-logic/reducers/makeFermentationRecipe.ts +2 -3
- package/src/game-logic/reducers/minePlot.test.ts +2 -2
- package/src/game-logic/reducers/minePlot.ts +1 -1
- package/src/game-logic/reducers/processCowFertilizerProduction.test.ts +16 -14
- package/src/game-logic/reducers/processFeedingCows.test.ts +2 -5
- package/src/game-logic/reducers/purchaseCow.ts +2 -7
- package/src/game-logic/reducers/updateAchievements.ts +1 -1
- package/src/game-logic/reducers/updateFinancialRecords.test.ts +21 -25
- package/src/game-logic/reducers/updateFinancialRecords.ts +2 -5
- package/src/game-logic/reducers/updateInventoryRecordsForNextDay.test.ts +12 -14
- package/src/handlers/ui-events.test.ts +44 -42
- package/src/handlers/ui-events.tsx +10 -0
- package/src/hooks/usePrefersReducedMotion.ts +10 -6
- package/src/mui-theme.ts +4 -3
- package/src/scripts/generate-crop-table.ts +3 -2
- package/src/styles/sx.ts +29 -25
- package/src/test-utils/index.ts +1 -0
- package/src/utils/chooseRandom.ts +4 -1
- package/src/utils/chooseRandomIndex.ts +6 -2
- package/src/utils/getCowImage.ts +22 -16
- package/src/utils/getMaxYieldOfFermentationRecipe.ts +2 -2
- package/src/utils/getPeerMetadata.ts +1 -1
- package/src/utils/getPlotImage.test.ts +14 -14
- package/src/utils/getPlotImage.ts +10 -10
- package/src/utils/getRandomUnlockedCrop.ts +5 -3
- package/src/utils/getRandomizedLifespan.test.ts +2 -8
- package/src/utils/getValueAdjustmentStream.test.ts +9 -0
- package/src/utils/getValueAdjustmentStream.ts +5 -0
- package/src/utils/isItemAFarmProduct.ts +2 -2
- package/src/utils/shouldPrecipitateToday.ts +3 -1
- package/src/utils/shouldStormToday.ts +2 -1
- package/src/utils/transformStateDataForImport.ts +3 -5
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
-
import { bool, func } from 'prop-types'
|
|
3
2
|
import Button from '@mui/material/Button/index.js'
|
|
4
3
|
import Dialog from '@mui/material/Dialog/index.js'
|
|
5
4
|
import DialogActions from '@mui/material/DialogActions/index.js'
|
|
@@ -11,11 +10,16 @@ import FormControlLabel from '@mui/material/FormControlLabel/index.js'
|
|
|
11
10
|
import FormGroup from '@mui/material/FormGroup/index.js'
|
|
12
11
|
import FormLabel from '@mui/material/FormLabel/index.js'
|
|
13
12
|
import Switch from '@mui/material/Switch/index.js'
|
|
13
|
+
import Slider from '@mui/material/Slider/index.js'
|
|
14
14
|
import Tooltip from '@mui/material/Tooltip/index.js'
|
|
15
15
|
import FileReaderInput from 'react-file-reader-input'
|
|
16
16
|
|
|
17
17
|
import FarmhandContext from '../Farmhand/Farmhand.context.js'
|
|
18
18
|
import { Div } from '../Elements/index.js'
|
|
19
|
+
import {
|
|
20
|
+
NOTIFICATION_DURATION_MAX,
|
|
21
|
+
NOTIFICATION_DURATION_MIN,
|
|
22
|
+
} from '../../constants.js'
|
|
19
23
|
|
|
20
24
|
import { RandomSeedInput } from './RandomSeedInput.js'
|
|
21
25
|
|
|
@@ -26,10 +30,12 @@ const SettingsView = ({
|
|
|
26
30
|
handleExportDataClick,
|
|
27
31
|
handleImportDataClick,
|
|
28
32
|
handleSaveButtonClick,
|
|
33
|
+
handleNotificationDurationChange,
|
|
29
34
|
handleShowNotificationsChange,
|
|
30
35
|
handleUseAlternateEndDayButtonPositionChange,
|
|
31
36
|
handleShowHomeScreenChange,
|
|
32
37
|
showNotifications,
|
|
38
|
+
notificationDuration,
|
|
33
39
|
useAlternateEndDayButtonPosition,
|
|
34
40
|
showHomeScreen,
|
|
35
41
|
}: {
|
|
@@ -41,6 +47,10 @@ const SettingsView = ({
|
|
|
41
47
|
handleExportDataClick: () => void
|
|
42
48
|
handleImportDataClick: (results: any) => void
|
|
43
49
|
handleSaveButtonClick: () => void
|
|
50
|
+
handleNotificationDurationChange: (
|
|
51
|
+
event: React.SyntheticEvent | Event,
|
|
52
|
+
value: number | number[]
|
|
53
|
+
) => void
|
|
44
54
|
handleShowNotificationsChange: (
|
|
45
55
|
event: React.ChangeEvent<HTMLInputElement>
|
|
46
56
|
) => void
|
|
@@ -51,6 +61,7 @@ const SettingsView = ({
|
|
|
51
61
|
event: React.ChangeEvent<HTMLInputElement>
|
|
52
62
|
) => void
|
|
53
63
|
showNotifications: boolean
|
|
64
|
+
notificationDuration: number
|
|
54
65
|
useAlternateEndDayButtonPosition: boolean
|
|
55
66
|
showHomeScreen: boolean
|
|
56
67
|
}) => {
|
|
@@ -110,6 +121,18 @@ const SettingsView = ({
|
|
|
110
121
|
}
|
|
111
122
|
label="Show new notifications"
|
|
112
123
|
/>
|
|
124
|
+
<FormLabel component="legend">Notification display time</FormLabel>
|
|
125
|
+
<Slider
|
|
126
|
+
aria-label="Notification display time"
|
|
127
|
+
marks
|
|
128
|
+
min={NOTIFICATION_DURATION_MIN / 1000}
|
|
129
|
+
max={NOTIFICATION_DURATION_MAX / 1000}
|
|
130
|
+
onChange={handleNotificationDurationChange}
|
|
131
|
+
sx={{ margin: '0 auto', width: '90%' }}
|
|
132
|
+
value={notificationDuration / 1000}
|
|
133
|
+
valueLabelDisplay="auto"
|
|
134
|
+
valueLabelFormat={value => `${value} seconds`}
|
|
135
|
+
/>
|
|
113
136
|
<FormControlLabel
|
|
114
137
|
control={
|
|
115
138
|
<Switch
|
|
@@ -230,21 +253,6 @@ const SettingsView = ({
|
|
|
230
253
|
)
|
|
231
254
|
}
|
|
232
255
|
|
|
233
|
-
SettingsView.propTypes = {
|
|
234
|
-
allowCustomPeerCowNames: bool.isRequired,
|
|
235
|
-
handleAllowCustomPeerCowNamesChange: func.isRequired,
|
|
236
|
-
handleClearPersistedDataClick: func.isRequired,
|
|
237
|
-
handleExportDataClick: func.isRequired,
|
|
238
|
-
handleImportDataClick: func.isRequired,
|
|
239
|
-
handleSaveButtonClick: func.isRequired,
|
|
240
|
-
handleShowHomeScreenChange: func.isRequired,
|
|
241
|
-
handleShowNotificationsChange: func.isRequired,
|
|
242
|
-
handleUseAlternateEndDayButtonPositionChange: func.isRequired,
|
|
243
|
-
showHomeScreen: bool.isRequired,
|
|
244
|
-
showNotifications: bool.isRequired,
|
|
245
|
-
useAlternateEndDayButtonPosition: bool.isRequired,
|
|
246
|
-
}
|
|
247
|
-
|
|
248
256
|
export { SettingsView }
|
|
249
257
|
|
|
250
258
|
export default function Consumer(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { array, func, number, object } from 'prop-types'
|
|
3
2
|
import Button from '@mui/material/Button/index.js'
|
|
4
3
|
import Card from '@mui/material/Card/index.js'
|
|
5
4
|
import CardActions from '@mui/material/CardActions/index.js'
|
|
@@ -395,25 +394,6 @@ export const Shop = ({
|
|
|
395
394
|
)
|
|
396
395
|
}
|
|
397
396
|
|
|
398
|
-
Shop.propTypes = {
|
|
399
|
-
handleCombinePurchase: func.isRequired,
|
|
400
|
-
handleCowPenPurchase: func.isRequired,
|
|
401
|
-
handleCellarPurchase: func.isRequired,
|
|
402
|
-
handleFieldPurchase: func.isRequired,
|
|
403
|
-
handleStorageExpansionPurchase: func.isRequired,
|
|
404
|
-
inventoryLimit: number.isRequired,
|
|
405
|
-
money: number.isRequired,
|
|
406
|
-
purchasedCowPen: number.isRequired,
|
|
407
|
-
purchasedCellar: number.isRequired,
|
|
408
|
-
purchasedField: number.isRequired,
|
|
409
|
-
purchasedSmelter: number.isRequired,
|
|
410
|
-
purchasedWoodChipper: number.isRequired,
|
|
411
|
-
purchasedCombine: number.isRequired,
|
|
412
|
-
shopInventory: array.isRequired,
|
|
413
|
-
toolLevels: object.isRequired,
|
|
414
|
-
valueAdjustments: object.isRequired,
|
|
415
|
-
}
|
|
416
|
-
|
|
417
397
|
export default function Consumer(props: Partial<Parameters<typeof Shop>[0]>) {
|
|
418
398
|
return (
|
|
419
399
|
<FarmhandContext.Consumer>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { node, number } from 'prop-types'
|
|
3
2
|
|
|
4
3
|
export const TabPanel = (
|
|
5
4
|
props: React.PropsWithChildren<
|
|
@@ -21,12 +20,6 @@ export const TabPanel = (
|
|
|
21
20
|
)
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
TabPanel.propTypes = {
|
|
25
|
-
children: node,
|
|
26
|
-
index: number.isRequired,
|
|
27
|
-
value: number.isRequired,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
23
|
export const a11yProps = (index: number) => ({
|
|
31
24
|
id: `shop-tab-${index}`,
|
|
32
25
|
'aria-controls': `shop-tabpanel-${index}`,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react'
|
|
2
2
|
import classNames from 'classnames'
|
|
3
|
-
import { array, arrayOf, bool, number, string } from 'prop-types'
|
|
4
3
|
import { Theme } from '@mui/material/styles/index.js'
|
|
5
4
|
|
|
6
5
|
import FarmhandContext from '../Farmhand/Farmhand.context.js'
|
|
@@ -45,9 +44,8 @@ export const Stage = ({
|
|
|
45
44
|
useAlternateEndDayButtonPosition = false,
|
|
46
45
|
viewTitle,
|
|
47
46
|
}: StageProps) => {
|
|
48
|
-
const ref =
|
|
49
|
-
null
|
|
50
|
-
)
|
|
47
|
+
const ref =
|
|
48
|
+
/** @type {React.MutableRefObject<HTMLDivElement | null>} */ useRef(null)
|
|
51
49
|
|
|
52
50
|
useEffect(() => {
|
|
53
51
|
if (ref.current) {
|
|
@@ -67,8 +65,8 @@ export const Stage = ({
|
|
|
67
65
|
[stageFocusType.HOME]: isOctober()
|
|
68
66
|
? jackOLanternBg
|
|
69
67
|
: isDecember()
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
? winterBg
|
|
69
|
+
: brownDotBg,
|
|
72
70
|
[stageFocusType.SHOP]: yellowDotBg,
|
|
73
71
|
[stageFocusType.WORKSHOP]: lavenderDotBg,
|
|
74
72
|
[stageFocusType.CELLAR]: floorboardBg,
|
|
@@ -81,11 +79,13 @@ export const Stage = ({
|
|
|
81
79
|
// filter (see seasonFilterMap) applied via the `.stage-background` layer
|
|
82
80
|
// below - scoped to just the background, not the crop/cow/tree sprites
|
|
83
81
|
// rendered on top of it.
|
|
84
|
-
const hasSeasonalColorShift = (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
const hasSeasonalColorShift = (
|
|
83
|
+
[
|
|
84
|
+
stageFocusType.FIELD,
|
|
85
|
+
stageFocusType.COW_PEN,
|
|
86
|
+
stageFocusType.FOREST,
|
|
87
|
+
] as string[]
|
|
88
|
+
).includes(stageFocus)
|
|
89
89
|
|
|
90
90
|
return (
|
|
91
91
|
<Div
|
|
@@ -230,15 +230,6 @@ export const Stage = ({
|
|
|
230
230
|
)
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
Stage.propTypes = {
|
|
234
|
-
dayCount: number.isRequired,
|
|
235
|
-
field: arrayOf(array).isRequired,
|
|
236
|
-
isMenuOpen: bool,
|
|
237
|
-
stageFocus: string.isRequired,
|
|
238
|
-
useAlternateEndDayButtonPosition: bool,
|
|
239
|
-
viewTitle: string.isRequired,
|
|
240
|
-
}
|
|
241
|
-
|
|
242
233
|
export default function Consumer(props: Partial<Parameters<typeof Stage>[0]>) {
|
|
243
234
|
return (
|
|
244
235
|
<FarmhandContext.Consumer>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { array, object, number, string } from 'prop-types'
|
|
3
2
|
import classNames from 'classnames'
|
|
4
3
|
import Table from '@mui/material/Table/index.js'
|
|
5
4
|
import TableBody from '@mui/material/TableBody/index.js'
|
|
@@ -262,20 +261,6 @@ export const StatsView = ({
|
|
|
262
261
|
</Div>
|
|
263
262
|
)
|
|
264
263
|
|
|
265
|
-
StatsView.propTypes = {
|
|
266
|
-
cowsTraded: number.isRequired,
|
|
267
|
-
farmName: string.isRequired,
|
|
268
|
-
historicalDailyLosses: array.isRequired,
|
|
269
|
-
historicalDailyRevenue: array.isRequired,
|
|
270
|
-
itemsSold: object.isRequired,
|
|
271
|
-
profitabilityStreak: number.isRequired,
|
|
272
|
-
record7dayProfitAverage: number.isRequired,
|
|
273
|
-
recordProfitabilityStreak: number.isRequired,
|
|
274
|
-
revenue: number.isRequired,
|
|
275
|
-
todaysLosses: number.isRequired,
|
|
276
|
-
todaysRevenue: number.isRequired,
|
|
277
|
-
}
|
|
278
|
-
|
|
279
264
|
export default function Consumer(props: Partial<StatsViewProps>) {
|
|
280
265
|
return (
|
|
281
266
|
<FarmhandContext.Consumer>
|
|
@@ -7,7 +7,6 @@ import CardContent from '@mui/material/CardContent/index.js'
|
|
|
7
7
|
import CardHeader from '@mui/material/CardHeader/index.js'
|
|
8
8
|
import CardActions from '@mui/material/CardActions/index.js'
|
|
9
9
|
import Typography from '@mui/material/Typography/index.js'
|
|
10
|
-
import { func, instanceOf, node, number, string } from 'prop-types'
|
|
11
10
|
|
|
12
11
|
import FarmhandContext from '../Farmhand/Farmhand.context.js'
|
|
13
12
|
|
|
@@ -130,17 +129,6 @@ export function TierPurchase({
|
|
|
130
129
|
)
|
|
131
130
|
}
|
|
132
131
|
|
|
133
|
-
TierPurchase.propTypes = {
|
|
134
|
-
description: string,
|
|
135
|
-
onBuyClick: func.isRequired,
|
|
136
|
-
maxedOutPlaceholder: node,
|
|
137
|
-
money: number.isRequired,
|
|
138
|
-
purchasedTier: number.isRequired,
|
|
139
|
-
renderTierLabel: func.isRequired,
|
|
140
|
-
tiers: instanceOf(Map),
|
|
141
|
-
title: string.isRequired,
|
|
142
|
-
}
|
|
143
|
-
|
|
144
132
|
export default function Consumer(
|
|
145
133
|
props: Partial<Parameters<typeof TierPurchase>[0]>
|
|
146
134
|
) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import PropTypes from 'prop-types'
|
|
3
2
|
import classNames from 'classnames'
|
|
4
3
|
import ReactMarkdown from 'react-markdown'
|
|
5
4
|
|
|
@@ -20,7 +19,7 @@ import { breakpoints } from '../../styles/tokens.js'
|
|
|
20
19
|
|
|
21
20
|
const getTools = memoize(
|
|
22
21
|
(toolLevels: Record<toolType, toolLevel>, stageFocus?: stageFocusType) => {
|
|
23
|
-
const tools: typeof toolsData[keyof typeof toolsData][] = []
|
|
22
|
+
const tools: (typeof toolsData)[keyof typeof toolsData][] = []
|
|
24
23
|
|
|
25
24
|
for (let tool of Object.values(toolsData)) {
|
|
26
25
|
if (toolLevels[tool.type] === toolLevel.UNAVAILABLE) continue
|
|
@@ -66,9 +65,10 @@ export const Toolbelt = ({
|
|
|
66
65
|
sx={{
|
|
67
66
|
display: 'flex',
|
|
68
67
|
flexFlow: 'row',
|
|
69
|
-
[`@media (orientation: landscape) and (min-height: ${breakpoints.largePhone}px)`]:
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
[`@media (orientation: landscape) and (min-height: ${breakpoints.largePhone}px)`]:
|
|
69
|
+
{
|
|
70
|
+
flexFlow: 'column',
|
|
71
|
+
},
|
|
72
72
|
'& button': { flexGrow: 1, margin: '0 0.5em' },
|
|
73
73
|
}}
|
|
74
74
|
>
|
|
@@ -146,11 +146,6 @@ export const Toolbelt = ({
|
|
|
146
146
|
)
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
Toolbelt.propTypes = {
|
|
150
|
-
fieldMode: PropTypes.string.isRequired,
|
|
151
|
-
handleFieldModeSelect: PropTypes.func,
|
|
152
|
-
}
|
|
153
|
-
|
|
154
149
|
Toolbelt.defaultProps = {
|
|
155
150
|
handleFieldModeSelect: noop,
|
|
156
151
|
toolLevels: {},
|
|
@@ -4,7 +4,6 @@ import Button from '@mui/material/Button/index.js'
|
|
|
4
4
|
import Card from '@mui/material/Card/index.js'
|
|
5
5
|
import CardHeader from '@mui/material/CardHeader/index.js'
|
|
6
6
|
import CardActions from '@mui/material/CardActions/index.js'
|
|
7
|
-
import { array, func, number, object } from 'prop-types'
|
|
8
7
|
|
|
9
8
|
import IngredientsList from '../IngredientsList/index.js'
|
|
10
9
|
|
|
@@ -85,15 +84,6 @@ export function UpgradePurchase({
|
|
|
85
84
|
)
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
UpgradePurchase.propTypes = {
|
|
89
|
-
handleUpgradeTool: func.isRequired,
|
|
90
|
-
inventory: array.isRequired,
|
|
91
|
-
inventoryLimit: number.isRequired,
|
|
92
|
-
playerInventoryQuantities: object.isRequired,
|
|
93
|
-
toolLevels: object,
|
|
94
|
-
upgrade: object,
|
|
95
|
-
}
|
|
96
|
-
|
|
97
87
|
export default function Consumer(
|
|
98
88
|
props: Partial<Parameters<typeof UpgradePurchase>[0]>
|
|
99
89
|
) {
|
|
@@ -56,14 +56,14 @@ const WineRecipeStub = (
|
|
|
56
56
|
return (
|
|
57
57
|
<FarmhandContext.Provider
|
|
58
58
|
value={
|
|
59
|
-
|
|
59
|
+
{
|
|
60
60
|
gameState: { ...stubGameState, ...state },
|
|
61
61
|
handlers: {
|
|
62
62
|
...stubHandlers,
|
|
63
63
|
...handlers,
|
|
64
64
|
debounced: { ...stubHandlers, ...handlers },
|
|
65
65
|
},
|
|
66
|
-
} as unknown
|
|
66
|
+
} as unknown as React.ContextType<typeof FarmhandContext>
|
|
67
67
|
}
|
|
68
68
|
>
|
|
69
69
|
<WineRecipe
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { useContext, useEffect, useState } from 'react'
|
|
2
|
-
import { oneOf } from 'prop-types'
|
|
3
2
|
import Card from '@mui/material/Card/index.js'
|
|
4
3
|
import CardHeader from '@mui/material/CardHeader/index.js'
|
|
5
4
|
import CardActions from '@mui/material/CardActions/index.js'
|
|
@@ -142,7 +141,3 @@ export const WineRecipe = ({ wineVariety }: { wineVariety: grapeVariety }) => {
|
|
|
142
141
|
</Card>
|
|
143
142
|
)
|
|
144
143
|
}
|
|
145
|
-
|
|
146
|
-
WineRecipe.propTypes = {
|
|
147
|
-
wineVariety: oneOf(Object.keys(grapeVariety)),
|
|
148
|
-
}
|
|
@@ -15,9 +15,8 @@ export const WineRecipeList = () => {
|
|
|
15
15
|
gameState: { itemsSold },
|
|
16
16
|
} = useContext(FarmhandContext)
|
|
17
17
|
|
|
18
|
-
const wineVarietiesAvailableToMake =
|
|
19
|
-
itemsSold
|
|
20
|
-
)
|
|
18
|
+
const wineVarietiesAvailableToMake =
|
|
19
|
+
getWineVarietiesAvailableToMake(itemsSold)
|
|
21
20
|
|
|
22
21
|
const [searchQuery, setSearchQuery] = useState('')
|
|
23
22
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { number, array, object } from 'prop-types'
|
|
3
2
|
|
|
4
3
|
import Card from '@mui/material/Card/index.js'
|
|
5
4
|
import CardContent from '@mui/material/CardContent/index.js'
|
|
@@ -73,10 +72,3 @@ export function ForgeTabPanel({
|
|
|
73
72
|
</TabPanel>
|
|
74
73
|
)
|
|
75
74
|
}
|
|
76
|
-
|
|
77
|
-
ForgeTabPanel.propTypes = {
|
|
78
|
-
currentTab: number.isRequired,
|
|
79
|
-
index: number.isRequired,
|
|
80
|
-
learnedForgeRecipes: array.isRequired,
|
|
81
|
-
toolLevels: object.isRequired,
|
|
82
|
-
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { number, array } from 'prop-types'
|
|
3
2
|
|
|
4
3
|
import Card from '@mui/material/Card/index.js'
|
|
5
4
|
import CardContent from '@mui/material/CardContent/index.js'
|
|
@@ -48,9 +47,3 @@ export function KitchenTabPanel({
|
|
|
48
47
|
</TabPanel>
|
|
49
48
|
)
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
KitchenTabPanel.propTypes = {
|
|
53
|
-
currentTab: number.isRequired,
|
|
54
|
-
index: number.isRequired,
|
|
55
|
-
learnedKitchenRecipes: array.isRequired,
|
|
56
|
-
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { number, array } from 'prop-types'
|
|
3
2
|
|
|
4
3
|
import Card from '@mui/material/Card/index.js'
|
|
5
4
|
import CardContent from '@mui/material/CardContent/index.js'
|
|
@@ -48,9 +47,3 @@ export function RecyclingTabPanel({
|
|
|
48
47
|
</TabPanel>
|
|
49
48
|
)
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
RecyclingTabPanel.propTypes = {
|
|
53
|
-
currentTab: number.isRequired,
|
|
54
|
-
index: number.isRequired,
|
|
55
|
-
learnedRecipes: array.isRequired,
|
|
56
|
-
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { node, number } from 'prop-types'
|
|
3
2
|
|
|
4
3
|
interface TabPanelProps {
|
|
5
4
|
children?: React.ReactNode
|
|
@@ -24,12 +23,6 @@ export const TabPanel = (props: TabPanelProps) => {
|
|
|
24
23
|
)
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
TabPanel.propTypes = {
|
|
28
|
-
children: node,
|
|
29
|
-
index: number.isRequired,
|
|
30
|
-
value: number.isRequired,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
26
|
export const a11yProps = (index: number) => ({
|
|
34
27
|
id: `workshop-tab-${index}`,
|
|
35
28
|
'aria-controls': `workshop-tabpanel-${index}`,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { number, array } from 'prop-types'
|
|
3
2
|
|
|
4
3
|
import Card from '@mui/material/Card/index.js'
|
|
5
4
|
import CardContent from '@mui/material/CardContent/index.js'
|
|
@@ -48,9 +47,3 @@ export function WoodChipperTabPanel({
|
|
|
48
47
|
</TabPanel>
|
|
49
48
|
)
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
WoodChipperTabPanel.propTypes = {
|
|
53
|
-
currentTab: number.isRequired,
|
|
54
|
-
index: number.isRequired,
|
|
55
|
-
learnedRecipes: array.isRequired,
|
|
56
|
-
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { number, object } from 'prop-types'
|
|
3
2
|
import Tab from '@mui/material/Tab/index.js'
|
|
4
3
|
import Tabs from '@mui/material/Tabs/index.js'
|
|
5
4
|
|
|
@@ -115,14 +114,6 @@ const Workshop = ({
|
|
|
115
114
|
)
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
Workshop.propTypes = {
|
|
119
|
-
learnedRecipes: object.isRequired,
|
|
120
|
-
purchasedComposter: number,
|
|
121
|
-
purchasedSmelter: number,
|
|
122
|
-
purchasedWoodChipper: number,
|
|
123
|
-
toolLevels: object.isRequired,
|
|
124
|
-
}
|
|
125
|
-
|
|
126
117
|
export default function Consumer(
|
|
127
118
|
props: Partial<Parameters<typeof Workshop>[0]>
|
|
128
119
|
) {
|
|
@@ -17,7 +17,7 @@ export function getUpgradesAvailable({
|
|
|
17
17
|
}: GetUpgradesAvailableArgs): farmhand.upgradesMetadatum[] {
|
|
18
18
|
let upgradesAvailable: farmhand.upgradesMetadatum[] = []
|
|
19
19
|
|
|
20
|
-
const typedToolUpgrades =
|
|
20
|
+
const typedToolUpgrades = toolUpgrades as unknown as Record<
|
|
21
21
|
string,
|
|
22
22
|
Record<string, farmhand.upgradesMetadatum>
|
|
23
23
|
>
|
package/src/constants.ts
CHANGED
|
@@ -143,7 +143,14 @@ export const COW_MAXIMUM_VALUE_MULTIPLIER = 1
|
|
|
143
143
|
export const COW_GESTATION_PERIOD_DAYS = 3
|
|
144
144
|
export const COW_MINIMUM_HAPPINESS_TO_BREED = 0.8
|
|
145
145
|
|
|
146
|
-
export const
|
|
146
|
+
export const NOTIFICATION_DURATION_MIN = 4000
|
|
147
|
+
export const NOTIFICATION_DURATION_MAX = 12000
|
|
148
|
+
export const NOTIFICATION_DURATION_DEFAULT = 6000
|
|
149
|
+
export const getNotificationDuration = (duration: number) =>
|
|
150
|
+
import.meta.env?.MODE === 'test' ? 1 : duration
|
|
151
|
+
export const NOTIFICATION_DURATION = getNotificationDuration(
|
|
152
|
+
NOTIFICATION_DURATION_DEFAULT
|
|
153
|
+
)
|
|
147
154
|
export const NOTIFICATION_LOG_SIZE = 14
|
|
148
155
|
|
|
149
156
|
export const PRICE_EVENT_CHANCE = 0.2
|
|
@@ -199,6 +206,7 @@ export const PERSISTED_STATE_KEYS = [
|
|
|
199
206
|
'mulchApplied',
|
|
200
207
|
'newDayNotifications',
|
|
201
208
|
'notificationLog',
|
|
209
|
+
'notificationDuration',
|
|
202
210
|
'priceCrashes',
|
|
203
211
|
'priceSurges',
|
|
204
212
|
'profitabilityStreak',
|
|
@@ -274,10 +282,9 @@ export const GOLD_SPAWN_CHANCE = 0.07
|
|
|
274
282
|
export const IRON_SPAWN_CHANCE = 0.33
|
|
275
283
|
export const SILVER_SPAWN_CHANCE = 0.2
|
|
276
284
|
|
|
277
|
-
export const HOE_LEVEL_TO_SEED_RECLAIM_RATE: Partial<
|
|
278
|
-
toolLevel,
|
|
279
|
-
|
|
280
|
-
>> = {
|
|
285
|
+
export const HOE_LEVEL_TO_SEED_RECLAIM_RATE: Partial<
|
|
286
|
+
Record<toolLevel, number>
|
|
287
|
+
> = {
|
|
281
288
|
[toolLevel.DEFAULT]: 0,
|
|
282
289
|
[toolLevel.BRONZE]: 0.25,
|
|
283
290
|
[toolLevel.IRON]: 0.5,
|
|
@@ -288,10 +295,9 @@ export const HOE_LEVEL_TO_SEED_RECLAIM_RATE: Partial<Record<
|
|
|
288
295
|
// [min, max] wood yield (inclusive) for chopping down a fully grown tree,
|
|
289
296
|
// keyed by the axe's tool level. An immature tree yields half of this
|
|
290
297
|
// range instead (see chopForestPlot.ts).
|
|
291
|
-
export const AXE_WOOD_YIELD_RANGE: Partial<
|
|
292
|
-
toolLevel,
|
|
293
|
-
|
|
294
|
-
>> = {
|
|
298
|
+
export const AXE_WOOD_YIELD_RANGE: Partial<
|
|
299
|
+
Record<toolLevel, [number, number]>
|
|
300
|
+
> = {
|
|
295
301
|
[toolLevel.DEFAULT]: [1, 2],
|
|
296
302
|
[toolLevel.BRONZE]: [2, 4],
|
|
297
303
|
[toolLevel.IRON]: [4, 6],
|
|
@@ -302,10 +308,9 @@ export const AXE_WOOD_YIELD_RANGE: Partial<Record<
|
|
|
302
308
|
// Flat +1 fruit per tool tier when picking with the Picker Pole (see
|
|
303
309
|
// harvestForestPlot.ts) - unlike AXE_WOOD_YIELD_RANGE this isn't a random
|
|
304
310
|
// range, just a per-tier constant.
|
|
305
|
-
export const PICKER_POLE_LEVEL_TO_FRUIT_YIELD: Partial<
|
|
306
|
-
toolLevel,
|
|
307
|
-
|
|
308
|
-
>> = {
|
|
311
|
+
export const PICKER_POLE_LEVEL_TO_FRUIT_YIELD: Partial<
|
|
312
|
+
Record<toolLevel, number>
|
|
313
|
+
> = {
|
|
309
314
|
[toolLevel.DEFAULT]: 1,
|
|
310
315
|
[toolLevel.BRONZE]: 2,
|
|
311
316
|
[toolLevel.IRON]: 3,
|
package/src/data/crops/grape.ts
CHANGED
|
@@ -198,18 +198,16 @@ export const grapeNebbiolo: farmhand.grape = grape({
|
|
|
198
198
|
wineId: 'wine-nebbiolo',
|
|
199
199
|
})
|
|
200
200
|
|
|
201
|
-
export const grapeVarietyToGrapeItemMap: Record<
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
[grapeVariety.NEBBIOLO]: grapeNebbiolo,
|
|
215
|
-
}
|
|
201
|
+
export const grapeVarietyToGrapeItemMap: Record<grapeVariety, farmhand.grape> =
|
|
202
|
+
{
|
|
203
|
+
[grapeVariety.CHARDONNAY]: grapeChardonnay,
|
|
204
|
+
[grapeVariety.SAUVIGNON_BLANC]: grapeSauvignonBlanc,
|
|
205
|
+
//[grapeVariety.PINOT_BLANC]: grapePinotBlanc,
|
|
206
|
+
//[grapeVariety.MUSCAT]: grapeMuscat,
|
|
207
|
+
//[grapeVariety.RIESLING]: grapeRiesling,
|
|
208
|
+
//[grapeVariety.MERLOT]: grapeMerlot,
|
|
209
|
+
[grapeVariety.CABERNET_SAUVIGNON]: grapeCabernetSauvignon,
|
|
210
|
+
//[grapeVariety.SYRAH]: grapeSyrah,
|
|
211
|
+
[grapeVariety.TEMPRANILLO]: grapeTempranillo,
|
|
212
|
+
[grapeVariety.NEBBIOLO]: grapeNebbiolo,
|
|
213
|
+
}
|
package/src/data/maps.test.ts
CHANGED
|
@@ -2,10 +2,9 @@ import { itemsMap } from './maps.js'
|
|
|
2
2
|
|
|
3
3
|
describe('itemsMap', () => {
|
|
4
4
|
test('no item declares the same season as both high and low demand', () => {
|
|
5
|
-
const itemsWithOverlappingDemandSeasons = Object.values(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
highDemandSeasons?.some(season => lowDemandSeasons?.includes(season))
|
|
5
|
+
const itemsWithOverlappingDemandSeasons = Object.values(itemsMap).filter(
|
|
6
|
+
({ highDemandSeasons, lowDemandSeasons }) =>
|
|
7
|
+
highDemandSeasons?.some(season => lowDemandSeasons?.includes(season))
|
|
9
8
|
)
|
|
10
9
|
|
|
11
10
|
expect(itemsWithOverlappingDemandSeasons).toEqual([])
|