@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
package/src/data/maps.ts
CHANGED
|
@@ -47,7 +47,7 @@ export const recipeCategories: Record<
|
|
|
47
47
|
export const recipesMap: Record<string, farmhand.recipe> = {}
|
|
48
48
|
|
|
49
49
|
for (const recipeId of Object.keys(recipes)) {
|
|
50
|
-
const recipe = (
|
|
50
|
+
const recipe = (recipes as unknown as Record<string, farmhand.recipe>)[
|
|
51
51
|
recipeId
|
|
52
52
|
]
|
|
53
53
|
|
|
@@ -59,10 +59,12 @@ export const upgradesMap: Record<string, farmhand.upgradesMetadatum> = {}
|
|
|
59
59
|
|
|
60
60
|
for (let toolType of Object.keys(upgrades)) {
|
|
61
61
|
for (let upgrade of Object.values(
|
|
62
|
-
(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
(
|
|
63
|
+
upgrades as unknown as Record<
|
|
64
|
+
string,
|
|
65
|
+
Record<string, farmhand.upgradesMetadatum>
|
|
66
|
+
>
|
|
67
|
+
)[toolType]
|
|
66
68
|
)) {
|
|
67
69
|
upgradesMap[upgrade.id] = upgrade
|
|
68
70
|
}
|
|
@@ -74,36 +76,32 @@ export const itemsMap: Record<string, farmhand.item> = {
|
|
|
74
76
|
...upgradesMap,
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
export const fermentableItemsMap: Record<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Object.entries(itemsMap).filter(([itemId]) => {
|
|
82
|
-
const item = itemsMap[itemId]
|
|
79
|
+
export const fermentableItemsMap: Record<string, farmhand.item> =
|
|
80
|
+
Object.fromEntries(
|
|
81
|
+
Object.entries(itemsMap).filter(([itemId]) => {
|
|
82
|
+
const item = itemsMap[itemId]
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
)
|
|
84
|
+
return 'daysToFerment' in item
|
|
85
|
+
})
|
|
86
|
+
)
|
|
87
87
|
|
|
88
|
-
export const cropItemIdToSeedItemMap: Record<
|
|
89
|
-
string,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
(acc, [itemId, item]) => {
|
|
93
|
-
const { growsInto } = item as { growsInto?: string | string[] }
|
|
88
|
+
export const cropItemIdToSeedItemMap: Record<string, farmhand.seedItem> =
|
|
89
|
+
Object.entries(baseItemsMap).reduce<Record<string, farmhand.seedItem>>(
|
|
90
|
+
(acc, [itemId, item]) => {
|
|
91
|
+
const { growsInto } = item as { growsInto?: string | string[] }
|
|
94
92
|
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
if (growsInto) {
|
|
94
|
+
const variants = Array.isArray(growsInto) ? growsInto : [growsInto]
|
|
97
95
|
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
for (const variantId of variants) {
|
|
97
|
+
acc[variantId] = baseItemsMap[itemId] as farmhand.seedItem
|
|
98
|
+
}
|
|
100
99
|
}
|
|
101
|
-
}
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
101
|
+
return acc
|
|
102
|
+
},
|
|
103
|
+
{}
|
|
104
|
+
)
|
|
107
105
|
|
|
108
106
|
export const cropTypeToIdMap: Record<string, string | Array<string>> = {
|
|
109
107
|
[ASPARAGUS]: 'asparagus',
|
package/src/enums.ts
CHANGED
|
@@ -27,7 +27,7 @@ export const cropType = {
|
|
|
27
27
|
WEED: 'WEED',
|
|
28
28
|
} as const
|
|
29
29
|
|
|
30
|
-
export type cropType = typeof cropType[keyof typeof cropType]
|
|
30
|
+
export type cropType = (typeof cropType)[keyof typeof cropType]
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* @property farmhand.module:enums.recipeType
|
|
@@ -42,7 +42,7 @@ export const recipeType = {
|
|
|
42
42
|
WOOD_CHIPPER: 'WOOD_CHIPPER',
|
|
43
43
|
} as const
|
|
44
44
|
|
|
45
|
-
export type recipeType = typeof recipeType[keyof typeof recipeType]
|
|
45
|
+
export type recipeType = (typeof recipeType)[keyof typeof recipeType]
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* @property farmhand.module:enums.fieldMode
|
|
@@ -63,7 +63,7 @@ export const fieldMode = {
|
|
|
63
63
|
WATER: 'WATER',
|
|
64
64
|
} as const
|
|
65
65
|
|
|
66
|
-
export type fieldMode = typeof fieldMode[keyof typeof fieldMode]
|
|
66
|
+
export type fieldMode = (typeof fieldMode)[keyof typeof fieldMode]
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* @property farmhand.module:enums.stageFocusType
|
|
@@ -81,7 +81,8 @@ export const stageFocusType = {
|
|
|
81
81
|
CELLAR: 'CELLAR',
|
|
82
82
|
} as const
|
|
83
83
|
|
|
84
|
-
export type stageFocusType =
|
|
84
|
+
export type stageFocusType =
|
|
85
|
+
(typeof stageFocusType)[keyof typeof stageFocusType]
|
|
85
86
|
|
|
86
87
|
/**
|
|
87
88
|
* @property farmhand.module:enums.cropLifeStage
|
|
@@ -93,7 +94,7 @@ export const cropLifeStage = {
|
|
|
93
94
|
GROWN: 'GROWN',
|
|
94
95
|
} as const
|
|
95
96
|
|
|
96
|
-
export type cropLifeStage = typeof cropLifeStage[keyof typeof cropLifeStage]
|
|
97
|
+
export type cropLifeStage = (typeof cropLifeStage)[keyof typeof cropLifeStage]
|
|
97
98
|
|
|
98
99
|
/**
|
|
99
100
|
* Tree-only extension of cropLifeStage. DEAD is deliberately not part of
|
|
@@ -107,7 +108,7 @@ export const treeLifeStage = {
|
|
|
107
108
|
DEAD: 'DEAD',
|
|
108
109
|
} as const
|
|
109
110
|
|
|
110
|
-
export type treeLifeStage = typeof treeLifeStage[keyof typeof treeLifeStage]
|
|
111
|
+
export type treeLifeStage = (typeof treeLifeStage)[keyof typeof treeLifeStage]
|
|
111
112
|
|
|
112
113
|
/**
|
|
113
114
|
* @property farmhand.module:enums.itemType
|
|
@@ -133,7 +134,7 @@ export const itemType = {
|
|
|
133
134
|
WOOD: 'WOOD',
|
|
134
135
|
} as const
|
|
135
136
|
|
|
136
|
-
export type itemType = typeof itemType[keyof typeof itemType]
|
|
137
|
+
export type itemType = (typeof itemType)[keyof typeof itemType]
|
|
137
138
|
|
|
138
139
|
/**
|
|
139
140
|
* @property farmhand.module:enums.treeType
|
|
@@ -144,7 +145,7 @@ export const treeType = {
|
|
|
144
145
|
BANANA: 'BANANA',
|
|
145
146
|
} as const
|
|
146
147
|
|
|
147
|
-
export type treeType = typeof treeType[keyof typeof treeType]
|
|
148
|
+
export type treeType = (typeof treeType)[keyof typeof treeType]
|
|
148
149
|
|
|
149
150
|
/**
|
|
150
151
|
* @property farmhand.module:enums.fertilizerType
|
|
@@ -156,7 +157,8 @@ export const fertilizerType = {
|
|
|
156
157
|
RAINBOW: 'RAINBOW',
|
|
157
158
|
} as const
|
|
158
159
|
|
|
159
|
-
export type fertilizerType =
|
|
160
|
+
export type fertilizerType =
|
|
161
|
+
(typeof fertilizerType)[keyof typeof fertilizerType]
|
|
160
162
|
|
|
161
163
|
/**
|
|
162
164
|
* @property farmhand.module:enums.genders
|
|
@@ -167,7 +169,7 @@ export const genders = {
|
|
|
167
169
|
MALE: 'MALE',
|
|
168
170
|
} as const
|
|
169
171
|
|
|
170
|
-
export type genders = typeof genders[keyof typeof genders]
|
|
172
|
+
export type genders = (typeof genders)[keyof typeof genders]
|
|
171
173
|
|
|
172
174
|
/**
|
|
173
175
|
* @property farmhand.module:enums.cowColors
|
|
@@ -184,7 +186,7 @@ export const cowColors = {
|
|
|
184
186
|
YELLOW: 'YELLOW',
|
|
185
187
|
} as const
|
|
186
188
|
|
|
187
|
-
export type cowColors = typeof cowColors[keyof typeof cowColors]
|
|
189
|
+
export type cowColors = (typeof cowColors)[keyof typeof cowColors]
|
|
188
190
|
|
|
189
191
|
const { RAINBOW, ...standardCowColors } = cowColors
|
|
190
192
|
|
|
@@ -206,7 +208,7 @@ export const dialogView = {
|
|
|
206
208
|
STATS: 'STATS',
|
|
207
209
|
} as const
|
|
208
210
|
|
|
209
|
-
export type dialogView = typeof dialogView[keyof typeof dialogView]
|
|
211
|
+
export type dialogView = (typeof dialogView)[keyof typeof dialogView]
|
|
210
212
|
|
|
211
213
|
/**
|
|
212
214
|
* @property farmhand.module:enums.toolType
|
|
@@ -221,7 +223,7 @@ export const toolType = {
|
|
|
221
223
|
WATERING_CAN: 'WATERING_CAN',
|
|
222
224
|
} as const
|
|
223
225
|
|
|
224
|
-
export type toolType = typeof toolType[keyof typeof toolType]
|
|
226
|
+
export type toolType = (typeof toolType)[keyof typeof toolType]
|
|
225
227
|
|
|
226
228
|
/**
|
|
227
229
|
* @property farmhand.module:enums.toolLevel
|
|
@@ -236,7 +238,7 @@ export const toolLevel = {
|
|
|
236
238
|
GOLD: 'GOLD',
|
|
237
239
|
} as const
|
|
238
240
|
|
|
239
|
-
export type toolLevel = typeof toolLevel[keyof typeof toolLevel]
|
|
241
|
+
export type toolLevel = (typeof toolLevel)[keyof typeof toolLevel]
|
|
240
242
|
|
|
241
243
|
/**
|
|
242
244
|
* @property farmhand.module:enums.notificationSeverity
|
|
@@ -249,7 +251,8 @@ export const notificationSeverity = {
|
|
|
249
251
|
ERROR: 'error',
|
|
250
252
|
} as const
|
|
251
253
|
|
|
252
|
-
export type notificationSeverity =
|
|
254
|
+
export type notificationSeverity =
|
|
255
|
+
(typeof notificationSeverity)[keyof typeof notificationSeverity]
|
|
253
256
|
|
|
254
257
|
/**
|
|
255
258
|
* @property farmhand.module:enums.cowTradeRejectionReason
|
|
@@ -259,7 +262,8 @@ export const cowTradeRejectionReason = {
|
|
|
259
262
|
REQUESTED_COW_UNAVAILABLE: 'REQUESTED_COW_UNAVAILABLE',
|
|
260
263
|
} as const
|
|
261
264
|
|
|
262
|
-
export type cowTradeRejectionReason =
|
|
265
|
+
export type cowTradeRejectionReason =
|
|
266
|
+
(typeof cowTradeRejectionReason)[keyof typeof cowTradeRejectionReason]
|
|
263
267
|
|
|
264
268
|
/**
|
|
265
269
|
* @property farmhand.module:enums.cropFamily
|
|
@@ -270,7 +274,7 @@ export const cropFamily = {
|
|
|
270
274
|
GRAPE: 'GRAPE',
|
|
271
275
|
} as const
|
|
272
276
|
|
|
273
|
-
export type cropFamily = typeof cropFamily[keyof typeof cropFamily]
|
|
277
|
+
export type cropFamily = (typeof cropFamily)[keyof typeof cropFamily]
|
|
274
278
|
|
|
275
279
|
/**
|
|
276
280
|
* @property farmhand.module:enums.grapeVariety
|
|
@@ -290,7 +294,7 @@ export const grapeVariety = {
|
|
|
290
294
|
NEBBIOLO: 'NEBBIOLO',
|
|
291
295
|
} as const
|
|
292
296
|
|
|
293
|
-
export type grapeVariety = typeof grapeVariety[keyof typeof grapeVariety]
|
|
297
|
+
export type grapeVariety = (typeof grapeVariety)[keyof typeof grapeVariety]
|
|
294
298
|
|
|
295
299
|
/**
|
|
296
300
|
* @property farmhand.module:enums.season
|
|
@@ -303,4 +307,28 @@ export const season = {
|
|
|
303
307
|
WINTER: 'WINTER',
|
|
304
308
|
} as const
|
|
305
309
|
|
|
306
|
-
export type season = typeof season[keyof typeof season]
|
|
310
|
+
export type season = (typeof season)[keyof typeof season]
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Names of the random number streams that game logic draws from. A stream
|
|
314
|
+
* name identifies where a value is drawn so that it can be forced with
|
|
315
|
+
* RandomNumberService#queueRandomNumbers (e.g. in E2E tests).
|
|
316
|
+
* @property farmhand.module:enums.randomStream
|
|
317
|
+
* @enum
|
|
318
|
+
*/
|
|
319
|
+
export const randomStream = {
|
|
320
|
+
PRECIPITATION: 'precipitation',
|
|
321
|
+
STORM: 'storm',
|
|
322
|
+
PRICE_EVENT_CHANCE: 'priceEventChance',
|
|
323
|
+
PRICE_EVENT_CROP: 'priceEventCrop',
|
|
324
|
+
PRICE_EVENT_TYPE: 'priceEventType',
|
|
325
|
+
} as const
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* The stream for an item's price adjustment (see generateValueAdjustments in
|
|
329
|
+
* src/common/utils.ts). Create one with getValueAdjustmentStream.
|
|
330
|
+
*/
|
|
331
|
+
export type valueAdjustmentStream = `valueAdjustment:${string}`
|
|
332
|
+
|
|
333
|
+
export type randomStream =
|
|
334
|
+
(typeof randomStream)[keyof typeof randomStream] | valueAdjustmentStream
|
|
@@ -9,7 +9,8 @@ const SPAWNABLE_ORES = [goldOre, ironOre, bronzeOre, silverOre]
|
|
|
9
9
|
* @constructor
|
|
10
10
|
*/
|
|
11
11
|
export default class OreFactory extends Factory {
|
|
12
|
-
oreOptions: Array<{ ore: typeof SPAWNABLE_ORES[number]; weight: number }> =
|
|
12
|
+
oreOptions: Array<{ ore: (typeof SPAWNABLE_ORES)[number]; weight: number }> =
|
|
13
|
+
[]
|
|
13
14
|
|
|
14
15
|
constructor() {
|
|
15
16
|
super()
|
package/src/farmhand.d.ts
CHANGED
|
@@ -181,9 +181,7 @@ declare namespace farmhand {
|
|
|
181
181
|
|
|
182
182
|
type achievementCondition = (state: state, prevState?: state) => boolean
|
|
183
183
|
type achievementReward = (state: state) => state
|
|
184
|
-
type achievementProgress = (
|
|
185
|
-
state: state
|
|
186
|
-
) => {
|
|
184
|
+
type achievementProgress = (state: state) => {
|
|
187
185
|
currentValue: number
|
|
188
186
|
goal: number
|
|
189
187
|
}
|
|
@@ -403,6 +401,7 @@ declare namespace farmhand {
|
|
|
403
401
|
latestNotification?: notification | null
|
|
404
402
|
newDayNotifications: notification[]
|
|
405
403
|
notificationLog: notificationLogEntry[]
|
|
404
|
+
notificationDuration: number
|
|
406
405
|
/**
|
|
407
406
|
* Keys are (Trystero) peer ids, values are their respective metadata or null.
|
|
408
407
|
*/
|
|
@@ -83,13 +83,13 @@ export const applyPrecipitation = (state: farmhand.state): farmhand.state => {
|
|
|
83
83
|
message: anyRodWasDestroyed
|
|
84
84
|
? LIGHTNING_ROD_DESTROYED_MESSAGE
|
|
85
85
|
: anyRodWasReplanted
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
? LIGHTNING_ROD_REPLANTED_MESSAGE
|
|
87
|
+
: LIGHTNING_ROD_STRUCK_MESSAGE,
|
|
88
88
|
severity: anyRodWasDestroyed
|
|
89
89
|
? 'error'
|
|
90
90
|
: anyRodWasReplanted
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
? 'success'
|
|
92
|
+
: 'info',
|
|
93
93
|
}
|
|
94
94
|
} else if (fieldHasScarecrow(field)) {
|
|
95
95
|
notification = {
|
|
@@ -6,6 +6,7 @@ import { getLevelEntitlements } from '../../utils/getLevelEntitlements.js'
|
|
|
6
6
|
import { PRICE_EVENT_CHANCE } from '../../constants.js'
|
|
7
7
|
import { PRICE_CRASH, PRICE_SURGE } from '../../templates.js'
|
|
8
8
|
import { random } from '../../common/utils.js'
|
|
9
|
+
import { randomStream } from '../../enums.js'
|
|
9
10
|
|
|
10
11
|
import { createPriceEvent } from './createPriceEvent.js'
|
|
11
12
|
|
|
@@ -20,13 +21,14 @@ export const generatePriceEvents = (state: farmhand.state): farmhand.state => {
|
|
|
20
21
|
|
|
21
22
|
// TODO: Use isRandomNumberLessThan here once it supports an exclusive
|
|
22
23
|
// less-than check.
|
|
23
|
-
if (random() < PRICE_EVENT_CHANCE) {
|
|
24
|
+
if (random(randomStream.PRICE_EVENT_CHANCE) < PRICE_EVENT_CHANCE) {
|
|
24
25
|
const { items: unlockedItems } = getLevelEntitlements(
|
|
25
26
|
levelAchieved(state.experience)
|
|
26
27
|
)
|
|
27
28
|
|
|
28
29
|
const cropItem = getRandomUnlockedCrop(
|
|
29
|
-
filterItemIdsToSeeds(Object.keys(unlockedItems))
|
|
30
|
+
filterItemIdsToSeeds(Object.keys(unlockedItems)),
|
|
31
|
+
randomStream.PRICE_EVENT_CROP
|
|
30
32
|
)
|
|
31
33
|
const { id } = cropItem
|
|
32
34
|
|
|
@@ -35,7 +37,8 @@ export const generatePriceEvents = (state: farmhand.state): farmhand.state => {
|
|
|
35
37
|
)
|
|
36
38
|
|
|
37
39
|
if (!doesPriceEventAlreadyExist) {
|
|
38
|
-
const priceEventType =
|
|
40
|
+
const priceEventType =
|
|
41
|
+
random(randomStream.PRICE_EVENT_TYPE) < 0.5 ? TYPE_CRASH : TYPE_SURGE
|
|
39
42
|
|
|
40
43
|
priceEvent = createPriceEvent(
|
|
41
44
|
state,
|
|
@@ -50,8 +50,7 @@ export const harvestForestPlot = (
|
|
|
50
50
|
...state,
|
|
51
51
|
treeFruitsHarvested: {
|
|
52
52
|
...state.treeFruitsHarvested,
|
|
53
|
-
[item.id]:
|
|
54
|
-
(state.treeFruitsHarvested[item.id] || 0) + receivedFruitYield,
|
|
53
|
+
[item.id]: (state.treeFruitsHarvested[item.id] || 0) + receivedFruitYield,
|
|
55
54
|
},
|
|
56
55
|
}
|
|
57
56
|
|
|
@@ -35,9 +35,8 @@ export const makeFermentationRecipe = (
|
|
|
35
35
|
state = addKegToCellarInventory(state, keg)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const saltRequirements =
|
|
39
|
-
fermentationRecipe
|
|
40
|
-
)
|
|
38
|
+
const saltRequirements =
|
|
39
|
+
getSaltRequirementsForFermentationRecipe(fermentationRecipe)
|
|
41
40
|
|
|
42
41
|
state = decrementItemFromInventory(state, fermentationRecipe.id, howMany)
|
|
43
42
|
|
|
@@ -11,9 +11,9 @@ describe('minePlot', () => {
|
|
|
11
11
|
|
|
12
12
|
beforeAll(() => {
|
|
13
13
|
vitest.spyOn(randomNumberService, 'generateRandomNumber').mockReturnValue(1)
|
|
14
|
-
vitest.spyOn(ResourceFactory, 'instance').mockReturnValue(
|
|
14
|
+
vitest.spyOn(ResourceFactory, 'instance').mockReturnValue({
|
|
15
15
|
generateResources: () => [goldOre],
|
|
16
|
-
} as unknown
|
|
16
|
+
} as unknown as typeof ResourceFactory.prototype)
|
|
17
17
|
|
|
18
18
|
gameState = minePlot(
|
|
19
19
|
testState({
|
|
@@ -29,7 +29,7 @@ export const minePlot = (
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const shovelLevel = state.toolLevels[toolType.SHOVEL]
|
|
32
|
-
const factory =
|
|
32
|
+
const factory = ResourceFactory.instance() as unknown as {
|
|
33
33
|
generateResources: (l: number) => farmhand.item[]
|
|
34
34
|
}
|
|
35
35
|
const spawnedResources = factory.generateResources(shovelLevel as any)
|
|
@@ -53,7 +53,8 @@ describe('processCowFertilizerProduction', () => {
|
|
|
53
53
|
state.cowInventory = [
|
|
54
54
|
generateCow({
|
|
55
55
|
color: standardCowColors.WHITE,
|
|
56
|
-
daysSinceProducingFertilizer:
|
|
56
|
+
daysSinceProducingFertilizer:
|
|
57
|
+
COW_FERTILIZER_PRODUCTION_RATE_SLOWEST,
|
|
57
58
|
gender: genders.MALE,
|
|
58
59
|
}),
|
|
59
60
|
]
|
|
@@ -85,12 +86,14 @@ describe('processCowFertilizerProduction', () => {
|
|
|
85
86
|
state.cowInventory = [
|
|
86
87
|
generateCow({
|
|
87
88
|
color: standardCowColors.WHITE,
|
|
88
|
-
daysSinceProducingFertilizer:
|
|
89
|
+
daysSinceProducingFertilizer:
|
|
90
|
+
COW_FERTILIZER_PRODUCTION_RATE_SLOWEST,
|
|
89
91
|
gender: genders.MALE,
|
|
90
92
|
}),
|
|
91
93
|
generateCow({
|
|
92
94
|
color: standardCowColors.WHITE,
|
|
93
|
-
daysSinceProducingFertilizer:
|
|
95
|
+
daysSinceProducingFertilizer:
|
|
96
|
+
COW_FERTILIZER_PRODUCTION_RATE_SLOWEST,
|
|
94
97
|
gender: genders.MALE,
|
|
95
98
|
}),
|
|
96
99
|
]
|
|
@@ -122,14 +125,14 @@ describe('processCowFertilizerProduction', () => {
|
|
|
122
125
|
state.cowInventory = [
|
|
123
126
|
generateCow({
|
|
124
127
|
color: cowColors.RAINBOW,
|
|
125
|
-
daysSinceProducingFertilizer:
|
|
128
|
+
daysSinceProducingFertilizer:
|
|
129
|
+
COW_FERTILIZER_PRODUCTION_RATE_SLOWEST,
|
|
126
130
|
gender: genders.MALE,
|
|
127
131
|
}),
|
|
128
132
|
]
|
|
129
133
|
|
|
130
|
-
const { hasProducedRainbowFertilizer } =
|
|
131
|
-
state
|
|
132
|
-
)
|
|
134
|
+
const { hasProducedRainbowFertilizer } =
|
|
135
|
+
processCowFertilizerProduction(state)
|
|
133
136
|
|
|
134
137
|
expect(hasProducedRainbowFertilizer).toBe(true)
|
|
135
138
|
})
|
|
@@ -141,14 +144,14 @@ describe('processCowFertilizerProduction', () => {
|
|
|
141
144
|
state.cowInventory = [
|
|
142
145
|
generateCow({
|
|
143
146
|
color: standardCowColors.WHITE,
|
|
144
|
-
daysSinceProducingFertilizer:
|
|
147
|
+
daysSinceProducingFertilizer:
|
|
148
|
+
COW_FERTILIZER_PRODUCTION_RATE_SLOWEST,
|
|
145
149
|
gender: genders.MALE,
|
|
146
150
|
}),
|
|
147
151
|
]
|
|
148
152
|
|
|
149
|
-
const { hasProducedRainbowFertilizer } =
|
|
150
|
-
state
|
|
151
|
-
)
|
|
153
|
+
const { hasProducedRainbowFertilizer } =
|
|
154
|
+
processCowFertilizerProduction(state)
|
|
152
155
|
|
|
153
156
|
expect(hasProducedRainbowFertilizer).toBe(false)
|
|
154
157
|
})
|
|
@@ -159,9 +162,8 @@ describe('processCowFertilizerProduction', () => {
|
|
|
159
162
|
state.hasProducedRainbowFertilizer = true
|
|
160
163
|
state.cowInventory = []
|
|
161
164
|
|
|
162
|
-
const { hasProducedRainbowFertilizer } =
|
|
163
|
-
state
|
|
164
|
-
)
|
|
165
|
+
const { hasProducedRainbowFertilizer } =
|
|
166
|
+
processCowFertilizerProduction(state)
|
|
165
167
|
|
|
166
168
|
expect(hasProducedRainbowFertilizer).toBe(true)
|
|
167
169
|
})
|
|
@@ -74,11 +74,8 @@ describe('processFeedingCows', () => {
|
|
|
74
74
|
describe('there are more cows to feed than feed units', () => {
|
|
75
75
|
test('units are distributed to cows and remainder goes hungry', () => {
|
|
76
76
|
state.inventory = [{ id: COW_FEED_ITEM_ID, quantity: 1 }]
|
|
77
|
-
const {
|
|
78
|
-
|
|
79
|
-
inventory,
|
|
80
|
-
newDayNotifications,
|
|
81
|
-
} = processFeedingCows(state)
|
|
77
|
+
const { cowInventory, inventory, newDayNotifications } =
|
|
78
|
+
processFeedingCows(state)
|
|
82
79
|
|
|
83
80
|
expect(cowInventory[0].weightMultiplier).toEqual(
|
|
84
81
|
1 + COW_WEIGHT_MULTIPLIER_FEED_BENEFIT
|
|
@@ -9,13 +9,8 @@ export const purchaseCow = (
|
|
|
9
9
|
state: farmhand.state,
|
|
10
10
|
cow: farmhand.cow
|
|
11
11
|
): farmhand.state => {
|
|
12
|
-
const {
|
|
13
|
-
|
|
14
|
-
cowColorsPurchased,
|
|
15
|
-
playerId,
|
|
16
|
-
money,
|
|
17
|
-
purchasedCowPen,
|
|
18
|
-
} = state
|
|
12
|
+
const { cowInventory, cowColorsPurchased, playerId, money, purchasedCowPen } =
|
|
13
|
+
state
|
|
19
14
|
const { color } = cow
|
|
20
15
|
const cowValue = getCowValue(cow, false)
|
|
21
16
|
|
|
@@ -10,7 +10,7 @@ export const updateAchievements = (
|
|
|
10
10
|
achievements.reduce(
|
|
11
11
|
(
|
|
12
12
|
reducerState: farmhand.state,
|
|
13
|
-
achievement: Omit<typeof achievements[number], 'condition'> & {
|
|
13
|
+
achievement: Omit<(typeof achievements)[number], 'condition'> & {
|
|
14
14
|
condition: (s: farmhand.state, ps: farmhand.state) => boolean
|
|
15
15
|
}
|
|
16
16
|
) => {
|
|
@@ -37,17 +37,15 @@ describe('updateFinancialRecords', () => {
|
|
|
37
37
|
})
|
|
38
38
|
|
|
39
39
|
test('truncates logs', () => {
|
|
40
|
-
const {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
})
|
|
50
|
-
)
|
|
40
|
+
const { historicalDailyLosses, historicalDailyRevenue } =
|
|
41
|
+
updateFinancialRecords(
|
|
42
|
+
testState({
|
|
43
|
+
historicalDailyLosses: [-1, -2, -3, -4, -5, -6, -7],
|
|
44
|
+
historicalDailyRevenue: [1, 2, 3, 4, 5, 6, 7],
|
|
45
|
+
todaysLosses: -5,
|
|
46
|
+
todaysRevenue: 10,
|
|
47
|
+
})
|
|
48
|
+
)
|
|
51
49
|
|
|
52
50
|
expect(historicalDailyLosses).toEqual([-5, -1, -2, -3, -4, -5, -6])
|
|
53
51
|
expect(historicalDailyRevenue).toEqual([10, 1, 2, 3, 4, 5, 6])
|
|
@@ -55,20 +53,18 @@ describe('updateFinancialRecords', () => {
|
|
|
55
53
|
|
|
56
54
|
describe('profitabilityStreak', () => {
|
|
57
55
|
test('unprofitable day resets streak', () => {
|
|
58
|
-
const {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
})
|
|
71
|
-
)
|
|
56
|
+
const { profitabilityStreak, recordProfitabilityStreak } =
|
|
57
|
+
updateFinancialRecords(
|
|
58
|
+
testState({
|
|
59
|
+
historicalDailyLosses: [],
|
|
60
|
+
historicalDailyRevenue: [],
|
|
61
|
+
profitabilityStreak: 10,
|
|
62
|
+
record7dayProfitAverage: 0,
|
|
63
|
+
recordProfitabilityStreak: 10,
|
|
64
|
+
todaysLosses: -10,
|
|
65
|
+
todaysRevenue: 10,
|
|
66
|
+
})
|
|
67
|
+
)
|
|
72
68
|
|
|
73
69
|
expect(profitabilityStreak).toEqual(0)
|
|
74
70
|
expect(recordProfitabilityStreak).toEqual(10)
|
|
@@ -13,11 +13,8 @@ export const updateFinancialRecords = (
|
|
|
13
13
|
record7dayProfitAverage,
|
|
14
14
|
recordProfitabilityStreak,
|
|
15
15
|
} = state
|
|
16
|
-
let {
|
|
17
|
-
|
|
18
|
-
historicalDailyRevenue,
|
|
19
|
-
recordSingleDayProfit,
|
|
20
|
-
} = state
|
|
16
|
+
let { historicalDailyLosses, historicalDailyRevenue, recordSingleDayProfit } =
|
|
17
|
+
state
|
|
21
18
|
|
|
22
19
|
historicalDailyLosses = [todaysLosses, ...historicalDailyLosses].slice(
|
|
23
20
|
0,
|
|
@@ -4,20 +4,18 @@ import { updateInventoryRecordsForNextDay } from './updateInventoryRecordsForNex
|
|
|
4
4
|
|
|
5
5
|
describe('updateInventoryRecordsForNextDay', () => {
|
|
6
6
|
test('records inventory records for next day', () => {
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
)
|
|
7
|
+
const { todaysPurchases, todaysStartingInventory } =
|
|
8
|
+
updateInventoryRecordsForNextDay(
|
|
9
|
+
testState({
|
|
10
|
+
inventory: [
|
|
11
|
+
{ id: 'sample-item-1', quantity: 2 },
|
|
12
|
+
{ id: 'sample-item-2', quantity: 5 },
|
|
13
|
+
],
|
|
14
|
+
todaysPurchases: {
|
|
15
|
+
'sample-item-3': 3,
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
)
|
|
21
19
|
|
|
22
20
|
expect(todaysPurchases).toEqual({})
|
|
23
21
|
expect(todaysStartingInventory).toEqual({
|