diff --git a/src/components/Farmhand/Farmhand.js b/src/components/Farmhand/Farmhand.js index f769d6060..5859e00ac 100644 --- a/src/components/Farmhand/Farmhand.js +++ b/src/components/Farmhand/Farmhand.js @@ -95,7 +95,6 @@ import { STANDARD_LOAN_AMOUNT, Z_INDEX, STANDARD_VIEW_LIST, - UNLOCK_FOREST_LEVEL, } from '../../constants' import { HEARTBEAT_INTERVAL_PERIOD, @@ -293,6 +292,8 @@ const applyPriceEvents = (valueAdjustments, priceCrashes, priceSurges) => { * @property {boolean} showHomeScreen Option to show the Home Screen * @property {boolean} showNotifications * @property {farmhand.stageFocusType} stageFocus + * @property {Object} stagesUnlocked Keys are stageFocusType, values are booleans + * indicating if the stage has been unlocked * @property {Array.} todaysNotifications * @property {number} todaysLosses Should always be a negative number. * @property {Object} todaysPurchases Keys are item names, values are their @@ -420,7 +421,7 @@ export default class Farmhand extends FarmhandReducers { } get isForestUnlocked() { - return levelAchieved(this.state.experience) >= UNLOCK_FOREST_LEVEL + return this.state.stagesUnlocked[stageFocusType.FOREST] } /** @@ -511,6 +512,9 @@ export default class Farmhand extends FarmhandReducers { showHomeScreen: true, showNotifications: true, stageFocus: stageFocusType.HOME, + stagesUnlocked: { + [stageFocusType.FOREST]: false, + }, todaysNotifications: [], todaysLosses: 0, todaysPurchases: {}, diff --git a/src/components/Shop/Shop.js b/src/components/Shop/Shop.js index b0e25deca..02a59dcd8 100644 --- a/src/components/Shop/Shop.js +++ b/src/components/Shop/Shop.js @@ -12,7 +12,6 @@ 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, @@ -20,7 +19,7 @@ import { } from '../../utils' import { memoize } from '../../utils/memoize' import { items } from '../../img' -import { itemType, toolType } from '../../enums' +import { itemType, stageFocusType, toolType } from '../../enums' import { INFINITE_STORAGE_LIMIT, PURCHASEABLE_CELLARS, @@ -31,7 +30,6 @@ import { PURCHASABLE_FOREST_SIZES, PURCHASEABLE_SMELTERS, STORAGE_EXPANSION_AMOUNT, - UNLOCK_FOREST_LEVEL, } from '../../constants' import Inventory from '../Inventory' import TierPurchase from '../TierPurchase' @@ -77,6 +75,7 @@ export const Shop = ({ purchasedForest, purchasedSmelter, shopInventory, + stagesUnlocked, toolLevels, storageUpgradeCost = getCostOfNextStorageExpansion(inventoryLimit), @@ -85,7 +84,7 @@ export const Shop = ({ const { seeds, fieldTools } = categorizeShopInventory(shopInventory) - const isForestUnlocked = levelAchieved(experience) >= UNLOCK_FOREST_LEVEL + const isForestUnlocked = stagesUnlocked[stageFocusType.FOREST] return (
diff --git a/src/constants.js b/src/constants.js index f326f943f..07c9c71b3 100644 --- a/src/constants.js +++ b/src/constants.js @@ -313,5 +313,3 @@ 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/data/levels.js b/src/data/levels.js index 30708053d..7d70cd10a 100644 --- a/src/data/levels.js +++ b/src/data/levels.js @@ -1,4 +1,4 @@ -import { toolType } from '../enums' +import { stageFocusType, toolType } from '../enums' import * as items from './items' import * as recipes from './recipes' @@ -45,6 +45,10 @@ levels[14] = { unlocksShopItem: items.potatoSeed.id, } +levels[15] = { + unlocksStageFocusType: stageFocusType.FOREST, +} + levels[16] = { unlocksShopItem: items.onionSeed.id, } diff --git a/src/game-logic/reducers/processLevelUp.js b/src/game-logic/reducers/processLevelUp.js index cc2442ad4..cb3db7c5d 100644 --- a/src/game-logic/reducers/processLevelUp.js +++ b/src/game-logic/reducers/processLevelUp.js @@ -3,10 +3,12 @@ import { levelAchieved } from '../../utils/levelAchieved' import { getRandomLevelUpReward, getRandomLevelUpRewardQuantity, + unlockStage, unlockTool, } from '../../utils' import { getLevelEntitlements } from '../../utils/getLevelEntitlements' -import { SPRINKLER_ITEM_ID, UNLOCK_FOREST_LEVEL } from '../../constants' +import { SPRINKLER_ITEM_ID } from '../../constants' +import { stageFocusType } from '../../enums' import { LEVEL_GAINED_NOTIFICATION } from '../../templates' import { FOREST_AVAILABLE_NOTIFICATION } from '../../strings' @@ -36,8 +38,18 @@ export const processLevelUp = (state, oldLevel) => { getRandomLevelUpRewardQuantity(i), true ) - } else if (levelObject && levelObject.unlocksTool) { + } else if (levelObject?.unlocksTool) { state.toolLevels = unlockTool(state.toolLevels, levelObject.unlocksTool) + } else if (levelObject?.unlocksStageFocusType) { + state = unlockStage(state, levelObject.unlocksStageFocusType) + + if (levelObject.unlocksStageFocusType === stageFocusType.FOREST) { + state = showNotification( + state, + FOREST_AVAILABLE_NOTIFICATION, + 'success' + ) + } } // This handles an edge case where the player levels up to level that // unlocks greater sprinkler range, but the sprinkler item is already @@ -62,10 +74,6 @@ 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/processLevelUp.test.js b/src/game-logic/reducers/processLevelUp.test.js index 07e38205e..f6d9fa409 100644 --- a/src/game-logic/reducers/processLevelUp.test.js +++ b/src/game-logic/reducers/processLevelUp.test.js @@ -1,5 +1,5 @@ import { LEVEL_GAINED_NOTIFICATION } from '../../templates' -import { toolLevel } from '../../enums' +import { stageFocusType, toolLevel } from '../../enums' import { experienceNeededForLevel } from '../../utils' jest.mock('../../data/achievements') @@ -103,4 +103,33 @@ describe('processLevelUp', () => { expect(newState.toolLevels['SHOVEL']).toEqual(toolLevel.DEFAULT) }) + + test('unlocksStageFocusType marks stage as unlocked', () => { + jest.resetModules() + jest.mock('../../data/levels', () => ({ + levels: [ + { + id: 0, + }, + { + id: 1, + unlocksStageFocusType: 'FOREST', + }, + ], + itemUnlockLevels: {}, + })) + const newState = jest.requireActual('./').processLevelUp( + { + itemsSold: {}, + inventory: [], + todaysNotifications: [], + stagesUnlocked: { + [stageFocusType.FOREST]: false, + }, + }, + 0 + ) + + expect(newState.stagesUnlocked[stageFocusType.FOREST]).toEqual(true) + }) }) diff --git a/src/game-logic/reducers/purchaseForest.test.js b/src/game-logic/reducers/purchaseForest.test.js index 947490e9b..0905246ae 100644 --- a/src/game-logic/reducers/purchaseForest.test.js +++ b/src/game-logic/reducers/purchaseForest.test.js @@ -1,4 +1,3 @@ -import { testCrop } from '../../test-utils' import { EXPERIENCE_VALUES, PURCHASABLE_FOREST_SIZES } from '../../constants' import { FOREST_AVAILABLE_NOTIFICATION } from '../../strings' diff --git a/src/game-logic/reducers/sellItem.js b/src/game-logic/reducers/sellItem.js index 6067f1c97..2d91a1ece 100644 --- a/src/game-logic/reducers/sellItem.js +++ b/src/game-logic/reducers/sellItem.js @@ -1,6 +1,6 @@ import { itemsMap } from '../../data/maps' import { isItemAFarmProduct } from '../../utils/isItemAFarmProduct' -import { levelAchieved } from '../../utils/levelAchieved' +//import { levelAchieved } from '../../utils/levelAchieved' import { castToMoney, getAdjustedItemValue, @@ -13,7 +13,7 @@ import { LOAN_GARNISHMENT_RATE, EXPERIENCE_VALUES } from '../../constants' import { SOLD_ITEM_PEER_NOTIFICATION } from '../../templates' import { decrementItemFromInventory } from './decrementItemFromInventory' -import { processLevelUp } from './processLevelUp' +//import { processLevelUp } from './processLevelUp' import { addExperience } from './addExperience' import { addRevenue } from './addRevenue' import { updateLearnedRecipes } from './updateLearnedRecipes' @@ -35,12 +35,12 @@ export const sellItem = (state, { id }, howMany = 1) => { const item = itemsMap[id] const { completedAchievements, - experience, + // experience, itemsSold, money: initialMoney, valueAdjustments, } = state - const oldLevel = levelAchieved(experience) + //const oldLevel = levelAchieved(experience) let { loanBalance } = state const adjustedItemValue = isItemSoldInShop(item) @@ -93,7 +93,10 @@ export const sellItem = (state, { id }, howMany = 1) => { itemsSold: newItemsSold, } - state = processLevelUp(state, oldLevel) + // this processLevelUp call actually doesn't have to happen because addExperience + // will call it and this results in double processing. although it doesn't cause + // any negative side effects, we could remove it.. eh? + //state = processLevelUp(state, oldLevel) state = decrementItemFromInventory(state, id, howMany) state = prependPendingPeerMessage( diff --git a/src/utils/index.js b/src/utils/index.js index 02f93cc74..54645d39e 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -984,6 +984,21 @@ export const unlockTool = (currentToolLevels, toolType) => { return currentToolLevels } +/* + * @param {farmhand.state} state + * @param {farmhand.stageFocusType} stageType + * @return {farmhand.state} + */ +export const unlockStage = (state, stageType) => { + return { + ...state, + stagesUnlocked: { + ...state.stagesUnlocked, + [stageType]: true, + }, + } +} + /** * @param {farmhand.state} state * @return {farmhand.state}