diff --git a/src/components/Farmhand/Farmhand.js b/src/components/Farmhand/Farmhand.js index 2688cf3c4..f769d6060 100644 --- a/src/components/Farmhand/Farmhand.js +++ b/src/components/Farmhand/Farmhand.js @@ -2,7 +2,9 @@ * @typedef {import("../../index").farmhand.item} farmhand.item * @typedef {import("../../index").farmhand.cow} farmhand.cow * @typedef {import("../../index").farmhand.cowBreedingPen} farmhand.cowBreedingPen + * @typedef {import("../../index").farmhand.forestForageable} farmhand.forestForageable * @typedef {import("../../index").farmhand.keg} farmhand.keg + * @typedef {import("../../index").farmhand.plantedTree} farmhand.plantedTree * @typedef {import("../../index").farmhand.plotContent} farmhand.plotContent * @typedef {import("../../index").farmhand.peerMessage} farmhand.peerMessage * @typedef {import("../../index").farmhand.peerMetadata} farmhand.peerMetadata @@ -93,6 +95,7 @@ import { STANDARD_LOAN_AMOUNT, Z_INDEX, STANDARD_VIEW_LIST, + UNLOCK_FOREST_LEVEL, } from '../../constants' import { HEARTBEAT_INTERVAL_PERIOD, @@ -215,7 +218,7 @@ const applyPriceEvents = (valueAdjustments, priceCrashes, priceSurges) => { * @property {number} experience * @property {string} farmName * @property {(?farmhand.plotContent)[][]} field - * @property {(?farmhand.plotContent)[][]} forest + * @property {(farmhand.plantedTree | farmhand.forestForageable | null)[][]} forest * @property {farmhand.fieldMode} fieldMode * @property {Function?} getCowAccept https://github.com/dmotz/trystero#receiver * @property {Function?} getCowReject https://github.com/dmotz/trystero#receiver @@ -374,7 +377,7 @@ export default class Farmhand extends FarmhandReducers { viewList.unshift(HOME) } - if (this.state.purchasedForest && features.FOREST) { + if (this.isForestUnlocked && features.FOREST) { viewList.push(FOREST) } @@ -416,6 +419,10 @@ export default class Farmhand extends FarmhandReducers { return isOnline && room !== DEFAULT_ROOM } + get isForestUnlocked() { + return levelAchieved(this.state.experience) >= UNLOCK_FOREST_LEVEL + } + /** * @returns {farmhand.state} */ diff --git a/src/components/Forest/Forest.js b/src/components/Forest/Forest.js index ea92e77b3..176b34afe 100644 --- a/src/components/Forest/Forest.js +++ b/src/components/Forest/Forest.js @@ -1,17 +1,5 @@ import React from 'react' -import FarmhandContext from '../Farmhand/Farmhand.context' - export const Forest = () => { return
'welcome to da forest'
} - -export default function Consumer(props) { - return ( - - {({ gameState, handlers }) => ( - - )} - - ) -} diff --git a/src/components/Forest/index.js b/src/components/Forest/index.js index 7951550e3..f8db3e650 100644 --- a/src/components/Forest/index.js +++ b/src/components/Forest/index.js @@ -1 +1 @@ -export { default } from './Forest' +export { Forest } from './Forest' diff --git a/src/components/Shop/Shop.js b/src/components/Shop/Shop.js index 299e678ce..b0e25deca 100644 --- a/src/components/Shop/Shop.js +++ b/src/components/Shop/Shop.js @@ -12,6 +12,7 @@ import Typography from '@mui/material/Typography' import FarmhandContext from '../Farmhand/Farmhand.context' import { features } from '../../config' import { moneyString } from '../../utils/moneyString' +import { levelAchieved } from '../../utils/levelAchieved' import { dollarString, getCostOfNextStorageExpansion, @@ -30,6 +31,7 @@ import { PURCHASABLE_FOREST_SIZES, PURCHASEABLE_SMELTERS, STORAGE_EXPANSION_AMOUNT, + UNLOCK_FOREST_LEVEL, } from '../../constants' import Inventory from '../Inventory' import TierPurchase from '../TierPurchase' @@ -56,6 +58,7 @@ const categorizeShopInventory = memoize(shopInventory => ) export const Shop = ({ + experience, handleCombinePurchase, handleComposterPurchase, handleCowPenPurchase, @@ -82,6 +85,8 @@ export const Shop = ({ const { seeds, fieldTools } = categorizeShopInventory(shopInventory) + const isForestUnlocked = levelAchieved(experience) >= UNLOCK_FOREST_LEVEL + return (
) : null} - {features.FOREST ? ( + {features.FOREST && isForestUnlocked ? (
  • `${dollarString(price)}: ${columns} x ${rows}`, tiers: PURCHASABLE_FOREST_SIZES, - title: purchasedForest ? 'Expand Forest' : 'Purchase Forest', + title: 'Expand Forest', }} />
  • diff --git a/src/components/Stage/Stage.js b/src/components/Stage/Stage.js index 9bf096bf7..88ef48da5 100644 --- a/src/components/Stage/Stage.js +++ b/src/components/Stage/Stage.js @@ -4,7 +4,7 @@ import { array, arrayOf, string } from 'prop-types' import FarmhandContext from '../Farmhand/Farmhand.context' import Field from '../Field' -import Forest from '../Forest' +import { Forest } from '../Forest' import Home from '../Home' import CowPen from '../CowPen' import Shop from '../Shop' diff --git a/src/constants.js b/src/constants.js index 07c9c71b3..f326f943f 100644 --- a/src/constants.js +++ b/src/constants.js @@ -313,3 +313,5 @@ export const STANDARD_VIEW_LIST = [stageFocusType.SHOP, stageFocusType.FIELD] export const Z_INDEX = { END_DAY_BUTTON: 1100, } + +export const UNLOCK_FOREST_LEVEL = 15 diff --git a/src/game-logic/reducers/processLevelUp.js b/src/game-logic/reducers/processLevelUp.js index 7793bc57b..cc2442ad4 100644 --- a/src/game-logic/reducers/processLevelUp.js +++ b/src/game-logic/reducers/processLevelUp.js @@ -6,8 +6,9 @@ import { unlockTool, } from '../../utils' import { getLevelEntitlements } from '../../utils/getLevelEntitlements' -import { SPRINKLER_ITEM_ID } from '../../constants' +import { SPRINKLER_ITEM_ID, UNLOCK_FOREST_LEVEL } from '../../constants' import { LEVEL_GAINED_NOTIFICATION } from '../../templates' +import { FOREST_AVAILABLE_NOTIFICATION } from '../../strings' import { addItemToInventory } from './addItemToInventory' import { showNotification } from './showNotification' @@ -61,6 +62,10 @@ export const processLevelUp = (state, oldLevel) => { LEVEL_GAINED_NOTIFICATION`${i}${randomCropSeed}`, 'success' ) + + if (i === UNLOCK_FOREST_LEVEL) { + state = showNotification(state, FOREST_AVAILABLE_NOTIFICATION, 'success') + } } return state diff --git a/src/game-logic/reducers/purchaseForest.test.js b/src/game-logic/reducers/purchaseForest.test.js index 5fbe4adfb..947490e9b 100644 --- a/src/game-logic/reducers/purchaseForest.test.js +++ b/src/game-logic/reducers/purchaseForest.test.js @@ -4,6 +4,13 @@ import { FOREST_AVAILABLE_NOTIFICATION } from '../../strings' import { purchaseForest } from './purchaseForest' +const tree = () => { + return { + daysOld: 0, + itemId: 'test-tree', + } +} + describe('purchaseForest', () => { test('updates purchasedForest', () => { const { purchasedForest } = purchaseForest({ purchasedForest: 0 }, 0) @@ -60,15 +67,15 @@ describe('purchaseForest', () => { { todaysNotifications: [], forest: [ - [testCrop(), null], - [null, testCrop()], + [tree(), null], + [null, tree()], ], }, 1 ) - expectedForest[0][0] = testCrop() - expectedForest[1][1] = testCrop() + expectedForest[0][0] = tree() + expectedForest[1][1] = tree() expect(forest).toEqual(expectedForest) }) diff --git a/src/index.js b/src/index.js index 28ae1aaa2..a969917e9 100644 --- a/src/index.js +++ b/src/index.js @@ -64,6 +64,20 @@ * @typedef {farmhand.plotContent & farmhand.cropType} farmhand.crop */ +/** + * Represents a tree + * @typedef farmhand.plantedTree + * @property {number} daysOld + * @property {string} itemId + */ + +/** + * Represents a forageable item that grows in the forest + * @typedef farmhand.forestForageable + * @property {number} daysOld + * @property {'mushroom' | 'acorn'} forageableId + */ + /** * Represents a shoveled plot * @typedef farmhand.shoveledPlot