From 77de027cbe5dbc68254d77dcdeae755cd5d373f7 Mon Sep 17 00:00:00 2001 From: Luke Stebner Date: Sun, 10 Sep 2023 15:27:44 -0700 Subject: [PATCH 1/2] [closes #371] add experience to a variety of activities (#451) * add experience to a variety of activities * fix: use correct import for EXPERIENCE_VALUES * fix(online): prevent receiving experience for getting cow back --------- Co-authored-by: Jeremy Kahn --- src/constants.js | 8 +-- .../reducers/computeStateForNextDay.js | 16 ++++-- .../reducers/computeStateForNextDay.test.js | 50 +++++++++++++++---- src/game-logic/reducers/makeRecipe.js | 14 ++++++ src/game-logic/reducers/makeRecipe.test.js | 29 ++++++++++- src/game-logic/reducers/processCowBreeding.js | 14 +++++- .../reducers/processCowBreeding.test.js | 16 ++++-- .../reducers/processLevelUp.test.js | 1 + src/game-logic/reducers/purchaseCellar.js | 9 +++- .../reducers/purchaseCellar.test.js | 20 +++++++- src/game-logic/reducers/purchaseComposter.js | 4 +- .../reducers/purchaseComposter.test.js | 7 ++- src/game-logic/reducers/purchaseCowPen.js | 9 +++- .../reducers/purchaseCowPen.test.js | 20 +++++++- src/game-logic/reducers/purchaseField.js | 7 ++- src/game-logic/reducers/purchaseField.test.js | 8 +++ src/game-logic/reducers/purchaseSmelter.js | 4 +- .../reducers/purchaseSmelter.test.js | 7 ++- src/handlers/peer-events.js | 16 ++++-- 19 files changed, 225 insertions(+), 34 deletions(-) diff --git a/src/constants.js b/src/constants.js index 68609c143..c588a56b3 100644 --- a/src/constants.js +++ b/src/constants.js @@ -260,20 +260,22 @@ export const KEG_SPOILAGE_RATE_MULTIPLIER = 0.001 // NOTE: not all of these are implemented yet, these are for all the currently // planned experience rewards export const EXPERIENCE_VALUES = { - COMPOSTER_ACQUIRED: 10, CELLAR_ACQUIRED: 10, CELLAR_EXPANDED: 5, + COMPOSTER_ACQUIRED: 10, COW_BRED: 1, COW_PEN_ACQUIRED: 10, COW_PEN_EXPANDED: 5, COW_TRADED: 1, + FERMENTATION_RECIPE_MADE: 1, FIELD_EXPANDED: 5, - ITEM_FORGED: 3, + FORGE_RECIPE_MADE: 3, ITEM_SOLD: 1, KEG_SOLD: 2, + KITCHEN_RECIPE_MADE: 2, LOAN_PAID_OFF: 25, NEW_YEAR: 5, RAINBOW_COW_BRED: 2, - RECIPE_CRAFTED: 2, + RECYCLING_RECIPE_MADE: 1, SMELTER_ACQUIRED: 10, } diff --git a/src/game-logic/reducers/computeStateForNextDay.js b/src/game-logic/reducers/computeStateForNextDay.js index 5b12cb2c0..13e97235f 100644 --- a/src/game-logic/reducers/computeStateForNextDay.js +++ b/src/game-logic/reducers/computeStateForNextDay.js @@ -1,6 +1,8 @@ import { generateCow } from '../../utils' import { generateValueAdjustments } from '../../common/utils' +import { EXPERIENCE_VALUES } from '../../constants' +import { addExperience } from './addExperience' import { applyLoanInterest } from './applyLoanInterest' import { computeCowInventoryForNextDay } from './computeCowInventoryForNextDay' import { generatePriceEvents } from './generatePriceEvents' @@ -36,8 +38,8 @@ const adjustItemValues = state => ({ * @param {farmhand.state} state * @returns {farmhand.state} */ -export const computeStateForNextDay = (state, isFirstDay = false) => - (isFirstDay +export const computeStateForNextDay = (state, isFirstDay = false) => { + const reducers = isFirstDay ? [processField] : [ computeCowInventoryForNextDay, @@ -58,7 +60,8 @@ export const computeStateForNextDay = (state, isFirstDay = false) => applyLoanInterest, rotateNotificationLogs, ] - ) + + state = reducers .concat([adjustItemValues]) .reduce((acc, fn) => fn({ ...acc }), { ...state, @@ -66,3 +69,10 @@ export const computeStateForNextDay = (state, isFirstDay = false) => dayCount: state.dayCount + 1, todaysNotifications: [], }) + + if (state.dayCount % 365 === 0) { + state = addExperience(state, EXPERIENCE_VALUES.NEW_YEAR) + } + + return state +} diff --git a/src/game-logic/reducers/computeStateForNextDay.test.js b/src/game-logic/reducers/computeStateForNextDay.test.js index b90efa69a..65d5e57d6 100644 --- a/src/game-logic/reducers/computeStateForNextDay.test.js +++ b/src/game-logic/reducers/computeStateForNextDay.test.js @@ -1,23 +1,18 @@ import { shapeOf, testCrop } from '../../test-utils' import { generateCow } from '../../utils' +import { EXPERIENCE_VALUES } from '../../constants' import { computeStateForNextDay } from './computeStateForNextDay' jest.mock('../../data/maps') describe('computeStateForNextDay', () => { + let state + beforeEach(() => { jest.spyOn(Math, 'random').mockReturnValue(0.75) - }) - test('computes state for next day', () => { - const { - cowForSale, - dayCount, - field: [firstRow], - valueAdjustments, - todaysNotifications, - } = computeStateForNextDay({ + state = { cowBreedingPen: { cowId1: null, cowId2: null, daysUntilBirth: -1 }, dayCount: 1, field: [ @@ -30,6 +25,7 @@ describe('computeStateForNextDay', () => { ], cellarInventory: [], cowInventory: [], + experience: 0, historicalDailyLosses: [], historicalDailyRevenue: [], inventory: [], @@ -43,7 +39,17 @@ describe('computeStateForNextDay', () => { record7dayProfitAverage: 0, recordProfitabilityStreak: 0, todaysNotifications: [{ message: 'some message', severity: 'info' }], - }) + } + }) + + test('computes state for next day', () => { + const { + cowForSale, + dayCount, + field: [firstRow], + valueAdjustments, + todaysNotifications, + } = computeStateForNextDay(state) expect(shapeOf(cowForSale)).toEqual(shapeOf(generateCow())) expect(dayCount).toEqual(2) @@ -54,4 +60,28 @@ describe('computeStateForNextDay', () => { expect(firstRow[0].daysOld).toBe(1) expect(todaysNotifications).toBeEmpty() }) + + describe('new year experience', () => { + const ONE_YEAR = 365 + + test.each([1, 5, 100, 363, 365, 730])( + 'it does not add any experience on day %s', + dayCount => { + const { experience } = computeStateForNextDay({ ...state, dayCount }) + + expect(experience).toEqual(0) + } + ) + + test.each([ + ONE_YEAR - 1, + ONE_YEAR * 2 - 1, + ONE_YEAR * 3 - 1, + ONE_YEAR * 4 - 1, + ])('it adds experience on day %s', dayCount => { + const { experience } = computeStateForNextDay({ ...state, dayCount }) + + expect(experience).toEqual(EXPERIENCE_VALUES.NEW_YEAR) + }) + }) }) diff --git a/src/game-logic/reducers/makeRecipe.js b/src/game-logic/reducers/makeRecipe.js index 2c7c334c7..aa8e6b4f3 100644 --- a/src/game-logic/reducers/makeRecipe.js +++ b/src/game-logic/reducers/makeRecipe.js @@ -1,8 +1,20 @@ import { canMakeRecipe } from '../../utils' +import { recipeType } from '../../enums' + +import { EXPERIENCE_VALUES } from '../../constants' + import { addItemToInventory } from './addItemToInventory' +import { addExperience } from './addExperience' import { decrementItemFromInventory } from './decrementItemFromInventory' +const EXPERIENCE_FOR_RECIPE = { + [recipeType.FERMENTATION]: EXPERIENCE_VALUES.FERMENTATION_RECIPE_MADE, + [recipeType.FORGE]: EXPERIENCE_VALUES.FORGE_RECIPE_MADE, + [recipeType.KITCHEN]: EXPERIENCE_VALUES.KITCHEN_RECIPE_MADE, + [recipeType.RECYCLING]: EXPERIENCE_VALUES.RECYCLING_RECIPE_MADE, +} + /** * @param {farmhand.state} state * @param {farmhand.recipe} recipe @@ -14,6 +26,8 @@ export const makeRecipe = (state, recipe, howMany = 1) => { return state } + state = addExperience(state, EXPERIENCE_FOR_RECIPE[recipe.recipeType] || 0) + state = Object.keys(recipe.ingredients).reduce( (state, ingredientId) => decrementItemFromInventory( diff --git a/src/game-logic/reducers/makeRecipe.test.js b/src/game-logic/reducers/makeRecipe.test.js index 046e19c90..210693b34 100644 --- a/src/game-logic/reducers/makeRecipe.test.js +++ b/src/game-logic/reducers/makeRecipe.test.js @@ -1,6 +1,8 @@ import { sampleRecipe1 } from '../../data/recipes' -import { INFINITE_STORAGE_LIMIT } from '../../constants' +import { EXPERIENCE_VALUES, INFINITE_STORAGE_LIMIT } from '../../constants' + +import { recipeType } from '../../enums' import { makeRecipe } from './makeRecipe' @@ -37,4 +39,29 @@ describe('makeRecipe', () => { ]) }) }) + + describe('experience', () => { + let state + + beforeEach(() => { + state = { + experience: 0, + inventory: [], + } + }) + + test.each([ + [recipeType.FERMENTATION, EXPERIENCE_VALUES.FERMENTATION_RECIPE_MADE], + [recipeType.FORGE, EXPERIENCE_VALUES.FORGE_RECIPE_MADE], + [recipeType.KITCHEN, EXPERIENCE_VALUES.KITCHEN_RECIPE_MADE], + [recipeType.RECYCLING, EXPERIENCE_VALUES.RECYCLING_RECIPE_MADE], + ])('adds experience for a %s recipe', (recipeType, experienceValue) => { + const { experience } = makeRecipe(state, { + ingredients: {}, + recipeType, + }) + + expect(experience).toEqual(experienceValue) + }) + }) }) diff --git a/src/game-logic/reducers/processCowBreeding.js b/src/game-logic/reducers/processCowBreeding.js index 221401307..4440994be 100644 --- a/src/game-logic/reducers/processCowBreeding.js +++ b/src/game-logic/reducers/processCowBreeding.js @@ -1,11 +1,15 @@ import { findCowById, generateOffspringCow } from '../../utils' +import { cowColors } from '../../enums' import { + EXPERIENCE_VALUES, COW_GESTATION_PERIOD_DAYS, COW_MINIMUM_HAPPINESS_TO_BREED, PURCHASEABLE_COW_PENS, } from '../../constants' import { COW_BORN_MESSAGE } from '../../templates' +import { addExperience } from './addExperience' + /** * @param {farmhand.state} state * @returns {farmhand.state} @@ -43,9 +47,17 @@ export const processCowBreeding = state => { cowInventory.length < PURCHASEABLE_COW_PENS.get(purchasedCowPen).cows && daysUntilBirth === 0 - let offspringCow = + const offspringCow = shouldGenerateOffspring && generateOffspringCow(cow1, cow2, id) + if (offspringCow) { + const experienceGained = + offspringCow.color === cowColors.RAINBOW + ? EXPERIENCE_VALUES.RAINBOW_COW_BRED + : EXPERIENCE_VALUES.COW_BRED + state = addExperience(state, experienceGained) + } + return { ...state, cowInventory: shouldGenerateOffspring diff --git a/src/game-logic/reducers/processCowBreeding.test.js b/src/game-logic/reducers/processCowBreeding.test.js index 89dcaa05d..162199e7c 100644 --- a/src/game-logic/reducers/processCowBreeding.test.js +++ b/src/game-logic/reducers/processCowBreeding.test.js @@ -1,4 +1,5 @@ import { + EXPERIENCE_VALUES, COW_GESTATION_PERIOD_DAYS, PURCHASEABLE_COW_PENS, } from '../../constants' @@ -96,19 +97,28 @@ describe('processCowBreeding', () => { describe('daysUntilBirth === 1', () => { describe('there is space in cowInventory', () => { - test('adds offspring cow to cowInventory', () => { - const { cowInventory } = processCowBreeding({ + let newState + + beforeEach(() => { + newState = processCowBreeding({ cowBreedingPen: { cowId1: maleCow1.id, cowId2: femaleCow.id, daysUntilBirth: 1, }, cowInventory: [maleCow1, femaleCow], + experience: 0, newDayNotifications: [], purchasedCowPen: 1, }) + }) + + test('adds offspring cow to cowInventory', () => { + expect(newState.cowInventory).toHaveLength(3) + }) - expect(cowInventory).toHaveLength(3) + test('adds experience', () => { + expect(newState.experience).toEqual(EXPERIENCE_VALUES.COW_BRED) }) }) diff --git a/src/game-logic/reducers/processLevelUp.test.js b/src/game-logic/reducers/processLevelUp.test.js index a61dd65d1..07e38205e 100644 --- a/src/game-logic/reducers/processLevelUp.test.js +++ b/src/game-logic/reducers/processLevelUp.test.js @@ -57,6 +57,7 @@ describe('processLevelUp', () => { itemUnlockLevels: {}, })) jest.mock('../../constants', () => ({ + ...jest.requireActual('../../constants'), INITIAL_SPRINKLER_RANGE: 1, SPRINKLER_ITEM_ID: 'sprinkler', })) diff --git a/src/game-logic/reducers/purchaseCellar.js b/src/game-logic/reducers/purchaseCellar.js index 93d8da288..b28464abb 100644 --- a/src/game-logic/reducers/purchaseCellar.js +++ b/src/game-logic/reducers/purchaseCellar.js @@ -1,8 +1,9 @@ import { moneyTotal } from '../../utils' -import { PURCHASEABLE_CELLARS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_CELLARS } from '../../constants' import { CELLAR_PURCHASED } from '../../templates' +import { addExperience } from './addExperience' import { showNotification } from './showNotification' /** @@ -21,6 +22,12 @@ export const purchaseCellar = (state, cellarId) => { state = showNotification(state, CELLAR_PURCHASED`${space}`, 'success') + const experienceEarned = + cellarId > 1 + ? EXPERIENCE_VALUES.CELLAR_EXPANDED + : EXPERIENCE_VALUES.CELLAR_ACQUIRED + state = addExperience(state, experienceEarned) + return { ...state, purchasedCellar: cellarId, diff --git a/src/game-logic/reducers/purchaseCellar.test.js b/src/game-logic/reducers/purchaseCellar.test.js index 39a412019..e614991a7 100644 --- a/src/game-logic/reducers/purchaseCellar.test.js +++ b/src/game-logic/reducers/purchaseCellar.test.js @@ -1,4 +1,4 @@ -import { PURCHASEABLE_CELLARS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_CELLARS } from '../../constants' import { purchaseCellar } from './purchaseCellar' @@ -33,4 +33,22 @@ describe('purchaseCellar', () => { 'Purchased a cellar with capacity for 10 kegs! View your keg inventory by going to the "Cellar" page.' ) }) + + test('adds experience when acquired', () => { + const { experience } = purchaseCellar( + { experience: 0, todaysNotifications: [] }, + 1 + ) + + expect(experience).toEqual(EXPERIENCE_VALUES.CELLAR_ACQUIRED) + }) + + test('adds experience when expanded', () => { + const { experience } = purchaseCellar( + { experience: 0, todaysNotifications: [] }, + 2 + ) + + expect(experience).toEqual(EXPERIENCE_VALUES.CELLAR_EXPANDED) + }) }) diff --git a/src/game-logic/reducers/purchaseComposter.js b/src/game-logic/reducers/purchaseComposter.js index e396ed55c..bdf899bda 100644 --- a/src/game-logic/reducers/purchaseComposter.js +++ b/src/game-logic/reducers/purchaseComposter.js @@ -1,7 +1,8 @@ import { moneyTotal } from '../../utils' -import { PURCHASEABLE_COMPOSTERS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_COMPOSTERS } from '../../constants' import { RECYCLING_AVAILABLE_NOTIFICATION } from '../../strings' +import { addExperience } from './addExperience' import { showNotification } from './showNotification' import { updateLearnedRecipes } from './updateLearnedRecipes' @@ -22,6 +23,7 @@ export const purchaseComposter = (state, composterId) => { } state = showNotification(state, RECYCLING_AVAILABLE_NOTIFICATION) + state = addExperience(state, EXPERIENCE_VALUES.COMPOSTER_ACQUIRED) return updateLearnedRecipes(state) } diff --git a/src/game-logic/reducers/purchaseComposter.test.js b/src/game-logic/reducers/purchaseComposter.test.js index c20867d18..ba7f68f09 100644 --- a/src/game-logic/reducers/purchaseComposter.test.js +++ b/src/game-logic/reducers/purchaseComposter.test.js @@ -1,4 +1,4 @@ -import { PURCHASEABLE_COMPOSTERS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_COMPOSTERS } from '../../constants' import { RECYCLING_AVAILABLE_NOTIFICATION } from '../../strings' import { purchaseComposter } from './purchaseComposter' @@ -8,6 +8,7 @@ describe('purchaseComposter', () => { beforeEach(() => { gameState = { + experience: 0, money: PURCHASEABLE_COMPOSTERS.get(1).price, purchasedComposter: 0, todaysNotifications: [], @@ -28,6 +29,10 @@ describe('purchaseComposter', () => { expect(newState.money).toEqual(0) }) + test('it adds experience', () => { + expect(newState.experience).toEqual(EXPERIENCE_VALUES.COMPOSTER_ACQUIRED) + }) + test('it shows the recycling available notification', () => { expect(newState.todaysNotifications[0].message).toEqual( RECYCLING_AVAILABLE_NOTIFICATION diff --git a/src/game-logic/reducers/purchaseCowPen.js b/src/game-logic/reducers/purchaseCowPen.js index 1fa5ef74d..2c7426d05 100644 --- a/src/game-logic/reducers/purchaseCowPen.js +++ b/src/game-logic/reducers/purchaseCowPen.js @@ -2,9 +2,10 @@ * @typedef {import("../../components/Farmhand/Farmhand").farmhand.state} state */ import { moneyTotal } from '../../utils' -import { PURCHASEABLE_COW_PENS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_COW_PENS } from '../../constants' import { COW_PEN_PURCHASED } from '../../templates' +import { addExperience } from './addExperience' import { showNotification } from './showNotification' /** @@ -23,6 +24,12 @@ export const purchaseCowPen = (state, cowPenId) => { state = showNotification(state, COW_PEN_PURCHASED`${cows}`, 'success') + const experienceEarned = + cowPenId > 1 + ? EXPERIENCE_VALUES.COW_PEN_EXPANDED + : EXPERIENCE_VALUES.COW_PEN_ACQUIRED + state = addExperience(state, experienceEarned) + return { ...state, purchasedCowPen: cowPenId, diff --git a/src/game-logic/reducers/purchaseCowPen.test.js b/src/game-logic/reducers/purchaseCowPen.test.js index cf05e2e5e..594c19258 100644 --- a/src/game-logic/reducers/purchaseCowPen.test.js +++ b/src/game-logic/reducers/purchaseCowPen.test.js @@ -1,4 +1,4 @@ -import { PURCHASEABLE_COW_PENS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_COW_PENS } from '../../constants' import { purchaseCowPen } from './purchaseCowPen' @@ -33,4 +33,22 @@ describe('purchaseCowPen', () => { 'Purchased a cow pen with capacity for 10 cows! You can visit your cow pen by going to the "Cows" page.' ) }) + + test('adds experience when cow pen is acquired', () => { + const { experience } = purchaseCowPen( + { todaysNotifications: [], experience: 0 }, + 1 + ) + + expect(experience).toEqual(EXPERIENCE_VALUES.COW_PEN_ACQUIRED) + }) + + test('adds experience when cow pen is expanded', () => { + const { experience } = purchaseCowPen( + { todaysNotifications: [], experience: 0 }, + 2 + ) + + expect(experience).toEqual(EXPERIENCE_VALUES.COW_PEN_EXPANDED) + }) }) diff --git a/src/game-logic/reducers/purchaseField.js b/src/game-logic/reducers/purchaseField.js index 7927836c1..33cf01914 100644 --- a/src/game-logic/reducers/purchaseField.js +++ b/src/game-logic/reducers/purchaseField.js @@ -1,5 +1,7 @@ import { moneyTotal, nullArray } from '../../utils' -import { PURCHASEABLE_FIELD_SIZES } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_FIELD_SIZES } from '../../constants' + +import { addExperience } from './addExperience' /** * @param {farmhand.state} state @@ -12,9 +14,12 @@ export const purchaseField = (state, fieldId) => { return state } + state = addExperience(state, EXPERIENCE_VALUES.FIELD_EXPANDED) + const { columns, price, rows } = PURCHASEABLE_FIELD_SIZES.get(fieldId) return { + ...state, purchasedField: fieldId, field: nullArray(rows).map((_, row) => nullArray(columns).map( diff --git a/src/game-logic/reducers/purchaseField.test.js b/src/game-logic/reducers/purchaseField.test.js index d435ecf50..7c4edca8b 100644 --- a/src/game-logic/reducers/purchaseField.test.js +++ b/src/game-logic/reducers/purchaseField.test.js @@ -1,4 +1,5 @@ import { testCrop } from '../../test-utils' +import { EXPERIENCE_VALUES } from '../../constants' import { purchaseField } from './purchaseField' @@ -18,10 +19,17 @@ describe('purchaseField', () => { expect(money).toEqual(500) }) + test('adds experience', () => { + const { experience } = purchaseField({ experience: 0, field: [[]] }, 1) + + expect(experience).toEqual(EXPERIENCE_VALUES.FIELD_EXPANDED) + }) + describe('field expansion', () => { test('field expands without destroying existing data', () => { jest.resetModules() jest.mock('../../constants', () => ({ + EXPERIENCE_VALUES: {}, PURCHASEABLE_FIELD_SIZES: new Map([ [1, { columns: 3, rows: 4, price: 1000 }], ]), diff --git a/src/game-logic/reducers/purchaseSmelter.js b/src/game-logic/reducers/purchaseSmelter.js index 8fd1d9f4c..e0813cfe5 100644 --- a/src/game-logic/reducers/purchaseSmelter.js +++ b/src/game-logic/reducers/purchaseSmelter.js @@ -1,7 +1,8 @@ import { moneyTotal } from '../../utils' -import { PURCHASEABLE_SMELTERS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_SMELTERS } from '../../constants' import { FORGE_AVAILABLE_NOTIFICATION } from '../../strings' +import { addExperience } from './addExperience' import { showNotification } from './showNotification' import { updateLearnedRecipes } from './updateLearnedRecipes' @@ -22,6 +23,7 @@ export const purchaseSmelter = (state, smelterId) => { } state = showNotification(state, FORGE_AVAILABLE_NOTIFICATION) + state = addExperience(state, EXPERIENCE_VALUES.SMELTER_ACQUIRED) return updateLearnedRecipes(state) } diff --git a/src/game-logic/reducers/purchaseSmelter.test.js b/src/game-logic/reducers/purchaseSmelter.test.js index c054564dc..2706bbf65 100644 --- a/src/game-logic/reducers/purchaseSmelter.test.js +++ b/src/game-logic/reducers/purchaseSmelter.test.js @@ -1,4 +1,4 @@ -import { PURCHASEABLE_SMELTERS } from '../../constants' +import { EXPERIENCE_VALUES, PURCHASEABLE_SMELTERS } from '../../constants' import { FORGE_AVAILABLE_NOTIFICATION } from '../../strings' import { purchaseSmelter } from './purchaseSmelter' @@ -8,6 +8,7 @@ describe('purchaseSmelter', () => { beforeEach(() => { gameState = { + experience: 0, money: PURCHASEABLE_SMELTERS.get(1).price, purchasedSmelter: 0, todaysNotifications: [], @@ -33,6 +34,10 @@ describe('purchaseSmelter', () => { FORGE_AVAILABLE_NOTIFICATION ) }) + + test('adds experience', () => { + expect(newState.experience).toEqual(EXPERIENCE_VALUES.SMELTER_ACQUIRED) + }) }) describe('unsuccessful purchase', () => { diff --git a/src/handlers/peer-events.js b/src/handlers/peer-events.js index 5d20068bb..d1b529d34 100644 --- a/src/handlers/peer-events.js +++ b/src/handlers/peer-events.js @@ -1,6 +1,7 @@ /** @typedef {import('../components/Farmhand/Farmhand').default} Farmhand */ /** @typedef {import('../index').farmhand.peerMetadata} farmhand.peerMetadata */ import { cowTradeRejectionReason } from '../enums' +import { EXPERIENCE_VALUES } from '../constants' import { COW_TRADED_NOTIFICATION } from '../templates' import { PROGRESS_SAVED_MESSAGE, @@ -16,6 +17,8 @@ import { showNotification, } from '../game-logic/reducers' +import { addExperience } from '../game-logic/reducers/addExperience' + /** * @param {Farmhand} farmhand * @param {farmhand.peerMetadata} peerMetadata @@ -188,12 +191,13 @@ export const handleCowTradeRequestAccept = (farmhand, cowReceived, peerId) => { ([, { id }]) => id === cowReceived.ownerId ) + const didOriginallyOwnReceivedCow = cowReceived.originalOwnerId === id + const updatedCowReceived = { ...cowReceived, - timesTraded: - cowReceived.originalOwnerId === id - ? cowReceived.timesTraded - : cowReceived.timesTraded + 1, + timesTraded: didOriginallyOwnReceivedCow + ? cowReceived.timesTraded + : cowReceived.timesTraded + 1, } state = removeCowFromInventory(state, cowTradedAway) @@ -207,6 +211,10 @@ export const handleCowTradeRequestAccept = (farmhand, cowReceived, peerId) => { 'success' ) + if (!didOriginallyOwnReceivedCow) { + state = addExperience(state, EXPERIENCE_VALUES.COW_TRADED) + } + clearTimeout(cowTradeTimeoutId) wasTradeSuccessful = true From 15ca44e35964df5dad17cb643dc2a1f6e01eb657 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 10 Sep 2023 22:41:00 +0000 Subject: [PATCH 2/2] 1.18.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b4c88012..0b955cea9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jeremyckahn/farmhand", - "version": "1.18.0", + "version": "1.18.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@jeremyckahn/farmhand", - "version": "1.18.0", + "version": "1.18.1", "license": "GPL-2.0-or-later", "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.27", diff --git a/package.json b/package.json index 3945b804f..c65ee9794 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jeremyckahn/farmhand", - "version": "1.18.0", + "version": "1.18.1", "publishConfig": { "access": "public" },